67e09c5270bfe006a783d7030874af44dfdc1a87
[openwrt/staging/dedeckeh.git] / target / linux / layerscape / patches-4.9 / 701-sdk_dpaa-support-layerscape.patch
1 From 6fe4518adbbbab0404958db4aa95673d60174881 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 11:58:03 +0800
4 Subject: [PATCH] sdk_dpaa: support layerscape
5
6 This is a integrated patch for layerscape dpaa1-sdk support.
7
8 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
11 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
12 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
13 ---
14 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 173 +
15 drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 46 +
16 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
17 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
18 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
19 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
20 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1213 ++++
21 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 698 ++
22 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
23 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
24 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1992 +++++
25 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 237 +
26 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1811 +++++
27 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 225 +
28 .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
29 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1179 +++
30 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
31 .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
32 .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++
33 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 +
34 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 907 +++
35 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 ++
36 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 +
37 .../net/ethernet/freescale/sdk_dpaa/offline_port.c | 848 +++
38 .../net/ethernet/freescale/sdk_dpaa/offline_port.h | 59 +
39 drivers/net/ethernet/freescale/sdk_fman/Kconfig | 153 +
40 drivers/net/ethernet/freescale/sdk_fman/Makefile | 11 +
41 .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 +
42 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++
43 .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
44 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1464 ++++
45 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
46 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
47 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
48 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 658 ++
49 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 225 +
50 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
51 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
52 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 +++
53 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 +
54 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 511 ++
55 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 +
56 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
57 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1096 +++
58 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
59 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 +
60 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 +
61 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 975 +++
62 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
63 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
64 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
65 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
66 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c | 237 +
67 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h | 203 +
68 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
69 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
70 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
71 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 +++
72 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
73 .../freescale/sdk_fman/Peripherals/FM/Makefile | 23 +
74 .../freescale/sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
75 .../freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
76 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 ++++++++++++++++++++
77 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
78 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++++
79 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
80 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++++
81 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
82 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 ++++++
83 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
84 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
85 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 +++++
86 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
87 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 ++
88 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
89 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
90 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
91 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 888 +++
92 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
93 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
94 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 +++++++++++++++++
95 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
96 .../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h | 494 ++
97 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
98 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1568 ++++
99 .../freescale/sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
100 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
101 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
102 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
103 .../freescale/sdk_fman/Peripherals/FM/SP/Makefile | 15 +
104 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
105 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
106 .../freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
107 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++++
108 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
109 .../freescale/sdk_fman/Peripherals/FM/fm_ipc.h | 465 ++
110 .../freescale/sdk_fman/Peripherals/FM/fm_muram.c | 174 +
111 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1398 ++++
112 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 ++++
113 .../freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
114 .../sdk_fman/Peripherals/FM/inc/fm_sp_common.h | 117 +
115 .../net/ethernet/freescale/sdk_fman/etc/Makefile | 12 +
116 .../net/ethernet/freescale/sdk_fman/etc/error.c | 95 +
117 drivers/net/ethernet/freescale/sdk_fman/etc/list.c | 71 +
118 .../net/ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
119 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
120 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
121 .../net/ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
122 .../ethernet/freescale/sdk_fman/fmanv3h_dflags.h | 57 +
123 .../ethernet/freescale/sdk_fman/fmanv3l_dflags.h | 56 +
124 .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 +
125 .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
126 .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++
127 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 859 +++
128 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++
129 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
130 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++
131 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 +++++++
132 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
133 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 ++
134 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
135 .../net/ethernet/freescale/sdk_fman/inc/core_ext.h | 90 +
136 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
137 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
138 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
139 .../ethernet/freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
140 .../ethernet/freescale/sdk_fman/inc/debug_ext.h | 233 +
141 .../ethernet/freescale/sdk_fman/inc/endian_ext.h | 447 ++
142 .../net/ethernet/freescale/sdk_fman/inc/enet_ext.h | 205 +
143 .../ethernet/freescale/sdk_fman/inc/error_ext.h | 529 ++
144 .../ethernet/freescale/sdk_fman/inc/etc/list_ext.h | 358 +
145 .../ethernet/freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
146 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
147 .../ethernet/freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
148 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
149 .../sdk_fman/inc/flib/common/arch/ppc_access.h | 37 +
150 .../freescale/sdk_fman/inc/flib/common/general.h | 52 +
151 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
152 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
153 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 +++
154 .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
155 .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
156 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
157 .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 427 ++
158 .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 +
159 .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
160 .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
161 .../freescale/sdk_fman/inc/flib/fsl_fman_rtc.h | 449 ++
162 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
163 .../freescale/sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
164 .../integrations/FMANV3H/dpaa_integration_ext.h | 291 +
165 .../sdk_fman/inc/integrations/FMANV3H/part_ext.h | 71 +
166 .../integrations/FMANV3H/part_integration_ext.h | 304 +
167 .../integrations/FMANV3L/dpaa_integration_ext.h | 293 +
168 .../sdk_fman/inc/integrations/FMANV3L/part_ext.h | 59 +
169 .../integrations/FMANV3L/part_integration_ext.h | 304 +
170 .../inc/integrations/LS1043/dpaa_integration_ext.h | 291 +
171 .../sdk_fman/inc/integrations/LS1043/part_ext.h | 64 +
172 .../inc/integrations/LS1043/part_integration_ext.h | 185 +
173 .../inc/integrations/P1023/dpaa_integration_ext.h | 213 +
174 .../sdk_fman/inc/integrations/P1023/part_ext.h | 82 +
175 .../inc/integrations/P1023/part_integration_ext.h | 635 ++
176 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
177 .../inc/integrations/P3040_P4080_P5020/part_ext.h | 83 +
178 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
179 .../net/ethernet/freescale/sdk_fman/inc/math_ext.h | 100 +
180 .../net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h | 435 ++
181 .../net/ethernet/freescale/sdk_fman/inc/net_ext.h | 430 ++
182 .../net/ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
183 .../ethernet/freescale/sdk_fman/inc/stdarg_ext.h | 49 +
184 .../ethernet/freescale/sdk_fman/inc/stdlib_ext.h | 162 +
185 .../ethernet/freescale/sdk_fman/inc/string_ext.h | 56 +
186 .../ethernet/freescale/sdk_fman/inc/types_ext.h | 62 +
187 .../ethernet/freescale/sdk_fman/inc/xx_common.h | 56 +
188 .../net/ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
189 .../ethernet/freescale/sdk_fman/ls1043_dflags.h | 56 +
190 .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 53 +
191 .../net/ethernet/freescale/sdk_fman/p1023_dflags.h | 65 +
192 .../freescale/sdk_fman/p3040_4080_5020_dflags.h | 62 +
193 .../net/ethernet/freescale/sdk_fman/src/Makefile | 11 +
194 .../freescale/sdk_fman/src/inc/system/sys_ext.h | 118 +
195 .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 +
196 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
197 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
198 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 128 +
199 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
200 .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++
201 .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 +
202 .../freescale/sdk_fman/src/system/Makefile | 10 +
203 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
204 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
205 .../freescale/sdk_fman/src/wrapper/fman_test.c | 1665 +++++
206 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 ++++++++
207 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
208 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1480 ++++
209 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4813 +++++++++++++
210 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++
211 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
212 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
213 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.c | 191 +
214 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.h | 144 +
215 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.make | 28 +
216 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
217 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
218 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 +++++
219 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
220 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 ++++
221 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
222 .../ethernet/freescale/sdk_fman/src/xx/Makefile | 18 +
223 .../freescale/sdk_fman/src/xx/module_strings.c | 46 +
224 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 +++
225 .../ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 918 +++
226 drivers/staging/fsl_qbman/Kconfig | 228 +
227 drivers/staging/fsl_qbman/Makefile | 28 +
228 drivers/staging/fsl_qbman/bman_config.c | 720 ++
229 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
230 drivers/staging/fsl_qbman/bman_driver.c | 575 ++
231 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
232 drivers/staging/fsl_qbman/bman_low.h | 565 ++
233 drivers/staging/fsl_qbman/bman_private.h | 166 +
234 drivers/staging/fsl_qbman/bman_test.c | 56 +
235 drivers/staging/fsl_qbman/bman_test.h | 44 +
236 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
237 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
238 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
239 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
240 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
241 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
242 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
243 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
244 drivers/staging/fsl_qbman/fsl_usdpaa.c | 1983 +++++
245 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
246 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
247 drivers/staging/fsl_qbman/qman_config.c | 1224 ++++
248 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
249 drivers/staging/fsl_qbman/qman_driver.c | 977 +++
250 drivers/staging/fsl_qbman/qman_high.c | 5669 +++++++++++++++
251 drivers/staging/fsl_qbman/qman_low.h | 1427 ++++
252 drivers/staging/fsl_qbman/qman_private.h | 398 +
253 drivers/staging/fsl_qbman/qman_test.c | 57 +
254 drivers/staging/fsl_qbman/qman_test.h | 45 +
255 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
256 drivers/staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
257 drivers/staging/fsl_qbman/qman_utility.c | 129 +
258 include/linux/fsl_bman.h | 532 ++
259 include/linux/fsl_qman.h | 3888 ++++++++++
260 include/linux/fsl_usdpaa.h | 372 +
261 include/uapi/linux/fmd/Kbuild | 5 +
262 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
263 include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
264 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++
265 .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 948 +++
266 .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
267 include/uapi/linux/fmd/integrations/Kbuild | 1 +
268 .../linux/fmd/integrations/integration_ioctls.h | 56 +
269 include/uapi/linux/fmd/ioctls.h | 96 +
270 include/uapi/linux/fmd/net_ioctls.h | 430 ++
271 257 files changed, 152931 insertions(+)
272 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
273 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
274 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
275 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
276 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
277 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
278 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
279 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
280 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
281 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
282 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
283 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
284 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
285 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
286 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
287 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
288 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
289 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
290 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
291 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
292 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
293 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
294 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
295 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
296 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
297 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
298 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
299 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
300 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
301 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
302 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
303 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
304 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
305 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
306 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
307 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
308 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
309 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
310 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
311 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
312 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
313 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
314 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
315 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
316 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
317 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
318 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
319 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
320 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
321 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
322 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
323 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
324 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
325 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
326 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
327 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
328 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
329 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
330 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
331 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
332 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
333 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
346 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
350 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
354 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
355 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
356 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
357 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
360 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
361 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
364 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
365 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
369 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
370 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
387 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
389 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
391 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
393 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
397 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
401 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
402 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
406 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
409 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
410 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
411 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
412 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
416 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
417 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
418 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
419 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
420 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
421 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
442 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
444 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
446 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
448 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
449 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
450 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
452 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
453 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
454 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
456 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
457 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
464 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
465 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
484 create mode 100644 drivers/staging/fsl_qbman/Kconfig
485 create mode 100644 drivers/staging/fsl_qbman/Makefile
486 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
487 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
488 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
489 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
490 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
491 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
492 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
493 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
494 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
495 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
496 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
497 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
498 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
499 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
500 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
501 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
502 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
503 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
504 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
505 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
506 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
507 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
508 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
509 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
510 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
511 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
512 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
513 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
514 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
515 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
516 create mode 100644 include/linux/fsl_bman.h
517 create mode 100644 include/linux/fsl_qman.h
518 create mode 100644 include/linux/fsl_usdpaa.h
519 create mode 100644 include/uapi/linux/fmd/Kbuild
520 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
521 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
522 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
523 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
524 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
525 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
526 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
527 create mode 100644 include/uapi/linux/fmd/ioctls.h
528 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
529
530 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
531 new file mode 100644
532 index 00000000..92118b76
533 --- /dev/null
534 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
535 @@ -0,0 +1,173 @@
536 +menuconfig FSL_SDK_DPAA_ETH
537 + tristate "DPAA Ethernet"
538 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
539 + select PHYLIB
540 + help
541 + Data Path Acceleration Architecture Ethernet driver,
542 + supporting the Freescale QorIQ chips.
543 + Depends on Freescale Buffer Manager and Queue Manager
544 + driver and Frame Manager Driver.
545 +
546 +if FSL_SDK_DPAA_ETH
547 +
548 +config FSL_DPAA_HOOKS
549 + bool "DPAA Ethernet driver hooks"
550 +
551 +config FSL_DPAA_CEETM
552 + bool "DPAA CEETM QoS"
553 + depends on NET_SCHED
554 + default n
555 + help
556 + Enable QoS offloading support through the CEETM hardware block.
557 +
558 +config FSL_DPAA_OFFLINE_PORTS
559 + bool "Offline Ports support"
560 + depends on FSL_SDK_DPAA_ETH
561 + default y
562 + help
563 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
564 + most of the functionality of the regular, online ports, except they receive their
565 + frames from a core or an accelerator on the SoC, via QMan frame queues,
566 + rather than directly from the network.
567 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
568 + any online FMan port. They deliver the processed frames to frame queues, according
569 + to the applied PCD configurations.
570 +
571 + Choosing this feature will not impact the functionality and/or performance of the system,
572 + so it is safe to have it.
573 +
574 +config FSL_DPAA_ADVANCED_DRIVERS
575 + bool "Advanced DPAA Ethernet drivers"
576 + depends on FSL_SDK_DPAA_ETH
577 + default y
578 + help
579 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
580 + is needed to support advanced scenarios. Select this to also build the advanced
581 + drivers.
582 +
583 +config FSL_DPAA_ETH_JUMBO_FRAME
584 + bool "Optimize for jumbo frames"
585 + default n
586 + help
587 + Optimize the DPAA Ethernet driver throughput for large frames
588 + termination traffic (e.g. 4K and above).
589 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
590 + is set to 9600 bytes.
591 + Using this option in combination with small frames increases
592 + significantly the driver's memory footprint and may even deplete
593 + the system memory. Also, the skb truesize is altered and messages
594 + from the stack that warn against this are bypassed.
595 + This option is not available on LS1043.
596 +
597 +config FSL_DPAA_TS
598 + bool "Linux compliant timestamping"
599 + depends on FSL_SDK_DPAA_ETH
600 + default n
601 + help
602 + Enable Linux API compliant timestamping support.
603 +
604 +config FSL_DPAA_1588
605 + bool "IEEE 1588-compliant timestamping"
606 + depends on FSL_SDK_DPAA_ETH
607 + select FSL_DPAA_TS
608 + default n
609 + help
610 + Enable IEEE1588 support code.
611 +
612 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
613 + bool "Use driver's Tx queue selection mechanism"
614 + default y
615 + depends on FSL_SDK_DPAA_ETH
616 + help
617 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
618 + of the egress FQ. That will override the XPS support for this netdevice.
619 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
620 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
621 + and use the standard XPS support instead.
622 +
623 +config FSL_DPAA_ETH_MAX_BUF_COUNT
624 + int "Maximum nuber of buffers in private bpool"
625 + depends on FSL_SDK_DPAA_ETH
626 + range 64 2048
627 + default "128"
628 + help
629 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
630 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
631 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
632 +
633 +config FSL_DPAA_ETH_REFILL_THRESHOLD
634 + int "Private bpool refill threshold"
635 + depends on FSL_SDK_DPAA_ETH
636 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
637 + default "80"
638 + help
639 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
640 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
641 + modify this value unless one has very specific performance reasons.
642 +
643 +config FSL_DPAA_CS_THRESHOLD_1G
644 + hex "Egress congestion threshold on 1G ports"
645 + depends on FSL_SDK_DPAA_ETH
646 + range 0x1000 0x10000000
647 + default "0x06000000"
648 + help
649 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
650 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
651 + (e.g. by sending UDP datagrams at "while(1) speed"),
652 + and the larger the frame size, the more acute the problem.
653 + So we have to find a balance between these factors:
654 + - avoiding the device staying congested for a prolonged time (risking
655 + the netdev watchdog to fire - see also the tx_timeout module param);
656 + - affecting performance of protocols such as TCP, which otherwise
657 + behave well under the congestion notification mechanism;
658 + - preventing the Tx cores from tightly-looping (as if the congestion
659 + threshold was too low to be effective);
660 + - running out of memory if the CS threshold is set too high.
661 +
662 +config FSL_DPAA_CS_THRESHOLD_10G
663 + hex "Egress congestion threshold on 10G ports"
664 + depends on FSL_SDK_DPAA_ETH
665 + range 0x1000 0x20000000
666 + default "0x10000000"
667 + help
668 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
669 +
670 +config FSL_DPAA_INGRESS_CS_THRESHOLD
671 + hex "Ingress congestion threshold on FMan ports"
672 + depends on FSL_SDK_DPAA_ETH
673 + default "0x10000000"
674 + help
675 + The size in bytes of the ingress tail-drop threshold on FMan ports.
676 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
677 +
678 +config FSL_DPAA_ETH_DEBUGFS
679 + bool "DPAA Ethernet debugfs interface"
680 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
681 + default y
682 + help
683 + This option compiles debugfs code for the DPAA Ethernet driver.
684 +
685 +config FSL_DPAA_ETH_DEBUG
686 + bool "DPAA Ethernet Debug Support"
687 + depends on FSL_SDK_DPAA_ETH
688 + default n
689 + help
690 + This option compiles debug code for the DPAA Ethernet driver.
691 +
692 +config FSL_DPAA_DBG_LOOP
693 + bool "DPAA Ethernet Debug loopback"
694 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
695 + default n
696 + help
697 + This option allows to divert all received traffic on a certain interface A towards a
698 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
699 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
700 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
701 + change the loop setting for interface 4 and divert all received traffic to interface 5
702 + write Tx interface number in the receive interface debugfs file:
703 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
704 + 4->-1
705 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
706 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
707 + 4->5
708 +endif # FSL_SDK_DPAA_ETH
709 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
710 new file mode 100644
711 index 00000000..a0f4b190
712 --- /dev/null
713 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
714 @@ -0,0 +1,46 @@
715 +#
716 +# Makefile for the Freescale Ethernet controllers
717 +#
718 +ccflags-y += -DVERSION=\"\"
719 +#
720 +# Include netcomm SW specific definitions
721 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
722 +
723 +ccflags-y += -I$(NET_DPA)
724 +
725 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
726 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
727 +
728 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
729 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
730 +fsl_dpa-objs += dpaa_debugfs.o
731 +endif
732 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
733 +fsl_dpa-objs += dpaa_1588.o
734 +endif
735 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
736 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
737 +fsl_dpa-objs += dpaa_eth_ceetm.o
738 +endif
739 +
740 +fsl_mac-objs += mac.o mac-api.o
741 +
742 +# Advanced drivers
743 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
744 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
745 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
746 +
747 +fsl_advanced-objs += dpaa_eth_base.o
748 +# suport for multiple drivers per kernel module comes in kernel 3.14
749 +# so we are forced to generate several modules for the advanced drivers
750 +fsl_proxy-objs += dpaa_eth_proxy.o
751 +
752 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
753 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
754 +
755 +fsl_oh-objs += offline_port.o
756 +endif
757 +endif
758 +
759 +# Needed by the tracing framework
760 +CFLAGS_dpaa_eth.o := -I$(src)
761 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
762 new file mode 100644
763 index 00000000..3bf8cbca
764 --- /dev/null
765 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
766 @@ -0,0 +1,580 @@
767 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
768 + * Copyright (C) 2009 IXXAT Automation, GmbH
769 + *
770 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
771 + *
772 + * This program is free software; you can redistribute it and/or modify
773 + * it under the terms of the GNU General Public License as published by
774 + * the Free Software Foundation; either version 2 of the License, or
775 + * (at your option) any later version.
776 + *
777 + * This program is distributed in the hope that it will be useful,
778 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
779 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
780 + * GNU General Public License for more details.
781 + *
782 + * You should have received a copy of the GNU General Public License along
783 + * with this program; if not, write to the Free Software Foundation, Inc.,
784 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
785 + *
786 + */
787 +#include <linux/io.h>
788 +#include <linux/device.h>
789 +#include <linux/fs.h>
790 +#include <linux/vmalloc.h>
791 +#include <linux/spinlock.h>
792 +#include <linux/ip.h>
793 +#include <linux/ipv6.h>
794 +#include <linux/udp.h>
795 +#include <asm/div64.h>
796 +#include "dpaa_eth.h"
797 +#include "dpaa_eth_common.h"
798 +#include "dpaa_1588.h"
799 +#include "mac.h"
800 +
801 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
802 +{
803 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
804 +
805 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
806 + if (!circ_buf->buf)
807 + return 1;
808 +
809 + circ_buf->head = 0;
810 + circ_buf->tail = 0;
811 + ptp_buf->size = size;
812 + spin_lock_init(&ptp_buf->ptp_lock);
813 +
814 + return 0;
815 +}
816 +
817 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
818 +{
819 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
820 +
821 + circ_buf->head = 0;
822 + circ_buf->tail = 0;
823 + ptp_buf->size = size;
824 +}
825 +
826 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
827 + struct dpa_ptp_data *data)
828 +{
829 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
830 + int size = ptp_buf->size;
831 + struct dpa_ptp_data *tmp;
832 + unsigned long flags;
833 + int head, tail;
834 +
835 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
836 +
837 + head = circ_buf->head;
838 + tail = circ_buf->tail;
839 +
840 + if (CIRC_SPACE(head, tail, size) <= 0)
841 + circ_buf->tail = (tail + 1) & (size - 1);
842 +
843 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
844 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
845 +
846 + circ_buf->head = (head + 1) & (size - 1);
847 +
848 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
849 +
850 + return 0;
851 +}
852 +
853 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
854 + struct dpa_ptp_ident *src)
855 +{
856 + int ret;
857 +
858 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
859 + return 0;
860 +
861 + if ((dst->netw_prot == src->netw_prot)
862 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
863 + if (dst->seq_id != src->seq_id)
864 + return 0;
865 +
866 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
867 + DPA_PTP_SOURCE_PORT_LENGTH);
868 + if (ret)
869 + return 0;
870 + else
871 + return 1;
872 + }
873 +
874 + return 0;
875 +}
876 +
877 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
878 + struct dpa_ptp_ident *ident,
879 + struct dpa_ptp_time *ts)
880 +{
881 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
882 + int size = ptp_buf->size;
883 + int head, tail, idx;
884 + unsigned long flags;
885 + struct dpa_ptp_data *tmp, *tmp2;
886 + struct dpa_ptp_ident *tmp_ident;
887 +
888 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
889 +
890 + head = circ_buf->head;
891 + tail = idx = circ_buf->tail;
892 +
893 + if (CIRC_CNT(head, tail, size) == 0) {
894 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
895 + return 1;
896 + }
897 +
898 + while (idx != head) {
899 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
900 + tmp_ident = &tmp->ident;
901 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
902 + break;
903 + idx = (idx + 1) & (size - 1);
904 + }
905 +
906 + if (idx == head) {
907 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
908 + return 1;
909 + }
910 +
911 + ts->sec = tmp->ts.sec;
912 + ts->nsec = tmp->ts.nsec;
913 +
914 + if (idx != tail) {
915 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
916 + tail = circ_buf->tail =
917 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
918 + }
919 +
920 + while (CIRC_CNT(idx, tail, size) > 0) {
921 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
922 + idx = (idx - 1) & (size - 1);
923 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
924 + *tmp = *tmp2;
925 + }
926 + }
927 + circ_buf->tail = (tail + 1) & (size - 1);
928 +
929 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
930 +
931 + return 0;
932 +}
933 +
934 +/* Parse the PTP packets
935 + *
936 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
937 + * an IEEE802.3 ethernet frame. This function returns the position of
938 + * the PTP packet or NULL if no PTP found
939 + */
940 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
941 +{
942 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
943 + u8 *ptp_loc = NULL;
944 + u8 msg_type;
945 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
946 + struct iphdr *iph;
947 + struct udphdr *udph;
948 + struct ipv6hdr *ipv6h;
949 +
950 + /* when we can receive S/G frames we need to check the data we want to
951 + * access is in the linear skb buffer
952 + */
953 + if (!pskb_may_pull(skb, access_len))
954 + return NULL;
955 +
956 + *eth_type = *((u16 *)pos);
957 +
958 + /* Check if inner tag is here */
959 + if (*eth_type == ETH_P_8021Q) {
960 + access_len += DPA_VLAN_TAG_LEN;
961 +
962 + if (!pskb_may_pull(skb, access_len))
963 + return NULL;
964 +
965 + pos += DPA_VLAN_TAG_LEN;
966 + *eth_type = *((u16 *)pos);
967 + }
968 +
969 + pos += DPA_ETYPE_LEN;
970 +
971 + switch (*eth_type) {
972 + /* Transport of PTP over Ethernet */
973 + case ETH_P_1588:
974 + ptp_loc = pos;
975 +
976 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
977 + return NULL;
978 +
979 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
980 + if ((msg_type == PTP_MSGTYPE_SYNC)
981 + || (msg_type == PTP_MSGTYPE_DELREQ)
982 + || (msg_type == PTP_MSGTYPE_PDELREQ)
983 + || (msg_type == PTP_MSGTYPE_PDELRESP))
984 + return ptp_loc;
985 + break;
986 + /* Transport of PTP over IPv4 */
987 + case ETH_P_IP:
988 + iph = (struct iphdr *)pos;
989 + access_len += sizeof(struct iphdr);
990 +
991 + if (!pskb_may_pull(skb, access_len))
992 + return NULL;
993 +
994 + if (ntohs(iph->protocol) != IPPROTO_UDP)
995 + return NULL;
996 +
997 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
998 + sizeof(struct udphdr);
999 +
1000 + if (!pskb_may_pull(skb, access_len))
1001 + return NULL;
1002 +
1003 + pos += iph->ihl * 4;
1004 + udph = (struct udphdr *)pos;
1005 + if (ntohs(udph->dest) != 319)
1006 + return NULL;
1007 + ptp_loc = pos + sizeof(struct udphdr);
1008 + break;
1009 + /* Transport of PTP over IPv6 */
1010 + case ETH_P_IPV6:
1011 + ipv6h = (struct ipv6hdr *)pos;
1012 +
1013 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1014 +
1015 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1016 + return NULL;
1017 +
1018 + pos += sizeof(struct ipv6hdr);
1019 + udph = (struct udphdr *)pos;
1020 + if (ntohs(udph->dest) != 319)
1021 + return NULL;
1022 + ptp_loc = pos + sizeof(struct udphdr);
1023 + break;
1024 + default:
1025 + break;
1026 + }
1027 +
1028 + return ptp_loc;
1029 +}
1030 +
1031 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1032 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1033 + struct dpa_ptp_data *ptp_data)
1034 +{
1035 + u64 nsec;
1036 + u32 mod;
1037 + u8 *ptp_loc;
1038 + u16 eth_type;
1039 +
1040 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1041 + if (!ptp_loc)
1042 + return -EINVAL;
1043 +
1044 + switch (eth_type) {
1045 + case ETH_P_IP:
1046 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1047 + break;
1048 + case ETH_P_IPV6:
1049 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1050 + break;
1051 + case ETH_P_1588:
1052 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1053 + break;
1054 + default:
1055 + return -EINVAL;
1056 + }
1057 +
1058 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1059 + return -EINVAL;
1060 +
1061 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1062 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1063 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1064 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1065 + DPA_PTP_SOURCE_PORT_LENGTH);
1066 +
1067 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1068 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1069 + ptp_data->ts.sec = nsec;
1070 + ptp_data->ts.nsec = mod;
1071 +
1072 + return 0;
1073 +}
1074 +
1075 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1076 + struct sk_buff *skb, void *data)
1077 +{
1078 + struct dpa_ptp_tsu *tsu = priv->tsu;
1079 + struct dpa_ptp_data ptp_tx_data;
1080 +
1081 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1082 + return;
1083 +
1084 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1085 +}
1086 +
1087 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1088 + struct sk_buff *skb, void *data)
1089 +{
1090 + struct dpa_ptp_tsu *tsu = priv->tsu;
1091 + struct dpa_ptp_data ptp_rx_data;
1092 +
1093 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1094 + return;
1095 +
1096 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1097 +}
1098 +
1099 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1100 + struct dpa_ptp_ident *ident,
1101 + struct dpa_ptp_time *ts)
1102 +{
1103 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1104 + struct dpa_ptp_time tmp;
1105 + int flag;
1106 +
1107 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1108 + if (!flag) {
1109 + ts->sec = tmp.sec;
1110 + ts->nsec = tmp.nsec;
1111 + return 0;
1112 + }
1113 +
1114 + return -1;
1115 +}
1116 +
1117 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1118 + struct dpa_ptp_ident *ident,
1119 + struct dpa_ptp_time *ts)
1120 +{
1121 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1122 + struct dpa_ptp_time tmp;
1123 + int flag;
1124 +
1125 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1126 + if (!flag) {
1127 + ts->sec = tmp.sec;
1128 + ts->nsec = tmp.nsec;
1129 + return 0;
1130 + }
1131 +
1132 + return -1;
1133 +}
1134 +
1135 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1136 + struct dpa_ptp_time *cnt_time)
1137 +{
1138 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1139 + u64 tmp, fiper;
1140 +
1141 + if (mac_dev->fm_rtc_disable)
1142 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1143 +
1144 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1145 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1146 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1147 + if (mac_dev->fm_rtc_set_alarm)
1148 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1149 + 0, tmp);
1150 + if (mac_dev->fm_rtc_set_fiper)
1151 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1152 + 0, fiper);
1153 +
1154 + if (mac_dev->fm_rtc_enable)
1155 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1156 +}
1157 +
1158 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1159 + struct dpa_ptp_time *curr_time)
1160 +{
1161 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1162 + u64 tmp;
1163 + u32 mod;
1164 +
1165 + if (mac_dev->fm_rtc_get_cnt)
1166 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1167 + &tmp);
1168 +
1169 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1170 + curr_time->sec = (u32)tmp;
1171 + curr_time->nsec = mod;
1172 +}
1173 +
1174 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1175 + struct dpa_ptp_time *cnt_time)
1176 +{
1177 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1178 + u64 tmp;
1179 +
1180 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1181 +
1182 + if (mac_dev->fm_rtc_set_cnt)
1183 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1184 + tmp);
1185 +
1186 + /* Restart fiper two seconds later */
1187 + cnt_time->sec += 2;
1188 + cnt_time->nsec = 0;
1189 + dpa_set_fiper_alarm(tsu, cnt_time);
1190 +}
1191 +
1192 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1193 +{
1194 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1195 + u32 drift;
1196 +
1197 + if (mac_dev->fm_rtc_get_drift)
1198 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1199 + &drift);
1200 +
1201 + *addend = drift;
1202 +}
1203 +
1204 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1205 +{
1206 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1207 +
1208 + if (mac_dev->fm_rtc_set_drift)
1209 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1210 + addend);
1211 +}
1212 +
1213 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1214 +{
1215 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1216 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1217 +}
1218 +
1219 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1220 +{
1221 + struct dpa_priv_s *priv = netdev_priv(dev);
1222 + struct dpa_ptp_tsu *tsu = priv->tsu;
1223 + struct mac_device *mac_dev = priv->mac_dev;
1224 + struct dpa_ptp_data ptp_data;
1225 + struct dpa_ptp_data *ptp_data_user;
1226 + struct dpa_ptp_time act_time;
1227 + u32 addend;
1228 + int retval = 0;
1229 +
1230 + if (!tsu || !tsu->valid)
1231 + return -ENODEV;
1232 +
1233 + switch (cmd) {
1234 + case PTP_ENBL_TXTS_IOCTL:
1235 + tsu->hwts_tx_en_ioctl = 1;
1236 + if (mac_dev->fm_rtc_enable)
1237 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1238 + if (mac_dev->ptp_enable)
1239 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1240 + break;
1241 + case PTP_DSBL_TXTS_IOCTL:
1242 + tsu->hwts_tx_en_ioctl = 0;
1243 + if (mac_dev->fm_rtc_disable)
1244 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1245 + if (mac_dev->ptp_disable)
1246 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1247 + break;
1248 + case PTP_ENBL_RXTS_IOCTL:
1249 + tsu->hwts_rx_en_ioctl = 1;
1250 + break;
1251 + case PTP_DSBL_RXTS_IOCTL:
1252 + tsu->hwts_rx_en_ioctl = 0;
1253 + break;
1254 + case PTP_GET_RX_TIMESTAMP:
1255 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1256 + if (copy_from_user(&ptp_data.ident,
1257 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1258 + return -EINVAL;
1259 +
1260 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1261 + return -EAGAIN;
1262 +
1263 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1264 + &ptp_data.ts, sizeof(ptp_data.ts)))
1265 + return -EFAULT;
1266 + break;
1267 + case PTP_GET_TX_TIMESTAMP:
1268 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1269 + if (copy_from_user(&ptp_data.ident,
1270 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1271 + return -EINVAL;
1272 +
1273 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1274 + return -EAGAIN;
1275 +
1276 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1277 + &ptp_data.ts, sizeof(ptp_data.ts)))
1278 + return -EFAULT;
1279 + break;
1280 + case PTP_GET_TIME:
1281 + dpa_get_curr_cnt(tsu, &act_time);
1282 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1283 + return -EFAULT;
1284 + break;
1285 + case PTP_SET_TIME:
1286 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1287 + return -EINVAL;
1288 + dpa_set_1588cnt(tsu, &act_time);
1289 + break;
1290 + case PTP_GET_ADJ:
1291 + dpa_get_drift(tsu, &addend);
1292 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1293 + return -EFAULT;
1294 + break;
1295 + case PTP_SET_ADJ:
1296 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1297 + return -EINVAL;
1298 + dpa_set_drift(tsu, addend);
1299 + break;
1300 + case PTP_SET_FIPER_ALARM:
1301 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1302 + return -EINVAL;
1303 + dpa_set_fiper_alarm(tsu, &act_time);
1304 + break;
1305 + case PTP_CLEANUP_TS:
1306 + dpa_flush_timestamp(tsu);
1307 + break;
1308 + default:
1309 + return -EINVAL;
1310 + }
1311 +
1312 + return retval;
1313 +}
1314 +
1315 +int dpa_ptp_init(struct dpa_priv_s *priv)
1316 +{
1317 + struct dpa_ptp_tsu *tsu;
1318 +
1319 + /* Allocate memory for PTP structure */
1320 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1321 + if (!tsu)
1322 + return -ENOMEM;
1323 +
1324 + tsu->valid = TRUE;
1325 + tsu->dpa_priv = priv;
1326 +
1327 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1328 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1329 +
1330 + priv->tsu = tsu;
1331 +
1332 + return 0;
1333 +}
1334 +EXPORT_SYMBOL(dpa_ptp_init);
1335 +
1336 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1337 +{
1338 + struct dpa_ptp_tsu *tsu = priv->tsu;
1339 +
1340 + tsu->valid = FALSE;
1341 + vfree(tsu->rx_timestamps.circ_buf.buf);
1342 + vfree(tsu->tx_timestamps.circ_buf.buf);
1343 +
1344 + kfree(tsu);
1345 +}
1346 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1347 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1348 new file mode 100644
1349 index 00000000..73390168
1350 --- /dev/null
1351 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1352 @@ -0,0 +1,138 @@
1353 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1354 + *
1355 + * This program is free software; you can redistribute it and/or modify
1356 + * it under the terms of the GNU General Public License as published by
1357 + * the Free Software Foundation; either version 2 of the License, or
1358 + * (at your option) any later version.
1359 + *
1360 + * This program is distributed in the hope that it will be useful,
1361 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1362 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1363 + * GNU General Public License for more details.
1364 + *
1365 + * You should have received a copy of the GNU General Public License along
1366 + * with this program; if not, write to the Free Software Foundation, Inc.,
1367 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1368 + *
1369 + */
1370 +#ifndef __DPAA_1588_H__
1371 +#define __DPAA_1588_H__
1372 +
1373 +#include <linux/netdevice.h>
1374 +#include <linux/etherdevice.h>
1375 +#include <linux/circ_buf.h>
1376 +#include <linux/fsl_qman.h>
1377 +
1378 +#define DEFAULT_PTP_RX_BUF_SZ 256
1379 +#define DEFAULT_PTP_TX_BUF_SZ 256
1380 +
1381 +/* 1588 private ioctl calls */
1382 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1383 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1384 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1385 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1386 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1387 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1388 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1389 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1390 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1391 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1392 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1393 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1394 +
1395 +/* PTP V2 message type */
1396 +enum {
1397 + PTP_MSGTYPE_SYNC = 0x0,
1398 + PTP_MSGTYPE_DELREQ = 0x1,
1399 + PTP_MSGTYPE_PDELREQ = 0x2,
1400 + PTP_MSGTYPE_PDELRESP = 0x3,
1401 + PTP_MSGTYPE_FLWUP = 0x8,
1402 + PTP_MSGTYPE_DELRESP = 0x9,
1403 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1404 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1405 + PTP_MSGTYPE_SGNLNG = 0xC,
1406 + PTP_MSGTYPE_MNGMNT = 0xD,
1407 +};
1408 +
1409 +/* Byte offset of data in the PTP V2 headers */
1410 +#define PTP_OFFS_MSG_TYPE 0
1411 +#define PTP_OFFS_VER_PTP 1
1412 +#define PTP_OFFS_MSG_LEN 2
1413 +#define PTP_OFFS_DOM_NMB 4
1414 +#define PTP_OFFS_FLAGS 6
1415 +#define PTP_OFFS_CORFIELD 8
1416 +#define PTP_OFFS_SRCPRTID 20
1417 +#define PTP_OFFS_SEQ_ID 30
1418 +#define PTP_OFFS_CTRL 32
1419 +#define PTP_OFFS_LOGMEAN 33
1420 +
1421 +#define PTP_IP_OFFS 14
1422 +#define PTP_UDP_OFFS 34
1423 +#define PTP_HEADER_OFFS 42
1424 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1425 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1426 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1427 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1428 +
1429 +/* 1588-2008 network protocol enumeration values */
1430 +#define DPA_PTP_PROT_IPV4 1
1431 +#define DPA_PTP_PROT_IPV6 2
1432 +#define DPA_PTP_PROT_802_3 3
1433 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1434 +
1435 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1436 +#define DPA_PTP_HEADER_SZE 34
1437 +#define DPA_ETYPE_LEN 2
1438 +#define DPA_VLAN_TAG_LEN 4
1439 +#define NANOSEC_PER_SECOND 1000000000
1440 +
1441 +/* The threshold between the current found one and the oldest one */
1442 +#define TS_ACCUMULATION_THRESHOLD 50
1443 +
1444 +/* Struct needed to identify a timestamp */
1445 +struct dpa_ptp_ident {
1446 + u8 version;
1447 + u8 msg_type;
1448 + u16 netw_prot;
1449 + u16 seq_id;
1450 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1451 +};
1452 +
1453 +/* Timestamp format in 1588-2008 */
1454 +struct dpa_ptp_time {
1455 + u64 sec; /* just 48 bit used */
1456 + u32 nsec;
1457 +};
1458 +
1459 +/* needed for timestamp data over ioctl */
1460 +struct dpa_ptp_data {
1461 + struct dpa_ptp_ident ident;
1462 + struct dpa_ptp_time ts;
1463 +};
1464 +
1465 +struct dpa_ptp_circ_buf {
1466 + struct circ_buf circ_buf;
1467 + u32 size;
1468 + spinlock_t ptp_lock;
1469 +};
1470 +
1471 +/* PTP TSU control structure */
1472 +struct dpa_ptp_tsu {
1473 + struct dpa_priv_s *dpa_priv;
1474 + bool valid;
1475 + struct dpa_ptp_circ_buf rx_timestamps;
1476 + struct dpa_ptp_circ_buf tx_timestamps;
1477 +
1478 + /* HW timestamping over ioctl enabled flag */
1479 + int hwts_tx_en_ioctl;
1480 + int hwts_rx_en_ioctl;
1481 +};
1482 +
1483 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1484 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1485 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1486 + struct sk_buff *skb, void *data);
1487 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1488 + struct sk_buff *skb, void *data);
1489 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1490 +#endif
1491 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1492 new file mode 100644
1493 index 00000000..25d9f5f1
1494 --- /dev/null
1495 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1496 @@ -0,0 +1,180 @@
1497 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1498 + *
1499 + * Redistribution and use in source and binary forms, with or without
1500 + * modification, are permitted provided that the following conditions are met:
1501 + * * Redistributions of source code must retain the above copyright
1502 + * notice, this list of conditions and the following disclaimer.
1503 + * * Redistributions in binary form must reproduce the above copyright
1504 + * notice, this list of conditions and the following disclaimer in the
1505 + * documentation and/or other materials provided with the distribution.
1506 + * * Neither the name of Freescale Semiconductor nor the
1507 + * names of its contributors may be used to endorse or promote products
1508 + * derived from this software without specific prior written permission.
1509 + *
1510 + *
1511 + * ALTERNATIVELY, this software may be distributed under the terms of the
1512 + * GNU General Public License ("GPL") as published by the Free Software
1513 + * Foundation, either version 2 of that License or (at your option) any
1514 + * later version.
1515 + *
1516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1526 + */
1527 +
1528 +#include <linux/module.h>
1529 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1530 +#include <linux/debugfs.h>
1531 +#include "dpaa_debugfs.h"
1532 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1533 +
1534 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1535 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1536 +
1537 +static struct dentry *dpa_debugfs_root;
1538 +
1539 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1540 +static ssize_t dpa_loop_write(struct file *f,
1541 + const char __user *buf, size_t count, loff_t *off);
1542 +
1543 +static const struct file_operations dpa_debugfs_lp_fops = {
1544 + .open = dpa_debugfs_loop_open,
1545 + .write = dpa_loop_write,
1546 + .read = seq_read,
1547 + .llseek = seq_lseek,
1548 + .release = single_release,
1549 +};
1550 +
1551 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1552 +{
1553 + struct dpa_priv_s *priv;
1554 +
1555 + BUG_ON(offset == NULL);
1556 +
1557 + priv = netdev_priv((struct net_device *)file->private);
1558 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1559 +
1560 + return 0;
1561 +}
1562 +
1563 +static int user_input_convert(const char __user *user_buf, size_t count,
1564 + long *val)
1565 +{
1566 + char buf[12];
1567 +
1568 + if (count > sizeof(buf) - 1)
1569 + return -EINVAL;
1570 + if (copy_from_user(buf, user_buf, count))
1571 + return -EFAULT;
1572 + buf[count] = '\0';
1573 + if (kstrtol(buf, 0, val))
1574 + return -EINVAL;
1575 + return 0;
1576 +}
1577 +
1578 +static ssize_t dpa_loop_write(struct file *f,
1579 + const char __user *buf, size_t count, loff_t *off)
1580 +{
1581 + struct dpa_priv_s *priv;
1582 + struct net_device *netdev;
1583 + struct seq_file *sf;
1584 + int ret;
1585 + long val;
1586 +
1587 + ret = user_input_convert(buf, count, &val);
1588 + if (ret)
1589 + return ret;
1590 +
1591 + sf = (struct seq_file *)f->private_data;
1592 + netdev = (struct net_device *)sf->private;
1593 + priv = netdev_priv(netdev);
1594 +
1595 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1596 +
1597 + return count;
1598 +}
1599 +
1600 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1601 +{
1602 + int _errno;
1603 + const struct net_device *net_dev;
1604 +
1605 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1606 + if (unlikely(_errno < 0)) {
1607 + net_dev = (struct net_device *)inode->i_private;
1608 +
1609 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1610 + netdev_err(net_dev, "single_open() = %d\n",
1611 + _errno);
1612 + }
1613 +
1614 + return _errno;
1615 +}
1616 +
1617 +
1618 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1619 +{
1620 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1621 + static int cnt;
1622 + char loop_file_name[100];
1623 +
1624 + if (unlikely(dpa_debugfs_root == NULL)) {
1625 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1626 + KBUILD_BASENAME".c", __LINE__, __func__,
1627 + "root debugfs missing, possible module ordering issue");
1628 + return -ENOMEM;
1629 + }
1630 +
1631 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1632 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1633 + S_IRUGO,
1634 + dpa_debugfs_root,
1635 + net_dev,
1636 + &dpa_debugfs_lp_fops);
1637 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1638 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1639 + dpa_debugfs_root->d_iname,
1640 + loop_file_name);
1641 +
1642 + return -ENOMEM;
1643 + }
1644 + return 0;
1645 +}
1646 +
1647 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1648 +{
1649 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1650 +
1651 + debugfs_remove(priv->debugfs_loop_file);
1652 +}
1653 +
1654 +int __init dpa_debugfs_module_init(void)
1655 +{
1656 + int _errno = 0;
1657 +
1658 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1659 +
1660 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1661 +
1662 + if (unlikely(dpa_debugfs_root == NULL)) {
1663 + _errno = -ENOMEM;
1664 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1665 + KBUILD_BASENAME".c", __LINE__, __func__);
1666 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1667 + DPA_ETH_DEBUGFS_ROOT, _errno);
1668 + }
1669 +
1670 + return _errno;
1671 +}
1672 +
1673 +void __exit dpa_debugfs_module_exit(void)
1674 +{
1675 + debugfs_remove(dpa_debugfs_root);
1676 +}
1677 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1678 new file mode 100644
1679 index 00000000..63d35427
1680 --- /dev/null
1681 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1682 @@ -0,0 +1,43 @@
1683 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1684 + *
1685 + * Redistribution and use in source and binary forms, with or without
1686 + * modification, are permitted provided that the following conditions are met:
1687 + * * Redistributions of source code must retain the above copyright
1688 + * notice, this list of conditions and the following disclaimer.
1689 + * * Redistributions in binary form must reproduce the above copyright
1690 + * notice, this list of conditions and the following disclaimer in the
1691 + * documentation and/or other materials provided with the distribution.
1692 + * * Neither the name of Freescale Semiconductor nor the
1693 + * names of its contributors may be used to endorse or promote products
1694 + * derived from this software without specific prior written permission.
1695 + *
1696 + *
1697 + * ALTERNATIVELY, this software may be distributed under the terms of the
1698 + * GNU General Public License ("GPL") as published by the Free Software
1699 + * Foundation, either version 2 of that License or (at your option) any
1700 + * later version.
1701 + *
1702 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1703 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1704 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1705 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1706 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1707 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1708 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1709 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1710 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1711 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1712 + */
1713 +
1714 +#ifndef DPAA_DEBUGFS_H_
1715 +#define DPAA_DEBUGFS_H_
1716 +
1717 +#include <linux/netdevice.h>
1718 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1719 +
1720 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1721 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1722 +int __init dpa_debugfs_module_init(void);
1723 +void __exit dpa_debugfs_module_exit(void);
1724 +
1725 +#endif /* DPAA_DEBUGFS_H_ */
1726 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1727 new file mode 100644
1728 index 00000000..7026f916
1729 --- /dev/null
1730 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1731 @@ -0,0 +1,1213 @@
1732 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1733 + *
1734 + * Redistribution and use in source and binary forms, with or without
1735 + * modification, are permitted provided that the following conditions are met:
1736 + * * Redistributions of source code must retain the above copyright
1737 + * notice, this list of conditions and the following disclaimer.
1738 + * * Redistributions in binary form must reproduce the above copyright
1739 + * notice, this list of conditions and the following disclaimer in the
1740 + * documentation and/or other materials provided with the distribution.
1741 + * * Neither the name of Freescale Semiconductor nor the
1742 + * names of its contributors may be used to endorse or promote products
1743 + * derived from this software without specific prior written permission.
1744 + *
1745 + *
1746 + * ALTERNATIVELY, this software may be distributed under the terms of the
1747 + * GNU General Public License ("GPL") as published by the Free Software
1748 + * Foundation, either version 2 of that License or (at your option) any
1749 + * later version.
1750 + *
1751 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1752 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1753 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1754 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1755 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1756 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1757 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1758 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1759 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1760 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1761 + */
1762 +
1763 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1764 +#define pr_fmt(fmt) \
1765 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1766 + KBUILD_BASENAME".c", __LINE__, __func__
1767 +#else
1768 +#define pr_fmt(fmt) \
1769 + KBUILD_MODNAME ": " fmt
1770 +#endif
1771 +
1772 +#include <linux/init.h>
1773 +#include <linux/module.h>
1774 +#include <linux/of_mdio.h>
1775 +#include <linux/of_net.h>
1776 +#include <linux/kthread.h>
1777 +#include <linux/io.h>
1778 +#include <linux/if_arp.h> /* arp_hdr_len() */
1779 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1780 +#include <linux/icmp.h> /* struct icmphdr */
1781 +#include <linux/ip.h> /* struct iphdr */
1782 +#include <linux/ipv6.h> /* struct ipv6hdr */
1783 +#include <linux/udp.h> /* struct udphdr */
1784 +#include <linux/tcp.h> /* struct tcphdr */
1785 +#include <linux/net.h> /* net_ratelimit() */
1786 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1787 +#include <linux/highmem.h>
1788 +#include <linux/percpu.h>
1789 +#include <linux/dma-mapping.h>
1790 +#include <linux/fsl_bman.h>
1791 +#ifdef CONFIG_SOC_BUS
1792 +#include <linux/sys_soc.h> /* soc_device_match */
1793 +#endif
1794 +
1795 +#include "fsl_fman.h"
1796 +#include "fm_ext.h"
1797 +#include "fm_port_ext.h"
1798 +
1799 +#include "mac.h"
1800 +#include "dpaa_eth.h"
1801 +#include "dpaa_eth_common.h"
1802 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1803 +#include "dpaa_debugfs.h"
1804 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1805 +
1806 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1807 + * using trace events only need to #include <trace/events/sched.h>
1808 + */
1809 +#define CREATE_TRACE_POINTS
1810 +#include "dpaa_eth_trace.h"
1811 +
1812 +#define DPA_NAPI_WEIGHT 64
1813 +
1814 +/* Valid checksum indication */
1815 +#define DPA_CSUM_VALID 0xFFFF
1816 +
1817 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1818 +
1819 +MODULE_LICENSE("Dual BSD/GPL");
1820 +
1821 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1822 +
1823 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1824 +
1825 +static uint8_t debug = -1;
1826 +module_param(debug, byte, S_IRUGO);
1827 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1828 +
1829 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1830 +static uint16_t tx_timeout = 1000;
1831 +module_param(tx_timeout, ushort, S_IRUGO);
1832 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1833 +
1834 +static const char rtx[][3] = {
1835 + [RX] = "RX",
1836 + [TX] = "TX"
1837 +};
1838 +
1839 +#ifndef CONFIG_PPC
1840 +bool dpaa_errata_a010022;
1841 +EXPORT_SYMBOL(dpaa_errata_a010022);
1842 +#endif
1843 +
1844 +/* BM */
1845 +
1846 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1847 +
1848 +static uint8_t dpa_priv_common_bpid;
1849 +
1850 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1851 +struct net_device *dpa_loop_netdevs[20];
1852 +#endif
1853 +
1854 +#ifdef CONFIG_PM
1855 +
1856 +static int dpaa_suspend(struct device *dev)
1857 +{
1858 + struct net_device *net_dev;
1859 + struct dpa_priv_s *priv;
1860 + struct mac_device *mac_dev;
1861 + int err = 0;
1862 +
1863 + net_dev = dev_get_drvdata(dev);
1864 +
1865 + if (net_dev->flags & IFF_UP) {
1866 + priv = netdev_priv(net_dev);
1867 + mac_dev = priv->mac_dev;
1868 +
1869 + if (priv->wol & DPAA_WOL_MAGIC) {
1870 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1871 + priv->mac_dev->get_mac_handle(mac_dev), true);
1872 + if (err) {
1873 + netdev_err(net_dev, "set_wol() = %d\n", err);
1874 + goto set_wol_failed;
1875 + }
1876 + }
1877 +
1878 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1879 + if (err) {
1880 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1881 + goto rx_port_suspend_failed;
1882 + }
1883 +
1884 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1885 + if (err) {
1886 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1887 + goto tx_port_suspend_failed;
1888 + }
1889 + }
1890 +
1891 + return 0;
1892 +
1893 +tx_port_suspend_failed:
1894 + fm_port_resume(mac_dev->port_dev[RX]);
1895 +rx_port_suspend_failed:
1896 + if (priv->wol & DPAA_WOL_MAGIC) {
1897 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1898 + priv->mac_dev->get_mac_handle(mac_dev), false);
1899 + }
1900 +set_wol_failed:
1901 + return err;
1902 +}
1903 +
1904 +static int dpaa_resume(struct device *dev)
1905 +{
1906 + struct net_device *net_dev;
1907 + struct dpa_priv_s *priv;
1908 + struct mac_device *mac_dev;
1909 + int err = 0;
1910 +
1911 + net_dev = dev_get_drvdata(dev);
1912 +
1913 + if (net_dev->flags & IFF_UP) {
1914 + priv = netdev_priv(net_dev);
1915 + mac_dev = priv->mac_dev;
1916 +
1917 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1918 + if (err) {
1919 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1920 + goto resume_failed;
1921 + }
1922 +
1923 + err = fm_port_resume(mac_dev->port_dev[TX]);
1924 + if (err) {
1925 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1926 + goto resume_failed;
1927 + }
1928 +
1929 + err = fm_port_resume(mac_dev->port_dev[RX]);
1930 + if (err) {
1931 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1932 + goto resume_failed;
1933 + }
1934 +
1935 + if (priv->wol & DPAA_WOL_MAGIC) {
1936 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1937 + priv->mac_dev->get_mac_handle(mac_dev), false);
1938 + if (err) {
1939 + netdev_err(net_dev, "set_wol() = %d\n", err);
1940 + goto resume_failed;
1941 + }
1942 + }
1943 + }
1944 +
1945 + return 0;
1946 +
1947 +resume_failed:
1948 + return err;
1949 +}
1950 +
1951 +static const struct dev_pm_ops dpaa_pm_ops = {
1952 + .suspend = dpaa_suspend,
1953 + .resume = dpaa_resume,
1954 +};
1955 +
1956 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1957 +
1958 +#else /* CONFIG_PM */
1959 +
1960 +#define DPAA_PM_OPS NULL
1961 +
1962 +#endif /* CONFIG_PM */
1963 +
1964 +/* Checks whether the checksum field in Parse Results array is valid
1965 + * (equals 0xFFFF) and increments the .cse counter otherwise
1966 + */
1967 +static inline void
1968 +dpa_csum_validation(const struct dpa_priv_s *priv,
1969 + struct dpa_percpu_priv_s *percpu_priv,
1970 + const struct qm_fd *fd)
1971 +{
1972 + dma_addr_t addr = qm_fd_addr(fd);
1973 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1974 + void *frm = phys_to_virt(addr);
1975 + fm_prs_result_t *parse_result;
1976 +
1977 + if (unlikely(!frm))
1978 + return;
1979 +
1980 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1981 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1982 +
1983 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1984 +
1985 + if (parse_result->cksum != DPA_CSUM_VALID)
1986 + percpu_priv->rx_errors.cse++;
1987 +}
1988 +
1989 +static void _dpa_rx_error(struct net_device *net_dev,
1990 + const struct dpa_priv_s *priv,
1991 + struct dpa_percpu_priv_s *percpu_priv,
1992 + const struct qm_fd *fd,
1993 + u32 fqid)
1994 +{
1995 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1996 + * interference with zero-loss convergence benchmark results.
1997 + */
1998 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
1999 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
2000 + else
2001 + if (netif_msg_hw(priv) && net_ratelimit())
2002 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
2003 + fd->status & FM_FD_STAT_RX_ERRORS);
2004 +#ifdef CONFIG_FSL_DPAA_HOOKS
2005 + if (dpaa_eth_hooks.rx_error &&
2006 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2007 + /* it's up to the hook to perform resource cleanup */
2008 + return;
2009 +#endif
2010 + percpu_priv->stats.rx_errors++;
2011 +
2012 + if (fd->status & FM_PORT_FRM_ERR_DMA)
2013 + percpu_priv->rx_errors.dme++;
2014 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
2015 + percpu_priv->rx_errors.fpe++;
2016 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
2017 + percpu_priv->rx_errors.fse++;
2018 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
2019 + percpu_priv->rx_errors.phe++;
2020 + if (fd->status & FM_FD_STAT_L4CV)
2021 + dpa_csum_validation(priv, percpu_priv, fd);
2022 +
2023 + dpa_fd_release(net_dev, fd);
2024 +}
2025 +
2026 +static void _dpa_tx_error(struct net_device *net_dev,
2027 + const struct dpa_priv_s *priv,
2028 + struct dpa_percpu_priv_s *percpu_priv,
2029 + const struct qm_fd *fd,
2030 + u32 fqid)
2031 +{
2032 + struct sk_buff *skb;
2033 +
2034 + if (netif_msg_hw(priv) && net_ratelimit())
2035 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2036 + fd->status & FM_FD_STAT_TX_ERRORS);
2037 +#ifdef CONFIG_FSL_DPAA_HOOKS
2038 + if (dpaa_eth_hooks.tx_error &&
2039 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2040 + /* now the hook must ensure proper cleanup */
2041 + return;
2042 +#endif
2043 + percpu_priv->stats.tx_errors++;
2044 +
2045 + /* If we intended the buffers from this frame to go into the bpools
2046 + * when the FMan transmit was done, we need to put it in manually.
2047 + */
2048 + if (fd->bpid != 0xff) {
2049 + dpa_fd_release(net_dev, fd);
2050 + return;
2051 + }
2052 +
2053 + skb = _dpa_cleanup_tx_fd(priv, fd);
2054 + dev_kfree_skb(skb);
2055 +}
2056 +
2057 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2058 + * purpose is to extract from the Parse Results structure information about
2059 + * the integrity of the frame, its checksum, the length of the parsed headers
2060 + * and whether the frame is suitable for GRO.
2061 + *
2062 + * Assumes no parser errors, since any error frame is dropped before this
2063 + * function is called.
2064 + *
2065 + * @skb will have its ip_summed field overwritten;
2066 + * @use_gro will only be written with 0, if the frame is definitely not
2067 + * GRO-able; otherwise, it will be left unchanged;
2068 + * @hdr_size will be written with a safe value, at least the size of the
2069 + * headers' length.
2070 + */
2071 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2072 + const struct qm_fd *fd,
2073 + struct sk_buff *skb, int *use_gro)
2074 +{
2075 + if (fd->status & FM_FD_STAT_L4CV) {
2076 + /* The parser has run and performed L4 checksum validation.
2077 + * We know there were no parser errors (and implicitly no
2078 + * L4 csum error), otherwise we wouldn't be here.
2079 + */
2080 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2081 +
2082 + /* Don't go through GRO for certain types of traffic that
2083 + * we know are not GRO-able, such as dgram-based protocols.
2084 + * In the worst-case scenarios, such as small-pkt terminating
2085 + * UDP, the extra GRO processing would be overkill.
2086 + *
2087 + * The only protocol the Parser supports that is also GRO-able
2088 + * is currently TCP.
2089 + */
2090 + if (!fm_l4_frame_is_tcp(parse_results))
2091 + *use_gro = 0;
2092 +
2093 + return;
2094 + }
2095 +
2096 + /* We're here because either the parser didn't run or the L4 checksum
2097 + * was not verified. This may include the case of a UDP frame with
2098 + * checksum zero or an L4 proto other than TCP/UDP
2099 + */
2100 + skb->ip_summed = CHECKSUM_NONE;
2101 +
2102 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2103 + *use_gro = 0;
2104 +}
2105 +
2106 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2107 +{
2108 + struct dpa_napi_portal *np =
2109 + container_of(napi, struct dpa_napi_portal, napi);
2110 +
2111 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2112 +
2113 + if (cleaned < budget) {
2114 + int tmp;
2115 + napi_complete(napi);
2116 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2117 + DPA_BUG_ON(tmp);
2118 + }
2119 +
2120 + return cleaned;
2121 +}
2122 +EXPORT_SYMBOL(dpaa_eth_poll);
2123 +
2124 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2125 + const struct dpa_priv_s *priv,
2126 + struct dpa_percpu_priv_s *percpu_priv,
2127 + const struct qm_fd *fd,
2128 + u32 fqid)
2129 +{
2130 + struct sk_buff *skb;
2131 +
2132 + /* do we need the timestamp for the error frames? */
2133 +
2134 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2135 + if (netif_msg_hw(priv) && net_ratelimit())
2136 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2137 + fd->status & FM_FD_STAT_TX_ERRORS);
2138 +
2139 + percpu_priv->stats.tx_errors++;
2140 + }
2141 +
2142 + /* hopefully we need not get the timestamp before the hook */
2143 +#ifdef CONFIG_FSL_DPAA_HOOKS
2144 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2145 + fd, fqid) == DPAA_ETH_STOLEN)
2146 + /* it's the hook that must now perform cleanup */
2147 + return;
2148 +#endif
2149 + /* This might not perfectly reflect the reality, if the core dequeuing
2150 + * the Tx confirmation is different from the one that did the enqueue,
2151 + * but at least it'll show up in the total count.
2152 + */
2153 + percpu_priv->tx_confirm++;
2154 +
2155 + skb = _dpa_cleanup_tx_fd(priv, fd);
2156 +
2157 + dev_kfree_skb(skb);
2158 +}
2159 +
2160 +enum qman_cb_dqrr_result
2161 +priv_rx_error_dqrr(struct qman_portal *portal,
2162 + struct qman_fq *fq,
2163 + const struct qm_dqrr_entry *dq)
2164 +{
2165 + struct net_device *net_dev;
2166 + struct dpa_priv_s *priv;
2167 + struct dpa_percpu_priv_s *percpu_priv;
2168 + int *count_ptr;
2169 +
2170 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2171 + priv = netdev_priv(net_dev);
2172 +
2173 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2174 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2175 +
2176 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2177 + return qman_cb_dqrr_stop;
2178 +
2179 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2180 + /* Unable to refill the buffer pool due to insufficient
2181 + * system memory. Just release the frame back into the pool,
2182 + * otherwise we'll soon end up with an empty buffer pool.
2183 + */
2184 + dpa_fd_release(net_dev, &dq->fd);
2185 + else
2186 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2187 +
2188 + return qman_cb_dqrr_consume;
2189 +}
2190 +
2191 +
2192 +enum qman_cb_dqrr_result __hot
2193 +priv_rx_default_dqrr(struct qman_portal *portal,
2194 + struct qman_fq *fq,
2195 + const struct qm_dqrr_entry *dq)
2196 +{
2197 + struct net_device *net_dev;
2198 + struct dpa_priv_s *priv;
2199 + struct dpa_percpu_priv_s *percpu_priv;
2200 + int *count_ptr;
2201 + struct dpa_bp *dpa_bp;
2202 +
2203 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2204 + priv = netdev_priv(net_dev);
2205 + dpa_bp = priv->dpa_bp;
2206 +
2207 + /* Trace the Rx fd */
2208 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2209 +
2210 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2211 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2212 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2213 +
2214 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2215 + return qman_cb_dqrr_stop;
2216 +
2217 + /* Vale of plenty: make sure we didn't run out of buffers */
2218 +
2219 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2220 + /* Unable to refill the buffer pool due to insufficient
2221 + * system memory. Just release the frame back into the pool,
2222 + * otherwise we'll soon end up with an empty buffer pool.
2223 + */
2224 + dpa_fd_release(net_dev, &dq->fd);
2225 + else
2226 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2227 + count_ptr);
2228 +
2229 + return qman_cb_dqrr_consume;
2230 +}
2231 +
2232 +enum qman_cb_dqrr_result
2233 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2234 + struct qman_fq *fq,
2235 + const struct qm_dqrr_entry *dq)
2236 +{
2237 + struct net_device *net_dev;
2238 + struct dpa_priv_s *priv;
2239 + struct dpa_percpu_priv_s *percpu_priv;
2240 +
2241 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2242 + priv = netdev_priv(net_dev);
2243 +
2244 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2245 +
2246 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2247 + return qman_cb_dqrr_stop;
2248 +
2249 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2250 +
2251 + return qman_cb_dqrr_consume;
2252 +}
2253 +
2254 +enum qman_cb_dqrr_result __hot
2255 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2256 + struct qman_fq *fq,
2257 + const struct qm_dqrr_entry *dq)
2258 +{
2259 + struct net_device *net_dev;
2260 + struct dpa_priv_s *priv;
2261 + struct dpa_percpu_priv_s *percpu_priv;
2262 +
2263 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2264 + priv = netdev_priv(net_dev);
2265 +
2266 + /* Trace the fd */
2267 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2268 +
2269 + /* Non-migratable context, safe to use raw_cpu_ptr */
2270 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2271 +
2272 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2273 + return qman_cb_dqrr_stop;
2274 +
2275 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2276 +
2277 + return qman_cb_dqrr_consume;
2278 +}
2279 +
2280 +void priv_ern(struct qman_portal *portal,
2281 + struct qman_fq *fq,
2282 + const struct qm_mr_entry *msg)
2283 +{
2284 + struct net_device *net_dev;
2285 + const struct dpa_priv_s *priv;
2286 + struct sk_buff *skb;
2287 + struct dpa_percpu_priv_s *percpu_priv;
2288 + struct qm_fd fd = msg->ern.fd;
2289 +
2290 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2291 + priv = netdev_priv(net_dev);
2292 + /* Non-migratable context, safe to use raw_cpu_ptr */
2293 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2294 +
2295 + percpu_priv->stats.tx_dropped++;
2296 + percpu_priv->stats.tx_fifo_errors++;
2297 + count_ern(percpu_priv, msg);
2298 +
2299 + /* If we intended this buffer to go into the pool
2300 + * when the FM was done, we need to put it in
2301 + * manually.
2302 + */
2303 + if (msg->ern.fd.bpid != 0xff) {
2304 + dpa_fd_release(net_dev, &fd);
2305 + return;
2306 + }
2307 +
2308 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2309 + dev_kfree_skb_any(skb);
2310 +}
2311 +
2312 +const struct dpa_fq_cbs_t private_fq_cbs = {
2313 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2314 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2315 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2316 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2317 + .egress_ern = { .cb = { .ern = priv_ern } }
2318 +};
2319 +EXPORT_SYMBOL(private_fq_cbs);
2320 +
2321 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2322 +{
2323 + struct dpa_percpu_priv_s *percpu_priv;
2324 + int i, j;
2325 +
2326 + for_each_possible_cpu(i) {
2327 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2328 +
2329 + for (j = 0; j < qman_portal_max; j++)
2330 + napi_enable(&percpu_priv->np[j].napi);
2331 + }
2332 +}
2333 +
2334 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2335 +{
2336 + struct dpa_percpu_priv_s *percpu_priv;
2337 + int i, j;
2338 +
2339 + for_each_possible_cpu(i) {
2340 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2341 +
2342 + for (j = 0; j < qman_portal_max; j++)
2343 + napi_disable(&percpu_priv->np[j].napi);
2344 + }
2345 +}
2346 +
2347 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2348 +{
2349 + int err;
2350 + struct dpa_priv_s *priv;
2351 +
2352 + priv = netdev_priv(net_dev);
2353 +
2354 + dpaa_eth_napi_enable(priv);
2355 +
2356 + err = dpa_start(net_dev);
2357 + if (err < 0)
2358 + dpaa_eth_napi_disable(priv);
2359 +
2360 + return err;
2361 +}
2362 +
2363 +
2364 +
2365 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2366 +{
2367 + int _errno;
2368 + struct dpa_priv_s *priv;
2369 +
2370 + _errno = dpa_stop(net_dev);
2371 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2372 + * ingress queues. This is to avoid a race between the current
2373 + * context and ksoftirqd which could leave NAPI disabled while
2374 + * in fact there's still Rx traffic to be processed.
2375 + */
2376 + usleep_range(5000, 10000);
2377 +
2378 + priv = netdev_priv(net_dev);
2379 + dpaa_eth_napi_disable(priv);
2380 +
2381 + return _errno;
2382 +}
2383 +
2384 +#ifdef CONFIG_NET_POLL_CONTROLLER
2385 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2386 +{
2387 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2388 + struct dpa_percpu_priv_s *percpu_priv =
2389 + raw_cpu_ptr(priv->percpu_priv);
2390 + struct qman_portal *p;
2391 + const struct qman_portal_config *pc;
2392 + struct dpa_napi_portal *np;
2393 +
2394 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2395 + pc = qman_p_get_portal_config(p);
2396 + np = &percpu_priv->np[pc->index];
2397 +
2398 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2399 + qman_p_poll_dqrr(np->p, np->napi.weight);
2400 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2401 +}
2402 +#endif
2403 +
2404 +static const struct net_device_ops dpa_private_ops = {
2405 + .ndo_open = dpa_eth_priv_start,
2406 + .ndo_start_xmit = dpa_tx,
2407 + .ndo_stop = dpa_eth_priv_stop,
2408 + .ndo_tx_timeout = dpa_timeout,
2409 + .ndo_get_stats64 = dpa_get_stats64,
2410 + .ndo_set_mac_address = dpa_set_mac_address,
2411 + .ndo_validate_addr = eth_validate_addr,
2412 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2413 + .ndo_select_queue = dpa_select_queue,
2414 +#endif
2415 + .ndo_change_mtu = dpa_change_mtu,
2416 + .ndo_set_rx_mode = dpa_set_rx_mode,
2417 + .ndo_init = dpa_ndo_init,
2418 + .ndo_set_features = dpa_set_features,
2419 + .ndo_fix_features = dpa_fix_features,
2420 + .ndo_do_ioctl = dpa_ioctl,
2421 +#ifdef CONFIG_NET_POLL_CONTROLLER
2422 + .ndo_poll_controller = dpaa_eth_poll_controller,
2423 +#endif
2424 +};
2425 +
2426 +static int dpa_private_napi_add(struct net_device *net_dev)
2427 +{
2428 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2429 + struct dpa_percpu_priv_s *percpu_priv;
2430 + int i, cpu;
2431 +
2432 + for_each_possible_cpu(cpu) {
2433 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2434 +
2435 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2436 + qman_portal_max * sizeof(struct dpa_napi_portal),
2437 + GFP_KERNEL);
2438 +
2439 + if (unlikely(percpu_priv->np == NULL)) {
2440 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2441 + return -ENOMEM;
2442 + }
2443 +
2444 + for (i = 0; i < qman_portal_max; i++)
2445 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2446 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2447 + }
2448 +
2449 + return 0;
2450 +}
2451 +
2452 +void dpa_private_napi_del(struct net_device *net_dev)
2453 +{
2454 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2455 + struct dpa_percpu_priv_s *percpu_priv;
2456 + int i, cpu;
2457 +
2458 + for_each_possible_cpu(cpu) {
2459 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2460 +
2461 + if (percpu_priv->np) {
2462 + for (i = 0; i < qman_portal_max; i++)
2463 + netif_napi_del(&percpu_priv->np[i].napi);
2464 +
2465 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2466 + }
2467 + }
2468 +}
2469 +EXPORT_SYMBOL(dpa_private_napi_del);
2470 +
2471 +static int dpa_private_netdev_init(struct net_device *net_dev)
2472 +{
2473 + int i;
2474 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2475 + struct dpa_percpu_priv_s *percpu_priv;
2476 + const uint8_t *mac_addr;
2477 +
2478 + /* Although we access another CPU's private data here
2479 + * we do it at initialization so it is safe
2480 + */
2481 + for_each_possible_cpu(i) {
2482 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2483 + percpu_priv->net_dev = net_dev;
2484 + }
2485 +
2486 + net_dev->netdev_ops = &dpa_private_ops;
2487 + mac_addr = priv->mac_dev->addr;
2488 +
2489 + net_dev->mem_start = priv->mac_dev->res->start;
2490 + net_dev->mem_end = priv->mac_dev->res->end;
2491 +
2492 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2493 + NETIF_F_LLTX);
2494 +
2495 + /* Advertise S/G and HIGHDMA support for private interfaces */
2496 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2497 + /* Recent kernels enable GSO automatically, if
2498 + * we declare NETIF_F_SG. For conformity, we'll
2499 + * still declare GSO explicitly.
2500 + */
2501 + net_dev->features |= NETIF_F_GSO;
2502 +
2503 + /* Advertise GRO support */
2504 + net_dev->features |= NETIF_F_GRO;
2505 +
2506 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2507 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2508 +
2509 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2510 +}
2511 +
2512 +static struct dpa_bp * __cold
2513 +dpa_priv_bp_probe(struct device *dev)
2514 +{
2515 + struct dpa_bp *dpa_bp;
2516 +
2517 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2518 + if (unlikely(dpa_bp == NULL)) {
2519 + dev_err(dev, "devm_kzalloc() failed\n");
2520 + return ERR_PTR(-ENOMEM);
2521 + }
2522 +
2523 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2524 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2525 +
2526 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2527 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2528 +
2529 + return dpa_bp;
2530 +}
2531 +
2532 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2533 + * We won't be sending congestion notifications to FMan; for now, we just use
2534 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2535 + * before they reach our ingress queues and eat up memory.
2536 + */
2537 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2538 +{
2539 + struct qm_mcc_initcgr initcgr;
2540 + u32 cs_th;
2541 + int err;
2542 +
2543 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2544 + if (err < 0) {
2545 + pr_err("Error %d allocating CGR ID\n", err);
2546 + goto out_error;
2547 + }
2548 +
2549 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2550 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2551 + initcgr.cgr.cscn_en = QM_CGR_EN;
2552 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2553 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2554 +
2555 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2556 + initcgr.cgr.cstd_en = QM_CGR_EN;
2557 +
2558 + /* This is actually a hack, because this CGR will be associated with
2559 + * our affine SWP. However, we'll place our ingress FQs in it.
2560 + */
2561 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2562 + &initcgr);
2563 + if (err < 0) {
2564 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2565 + priv->ingress_cgr.cgrid);
2566 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2567 + goto out_error;
2568 + }
2569 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2570 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2571 +
2572 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2573 + * range), but we have no common initialization path between the
2574 + * different variants of the DPAA Eth driver, so we do it here rather
2575 + * than modifying every other variant than "private Eth".
2576 + */
2577 + priv->use_ingress_cgr = true;
2578 +
2579 +out_error:
2580 + return err;
2581 +}
2582 +
2583 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2584 + size_t count)
2585 +{
2586 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2587 + int i;
2588 +
2589 + if (netif_msg_probe(priv))
2590 + dev_dbg(net_dev->dev.parent,
2591 + "Using private BM buffer pools\n");
2592 +
2593 + priv->bp_count = count;
2594 +
2595 + for (i = 0; i < count; i++) {
2596 + int err;
2597 + err = dpa_bp_alloc(&dpa_bp[i]);
2598 + if (err < 0) {
2599 + dpa_bp_free(priv);
2600 + priv->dpa_bp = NULL;
2601 + return err;
2602 + }
2603 +
2604 + priv->dpa_bp = &dpa_bp[i];
2605 + }
2606 +
2607 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2608 + return 0;
2609 +}
2610 +
2611 +static const struct of_device_id dpa_match[];
2612 +
2613 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2614 +static int dpa_new_loop_id(void)
2615 +{
2616 + static int if_id;
2617 +
2618 + return if_id++;
2619 +}
2620 +#endif
2621 +
2622 +static int
2623 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2624 +{
2625 + int err = 0, i, channel;
2626 + struct device *dev;
2627 + struct device_node *dpa_node;
2628 + struct dpa_bp *dpa_bp;
2629 + size_t count = 1;
2630 + struct net_device *net_dev = NULL;
2631 + struct dpa_priv_s *priv = NULL;
2632 + struct dpa_percpu_priv_s *percpu_priv;
2633 + struct fm_port_fqs port_fqs;
2634 + struct dpa_buffer_layout_s *buf_layout = NULL;
2635 + struct mac_device *mac_dev;
2636 +
2637 + dev = &_of_dev->dev;
2638 +
2639 + dpa_node = dev->of_node;
2640 +
2641 + if (!of_device_is_available(dpa_node))
2642 + return -ENODEV;
2643 +
2644 + /* Get the buffer pools assigned to this interface;
2645 + * run only once the default pool probing code
2646 + */
2647 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2648 + dpa_priv_bp_probe(dev);
2649 + if (IS_ERR(dpa_bp))
2650 + return PTR_ERR(dpa_bp);
2651 +
2652 + /* Allocate this early, so we can store relevant information in
2653 + * the private area (needed by 1588 code in dpa_mac_probe)
2654 + */
2655 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2656 + if (!net_dev) {
2657 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2658 + goto alloc_etherdev_mq_failed;
2659 + }
2660 +
2661 + /* Do this here, so we can be verbose early */
2662 + SET_NETDEV_DEV(net_dev, dev);
2663 + dev_set_drvdata(dev, net_dev);
2664 +
2665 + priv = netdev_priv(net_dev);
2666 + priv->net_dev = net_dev;
2667 + strcpy(priv->if_type, "private");
2668 +
2669 + priv->msg_enable = netif_msg_init(debug, -1);
2670 +
2671 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2672 + priv->loop_id = dpa_new_loop_id();
2673 + priv->loop_to = -1; /* disabled by default */
2674 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2675 +#endif
2676 +
2677 + mac_dev = dpa_mac_probe(_of_dev);
2678 + if (IS_ERR(mac_dev) || !mac_dev) {
2679 + err = PTR_ERR(mac_dev);
2680 + goto mac_probe_failed;
2681 + }
2682 +
2683 + /* We have physical ports, so we need to establish
2684 + * the buffer layout.
2685 + */
2686 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2687 + GFP_KERNEL);
2688 + if (!buf_layout) {
2689 + dev_err(dev, "devm_kzalloc() failed\n");
2690 + goto alloc_failed;
2691 + }
2692 + dpa_set_buffers_layout(mac_dev, buf_layout);
2693 +
2694 + /* For private ports, need to compute the size of the default
2695 + * buffer pool, based on FMan port buffer layout;also update
2696 + * the maximum buffer size for private ports if necessary
2697 + */
2698 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2699 +
2700 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2701 + /* We only want to use jumbo frame optimization if we actually have
2702 + * L2 MAX FRM set for jumbo frames as well.
2703 + */
2704 +#ifndef CONFIG_PPC
2705 + if (likely(!dpaa_errata_a010022))
2706 +#endif
2707 + if(fm_get_max_frm() < 9600)
2708 + dev_warn(dev,
2709 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2710 +#endif
2711 +
2712 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2713 +
2714 + memset(&port_fqs, 0, sizeof(port_fqs));
2715 +
2716 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2717 + if (!err)
2718 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2719 + &port_fqs, true, TX);
2720 +
2721 + if (err < 0)
2722 + goto fq_probe_failed;
2723 +
2724 + /* bp init */
2725 +
2726 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2727 +
2728 + if (err < 0)
2729 + goto bp_create_failed;
2730 +
2731 + priv->mac_dev = mac_dev;
2732 +
2733 + channel = dpa_get_channel();
2734 +
2735 + if (channel < 0) {
2736 + err = channel;
2737 + goto get_channel_failed;
2738 + }
2739 +
2740 + priv->channel = (uint16_t)channel;
2741 + dpaa_eth_add_channel(priv->channel);
2742 +
2743 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2744 +
2745 + /* Create a congestion group for this netdev, with
2746 + * dynamically-allocated CGR ID.
2747 + * Must be executed after probing the MAC, but before
2748 + * assigning the egress FQs to the CGRs.
2749 + */
2750 + err = dpaa_eth_cgr_init(priv);
2751 + if (err < 0) {
2752 + dev_err(dev, "Error initializing CGR\n");
2753 + goto tx_cgr_init_failed;
2754 + }
2755 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2756 + if (err < 0) {
2757 + dev_err(dev, "Error initializing ingress CGR\n");
2758 + goto rx_cgr_init_failed;
2759 + }
2760 +
2761 + /* Add the FQs to the interface, and make them active */
2762 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2763 + if (err < 0)
2764 + goto fq_alloc_failed;
2765 +
2766 + priv->buf_layout = buf_layout;
2767 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2768 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2769 +
2770 + /* All real interfaces need their ports initialized */
2771 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2772 + buf_layout, dev);
2773 +
2774 +#ifdef CONFIG_FMAN_PFC
2775 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2776 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2777 + mac_dev->port_dev[TX], i, i);
2778 + if (unlikely(err != 0)) {
2779 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2780 + goto pfc_mapping_failed;
2781 + }
2782 + }
2783 +#endif
2784 +
2785 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2786 +
2787 + if (priv->percpu_priv == NULL) {
2788 + dev_err(dev, "devm_alloc_percpu() failed\n");
2789 + err = -ENOMEM;
2790 + goto alloc_percpu_failed;
2791 + }
2792 + for_each_possible_cpu(i) {
2793 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2794 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2795 + }
2796 +
2797 + /* Initialize NAPI */
2798 + err = dpa_private_napi_add(net_dev);
2799 +
2800 + if (err < 0)
2801 + goto napi_add_failed;
2802 +
2803 + err = dpa_private_netdev_init(net_dev);
2804 +
2805 + if (err < 0)
2806 + goto netdev_init_failed;
2807 +
2808 + dpaa_eth_sysfs_init(&net_dev->dev);
2809 +
2810 +#ifdef CONFIG_PM
2811 + device_set_wakeup_capable(dev, true);
2812 +#endif
2813 +
2814 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2815 +
2816 + return 0;
2817 +
2818 +netdev_init_failed:
2819 +napi_add_failed:
2820 + dpa_private_napi_del(net_dev);
2821 +alloc_percpu_failed:
2822 +#ifdef CONFIG_FMAN_PFC
2823 +pfc_mapping_failed:
2824 +#endif
2825 + dpa_fq_free(dev, &priv->dpa_fq_list);
2826 +fq_alloc_failed:
2827 + qman_delete_cgr_safe(&priv->ingress_cgr);
2828 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2829 +rx_cgr_init_failed:
2830 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2831 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2832 +tx_cgr_init_failed:
2833 +get_channel_failed:
2834 + dpa_bp_free(priv);
2835 +bp_create_failed:
2836 +fq_probe_failed:
2837 +alloc_failed:
2838 +mac_probe_failed:
2839 + dev_set_drvdata(dev, NULL);
2840 + free_netdev(net_dev);
2841 +alloc_etherdev_mq_failed:
2842 + if (atomic_read(&dpa_bp->refs) == 0)
2843 + devm_kfree(dev, dpa_bp);
2844 +
2845 + return err;
2846 +}
2847 +
2848 +static const struct of_device_id dpa_match[] = {
2849 + {
2850 + .compatible = "fsl,dpa-ethernet"
2851 + },
2852 + {}
2853 +};
2854 +MODULE_DEVICE_TABLE(of, dpa_match);
2855 +
2856 +static struct platform_driver dpa_driver = {
2857 + .driver = {
2858 + .name = KBUILD_MODNAME,
2859 + .of_match_table = dpa_match,
2860 + .owner = THIS_MODULE,
2861 + .pm = DPAA_PM_OPS,
2862 + },
2863 + .probe = dpaa_eth_priv_probe,
2864 + .remove = dpa_remove
2865 +};
2866 +
2867 +#ifndef CONFIG_PPC
2868 +static bool __init __cold soc_has_errata_a010022(void)
2869 +{
2870 +#ifdef CONFIG_SOC_BUS
2871 + const struct soc_device_attribute soc_msi_matches[] = {
2872 + { .family = "QorIQ LS1043A",
2873 + .data = NULL },
2874 + { },
2875 + };
2876 +
2877 + if (soc_device_match(soc_msi_matches))
2878 + return true;
2879 +
2880 + return false;
2881 +#else
2882 + return true; /* cannot identify SoC */
2883 +#endif
2884 +}
2885 +#endif
2886 +
2887 +static int __init __cold dpa_load(void)
2888 +{
2889 + int _errno;
2890 +
2891 + pr_info(DPA_DESCRIPTION "\n");
2892 +
2893 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2894 + dpa_debugfs_module_init();
2895 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2896 +
2897 + /* initialise dpaa_eth mirror values */
2898 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2899 + dpa_max_frm = fm_get_max_frm();
2900 + dpa_num_cpus = num_possible_cpus();
2901 +
2902 +#ifndef CONFIG_PPC
2903 + /* Detect if the current SoC requires the 4K alignment workaround */
2904 + dpaa_errata_a010022 = soc_has_errata_a010022();
2905 +#endif
2906 +
2907 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2908 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2909 +#endif
2910 +
2911 + _errno = platform_driver_register(&dpa_driver);
2912 + if (unlikely(_errno < 0)) {
2913 + pr_err(KBUILD_MODNAME
2914 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2915 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2916 + }
2917 +
2918 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2919 + KBUILD_BASENAME".c", __func__);
2920 +
2921 + return _errno;
2922 +}
2923 +module_init(dpa_load);
2924 +
2925 +static void __exit __cold dpa_unload(void)
2926 +{
2927 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2928 + KBUILD_BASENAME".c", __func__);
2929 +
2930 + platform_driver_unregister(&dpa_driver);
2931 +
2932 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2933 + dpa_debugfs_module_exit();
2934 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2935 +
2936 + /* Only one channel is used and needs to be relased after all
2937 + * interfaces are removed
2938 + */
2939 + dpa_release_channel();
2940 +
2941 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2942 + KBUILD_BASENAME".c", __func__);
2943 +}
2944 +module_exit(dpa_unload);
2945 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2946 new file mode 100644
2947 index 00000000..b1703bc1
2948 --- /dev/null
2949 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2950 @@ -0,0 +1,698 @@
2951 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2952 + *
2953 + * Redistribution and use in source and binary forms, with or without
2954 + * modification, are permitted provided that the following conditions are met:
2955 + * * Redistributions of source code must retain the above copyright
2956 + * notice, this list of conditions and the following disclaimer.
2957 + * * Redistributions in binary form must reproduce the above copyright
2958 + * notice, this list of conditions and the following disclaimer in the
2959 + * documentation and/or other materials provided with the distribution.
2960 + * * Neither the name of Freescale Semiconductor nor the
2961 + * names of its contributors may be used to endorse or promote products
2962 + * derived from this software without specific prior written permission.
2963 + *
2964 + *
2965 + * ALTERNATIVELY, this software may be distributed under the terms of the
2966 + * GNU General Public License ("GPL") as published by the Free Software
2967 + * Foundation, either version 2 of that License or (at your option) any
2968 + * later version.
2969 + *
2970 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2971 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2972 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2973 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2974 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2975 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2976 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2977 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2978 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2979 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2980 + */
2981 +
2982 +#ifndef __DPA_H
2983 +#define __DPA_H
2984 +
2985 +#include <linux/netdevice.h>
2986 +#include <linux/fsl_qman.h> /* struct qman_fq */
2987 +
2988 +#include "fm_ext.h"
2989 +#include "dpaa_eth_trace.h"
2990 +
2991 +extern int dpa_rx_extra_headroom;
2992 +extern int dpa_max_frm;
2993 +extern int dpa_num_cpus;
2994 +
2995 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
2996 +#define dpa_get_max_frm() dpa_max_frm
2997 +
2998 +#define dpa_get_max_mtu() \
2999 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
3000 +
3001 +#define __hot
3002 +
3003 +/* Simple enum of FQ types - used for array indexing */
3004 +enum port_type {RX, TX};
3005 +
3006 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
3007 +struct dpa_buffer_layout_s {
3008 + uint16_t priv_data_size;
3009 + bool parse_results;
3010 + bool time_stamp;
3011 + bool hash_results;
3012 + uint8_t manip_extra_space;
3013 + uint16_t data_align;
3014 +};
3015 +
3016 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3017 +#define DPA_BUG_ON(cond) BUG_ON(cond)
3018 +#else
3019 +#define DPA_BUG_ON(cond)
3020 +#endif
3021 +
3022 +#define DPA_TX_PRIV_DATA_SIZE 16
3023 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3024 +#define DPA_TIME_STAMP_SIZE 8
3025 +#define DPA_HASH_RESULTS_SIZE 8
3026 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3027 + dpa_get_rx_extra_headroom())
3028 +
3029 +#define FM_FD_STAT_RX_ERRORS \
3030 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3031 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3032 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3033 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3034 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3035 +
3036 +#define FM_FD_STAT_TX_ERRORS \
3037 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3038 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3039 +
3040 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3041 +/* The raw buffer size must be cacheline aligned.
3042 + * Normally we use 2K buffers.
3043 + */
3044 +#define DPA_BP_RAW_SIZE 2048
3045 +#else
3046 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3047 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3048 + * space to account for further alignments.
3049 + */
3050 +#define DPA_MAX_FRM_SIZE 9600
3051 +#ifdef CONFIG_PPC
3052 +#define DPA_BP_RAW_SIZE \
3053 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3054 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3055 +#else /* CONFIG_PPC */
3056 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3057 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3058 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3059 +#endif /* CONFIG_PPC */
3060 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3061 +
3062 +/* This is what FMan is ever allowed to use.
3063 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3064 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3065 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3066 + * half-page-aligned buffers (can we?), so we reserve some more space
3067 + * for start-of-buffer alignment.
3068 + */
3069 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3070 + SMP_CACHE_BYTES)
3071 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3072 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3073 +
3074 +/* Maximum size of a buffer for which recycling is allowed.
3075 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3076 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3077 + * that skbs allocated by us will not fail to be recycled due to their size.
3078 + *
3079 + * For a requested size, the kernel allocator provides the next power of two
3080 + * sized block, which the stack will use as is, regardless of the actual size
3081 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3082 + * supported frame size), set the recycling upper limit to 16K.
3083 + */
3084 +#define DPA_RECYCLE_MAX_SIZE 16384
3085 +
3086 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3087 +/*TODO: temporary for fman pcd testing */
3088 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3089 +#endif
3090 +
3091 +#define DPAA_ETH_FQ_DELTA 0x10000
3092 +
3093 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3094 + (((device_addr) & 0x1fffff) >> 6)
3095 +
3096 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3097 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3098 +
3099 +/* Largest value that the FQD's OAL field can hold.
3100 + * This is DPAA-1.x specific.
3101 + * TODO: This rather belongs in fsl_qman.h
3102 + */
3103 +#define FSL_QMAN_MAX_OAL 127
3104 +
3105 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3106 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3107 +
3108 +/* Default alignment for start of data in an Rx FD */
3109 +#define DPA_FD_DATA_ALIGNMENT 16
3110 +
3111 +/* Values for the L3R field of the FM Parse Results
3112 + */
3113 +/* L3 Type field: First IP Present IPv4 */
3114 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3115 +/* L3 Type field: First IP Present IPv6 */
3116 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3117 +
3118 +/* Values for the L4R field of the FM Parse Results
3119 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3120 + */
3121 +/* L4 Type field: UDP */
3122 +#define FM_L4_PARSE_RESULT_UDP 0x40
3123 +/* L4 Type field: TCP */
3124 +#define FM_L4_PARSE_RESULT_TCP 0x20
3125 +/* FD status field indicating whether the FM Parser has attempted to validate
3126 + * the L4 csum of the frame.
3127 + * Note that having this bit set doesn't necessarily imply that the checksum
3128 + * is valid. One would have to check the parse results to find that out.
3129 + */
3130 +#define FM_FD_STAT_L4CV 0x00000004
3131 +
3132 +
3133 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3134 +
3135 +/* Check if the parsed frame was found to be a TCP segment.
3136 + *
3137 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3138 + */
3139 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3140 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3141 +
3142 +/* number of Tx queues to FMan */
3143 +#ifdef CONFIG_FMAN_PFC
3144 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3145 +#else
3146 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3147 +#endif
3148 +
3149 +#define DPAA_ETH_RX_QUEUES 128
3150 +
3151 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3152 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3153 + * was allocated by ourselves, respectively by the stack. In the former case,
3154 + * we could store the skb at negative offset; in the latter case, we can't,
3155 + * so we'll use 0 as offset.
3156 + *
3157 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3158 + */
3159 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3160 +{ \
3161 + skbh = (struct sk_buff **)addr; \
3162 + *(skbh + (off)) = skb; \
3163 +}
3164 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3165 +{ \
3166 + skbh = (struct sk_buff **)addr; \
3167 + skb = *(skbh + (off)); \
3168 +}
3169 +
3170 +#ifdef CONFIG_PM
3171 +/* Magic Packet wakeup */
3172 +#define DPAA_WOL_MAGIC 0x00000001
3173 +#endif
3174 +
3175 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3176 +struct pcd_range {
3177 + uint32_t base;
3178 + uint32_t count;
3179 +};
3180 +#endif
3181 +
3182 +/* More detailed FQ types - used for fine-grained WQ assignments */
3183 +enum dpa_fq_type {
3184 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3185 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3186 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3187 + FQ_TYPE_TX, /* "Real" Tx FQs */
3188 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3189 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3190 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3191 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3192 +};
3193 +
3194 +struct dpa_fq {
3195 + struct qman_fq fq_base;
3196 + struct list_head list;
3197 + struct net_device *net_dev;
3198 + bool init;
3199 + uint32_t fqid;
3200 + uint32_t flags;
3201 + uint16_t channel;
3202 + uint8_t wq;
3203 + enum dpa_fq_type fq_type;
3204 +};
3205 +
3206 +struct dpa_fq_cbs_t {
3207 + struct qman_fq rx_defq;
3208 + struct qman_fq tx_defq;
3209 + struct qman_fq rx_errq;
3210 + struct qman_fq tx_errq;
3211 + struct qman_fq egress_ern;
3212 +};
3213 +
3214 +struct fqid_cell {
3215 + uint32_t start;
3216 + uint32_t count;
3217 +};
3218 +
3219 +struct dpa_bp {
3220 + struct bman_pool *pool;
3221 + uint8_t bpid;
3222 + struct device *dev;
3223 + union {
3224 + /* The buffer pools used for the private ports are initialized
3225 + * with target_count buffers for each CPU; at runtime the
3226 + * number of buffers per CPU is constantly brought back to this
3227 + * level
3228 + */
3229 + int target_count;
3230 + /* The configured value for the number of buffers in the pool,
3231 + * used for shared port buffer pools
3232 + */
3233 + int config_count;
3234 + };
3235 + size_t size;
3236 + bool seed_pool;
3237 + /* physical address of the contiguous memory used by the pool to store
3238 + * the buffers
3239 + */
3240 + dma_addr_t paddr;
3241 + /* virtual address of the contiguous memory used by the pool to store
3242 + * the buffers
3243 + */
3244 + void __iomem *vaddr;
3245 + /* current number of buffers in the bpool alloted to this CPU */
3246 + int __percpu *percpu_count;
3247 + atomic_t refs;
3248 + /* some bpools need to be seeded before use by this cb */
3249 + int (*seed_cb)(struct dpa_bp *);
3250 + /* some bpools need to be emptied before freeing; this cb is used
3251 + * for freeing of individual buffers taken from the pool
3252 + */
3253 + void (*free_buf_cb)(void *addr);
3254 +};
3255 +
3256 +struct dpa_rx_errors {
3257 + u64 dme; /* DMA Error */
3258 + u64 fpe; /* Frame Physical Error */
3259 + u64 fse; /* Frame Size Error */
3260 + u64 phe; /* Header Error */
3261 + u64 cse; /* Checksum Validation Error */
3262 +};
3263 +
3264 +/* Counters for QMan ERN frames - one counter per rejection code */
3265 +struct dpa_ern_cnt {
3266 + u64 cg_tdrop; /* Congestion group taildrop */
3267 + u64 wred; /* WRED congestion */
3268 + u64 err_cond; /* Error condition */
3269 + u64 early_window; /* Order restoration, frame too early */
3270 + u64 late_window; /* Order restoration, frame too late */
3271 + u64 fq_tdrop; /* FQ taildrop */
3272 + u64 fq_retired; /* FQ is retired */
3273 + u64 orp_zero; /* ORP disabled */
3274 +};
3275 +
3276 +struct dpa_napi_portal {
3277 + struct napi_struct napi;
3278 + struct qman_portal *p;
3279 +};
3280 +
3281 +struct dpa_percpu_priv_s {
3282 + struct net_device *net_dev;
3283 + struct dpa_napi_portal *np;
3284 + u64 in_interrupt;
3285 + u64 tx_returned;
3286 + u64 tx_confirm;
3287 + /* fragmented (non-linear) skbuffs received from the stack */
3288 + u64 tx_frag_skbuffs;
3289 + /* number of S/G frames received */
3290 + u64 rx_sg;
3291 +
3292 + struct rtnl_link_stats64 stats;
3293 + struct dpa_rx_errors rx_errors;
3294 + struct dpa_ern_cnt ern_cnt;
3295 +};
3296 +
3297 +struct dpa_priv_s {
3298 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3299 + struct dpa_bp *dpa_bp;
3300 + /* Store here the needed Tx headroom for convenience and speed
3301 + * (even though it can be computed based on the fields of buf_layout)
3302 + */
3303 + uint16_t tx_headroom;
3304 + struct net_device *net_dev;
3305 + struct mac_device *mac_dev;
3306 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3307 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3308 +
3309 + size_t bp_count;
3310 +
3311 + uint16_t channel; /* "fsl,qman-channel-id" */
3312 + struct list_head dpa_fq_list;
3313 +
3314 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3315 + struct dentry *debugfs_loop_file;
3316 +#endif
3317 +
3318 + uint32_t msg_enable; /* net_device message level */
3319 +#ifdef CONFIG_FSL_DPAA_1588
3320 + struct dpa_ptp_tsu *tsu;
3321 +#endif
3322 +
3323 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3324 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3325 + int priv_pcd_num_ranges;
3326 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3327 +#endif
3328 +
3329 + struct {
3330 + /**
3331 + * All egress queues to a given net device belong to one
3332 + * (and the same) congestion group.
3333 + */
3334 + struct qman_cgr cgr;
3335 + /* If congested, when it began. Used for performance stats. */
3336 + u32 congestion_start_jiffies;
3337 + /* Number of jiffies the Tx port was congested. */
3338 + u32 congested_jiffies;
3339 + /**
3340 + * Counter for the number of times the CGR
3341 + * entered congestion state
3342 + */
3343 + u32 cgr_congested_count;
3344 + } cgr_data;
3345 + /* Use a per-port CGR for ingress traffic. */
3346 + bool use_ingress_cgr;
3347 + struct qman_cgr ingress_cgr;
3348 +
3349 +#ifdef CONFIG_FSL_DPAA_TS
3350 + bool ts_tx_en; /* Tx timestamping enabled */
3351 + bool ts_rx_en; /* Rx timestamping enabled */
3352 +#endif /* CONFIG_FSL_DPAA_TS */
3353 +
3354 + struct dpa_buffer_layout_s *buf_layout;
3355 + uint16_t rx_headroom;
3356 + char if_type[30];
3357 +
3358 + void *peer;
3359 +#ifdef CONFIG_PM
3360 + u32 wol;
3361 +#endif
3362 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3363 + int loop_id;
3364 + int loop_to;
3365 +#endif
3366 +#ifdef CONFIG_FSL_DPAA_CEETM
3367 + bool ceetm_en; /* CEETM QoS enabled */
3368 +#endif
3369 +};
3370 +
3371 +struct fm_port_fqs {
3372 + struct dpa_fq *tx_defq;
3373 + struct dpa_fq *tx_errq;
3374 + struct dpa_fq *rx_defq;
3375 + struct dpa_fq *rx_errq;
3376 +};
3377 +
3378 +
3379 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3380 +extern struct net_device *dpa_loop_netdevs[20];
3381 +#endif
3382 +
3383 +/* functions with different implementation for SG and non-SG: */
3384 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3385 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3386 +void __hot _dpa_rx(struct net_device *net_dev,
3387 + struct qman_portal *portal,
3388 + const struct dpa_priv_s *priv,
3389 + struct dpa_percpu_priv_s *percpu_priv,
3390 + const struct qm_fd *fd,
3391 + u32 fqid,
3392 + int *count_ptr);
3393 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3394 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3395 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3396 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3397 + const struct qm_fd *fd);
3398 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3399 + const struct qm_fd *fd,
3400 + struct sk_buff *skb,
3401 + int *use_gro);
3402 +#ifndef CONFIG_FSL_DPAA_TS
3403 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3404 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3405 + uint32_t min_size,
3406 + uint16_t min_offset,
3407 + unsigned char **new_buf_start);
3408 +#endif
3409 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3410 + struct sk_buff *skb, struct qm_fd *fd,
3411 + int *count_ptr, int *offset);
3412 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3413 + struct sk_buff *skb, struct qm_fd *fd);
3414 +int __cold __attribute__((nonnull))
3415 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3416 +
3417 +/* Turn on HW checksum computation for this outgoing frame.
3418 + * If the current protocol is not something we support in this regard
3419 + * (or if the stack has already computed the SW checksum), we do nothing.
3420 + *
3421 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3422 + * otherwise.
3423 + *
3424 + * Note that this function may modify the fd->cmd field and the skb data buffer
3425 + * (the Parse Results area).
3426 + */
3427 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3428 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3429 +
3430 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3431 + struct qman_portal *portal)
3432 +{
3433 + /* In case of threaded ISR for RT enable kernel,
3434 + * in_irq() does not return appropriate value, so use
3435 + * in_serving_softirq to distinguish softirq or irq context.
3436 + */
3437 + if (unlikely(in_irq() || !in_serving_softirq())) {
3438 + /* Disable QMan IRQ and invoke NAPI */
3439 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3440 + if (likely(!ret)) {
3441 + const struct qman_portal_config *pc =
3442 + qman_p_get_portal_config(portal);
3443 + struct dpa_napi_portal *np =
3444 + &percpu_priv->np[pc->index];
3445 +
3446 + np->p = portal;
3447 + napi_schedule(&np->napi);
3448 + percpu_priv->in_interrupt++;
3449 + return 1;
3450 + }
3451 + }
3452 + return 0;
3453 +}
3454 +
3455 +static inline ssize_t __const __must_check __attribute__((nonnull))
3456 +dpa_fd_length(const struct qm_fd *fd)
3457 +{
3458 + return fd->length20;
3459 +}
3460 +
3461 +static inline ssize_t __const __must_check __attribute__((nonnull))
3462 +dpa_fd_offset(const struct qm_fd *fd)
3463 +{
3464 + return fd->offset;
3465 +}
3466 +
3467 +/* Verifies if the skb length is below the interface MTU */
3468 +static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu)
3469 +{
3470 + if (unlikely(skb->len > mtu))
3471 + if ((skb->protocol != htons(ETH_P_8021Q))
3472 + || (skb->len > mtu + 4))
3473 + return -1;
3474 +
3475 + return 0;
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 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3650 new file mode 100644
3651 index 00000000..507e77c3
3652 --- /dev/null
3653 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3654 @@ -0,0 +1,205 @@
3655 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3656 + *
3657 + * Redistribution and use in source and binary forms, with or without
3658 + * modification, are permitted provided that the following conditions are met:
3659 + * * Redistributions of source code must retain the above copyright
3660 + * notice, this list of conditions and the following disclaimer.
3661 + * * Redistributions in binary form must reproduce the above copyright
3662 + * notice, this list of conditions and the following disclaimer in the
3663 + * documentation and/or other materials provided with the distribution.
3664 + * * Neither the name of Freescale Semiconductor nor the
3665 + * names of its contributors may be used to endorse or promote products
3666 + * derived from this software without specific prior written permission.
3667 + *
3668 + *
3669 + * ALTERNATIVELY, this software may be distributed under the terms of the
3670 + * GNU General Public License ("GPL") as published by the Free Software
3671 + * Foundation, either version 2 of that License or (at your option) any
3672 + * later version.
3673 + *
3674 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3675 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3676 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3677 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3678 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3679 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3680 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3681 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3682 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3683 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3684 + */
3685 +
3686 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3687 +#define pr_fmt(fmt) \
3688 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3689 + KBUILD_BASENAME".c", __LINE__, __func__
3690 +#else
3691 +#define pr_fmt(fmt) \
3692 + KBUILD_MODNAME ": " fmt
3693 +#endif
3694 +
3695 +#include <linux/init.h>
3696 +#include <linux/module.h>
3697 +#include <linux/io.h>
3698 +#include <linux/of_platform.h>
3699 +#include <linux/of_net.h>
3700 +#include <linux/etherdevice.h>
3701 +#include <linux/kthread.h>
3702 +#include <linux/percpu.h>
3703 +#include <linux/highmem.h>
3704 +#include <linux/sort.h>
3705 +#include <linux/fsl_qman.h>
3706 +#include "dpaa_eth.h"
3707 +#include "dpaa_eth_common.h"
3708 +#include "dpaa_eth_base.h"
3709 +
3710 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3711 +
3712 +MODULE_LICENSE("Dual BSD/GPL");
3713 +
3714 +uint8_t advanced_debug = -1;
3715 +module_param(advanced_debug, byte, S_IRUGO);
3716 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3717 +EXPORT_SYMBOL(advanced_debug);
3718 +
3719 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3720 +{
3721 + return ((struct dpa_bp *)dpa_bp0)->size -
3722 + ((struct dpa_bp *)dpa_bp1)->size;
3723 +}
3724 +
3725 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3726 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3727 +{
3728 + int i, lenp, na, ns, err;
3729 + struct device *dev;
3730 + struct device_node *dev_node;
3731 + const __be32 *bpool_cfg;
3732 + struct dpa_bp *dpa_bp;
3733 + u32 bpid;
3734 +
3735 + dev = &_of_dev->dev;
3736 +
3737 + *count = of_count_phandle_with_args(dev->of_node,
3738 + "fsl,bman-buffer-pools", NULL);
3739 + if (*count < 1) {
3740 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3741 + return ERR_PTR(-EINVAL);
3742 + }
3743 +
3744 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3745 + if (dpa_bp == NULL) {
3746 + dev_err(dev, "devm_kzalloc() failed\n");
3747 + return ERR_PTR(-ENOMEM);
3748 + }
3749 +
3750 + dev_node = of_find_node_by_path("/");
3751 + if (unlikely(dev_node == NULL)) {
3752 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3753 + return ERR_PTR(-EINVAL);
3754 + }
3755 +
3756 + na = of_n_addr_cells(dev_node);
3757 + ns = of_n_size_cells(dev_node);
3758 +
3759 + for (i = 0; i < *count; i++) {
3760 + of_node_put(dev_node);
3761 +
3762 + dev_node = of_parse_phandle(dev->of_node,
3763 + "fsl,bman-buffer-pools", i);
3764 + if (dev_node == NULL) {
3765 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3766 + return ERR_PTR(-EFAULT);
3767 + }
3768 +
3769 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3770 + dev_err(dev,
3771 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3772 + dev_node->full_name);
3773 + dpa_bp = ERR_PTR(-EINVAL);
3774 + goto _return_of_node_put;
3775 + }
3776 +
3777 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3778 + if (err) {
3779 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3780 + dpa_bp = ERR_PTR(-EINVAL);
3781 + goto _return_of_node_put;
3782 + }
3783 + dpa_bp[i].bpid = (uint8_t)bpid;
3784 +
3785 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3786 + &lenp);
3787 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3788 + const uint32_t *seed_pool;
3789 +
3790 + dpa_bp[i].config_count =
3791 + (int)of_read_number(bpool_cfg, ns);
3792 + dpa_bp[i].size =
3793 + (size_t)of_read_number(bpool_cfg + ns, ns);
3794 + dpa_bp[i].paddr =
3795 + of_read_number(bpool_cfg + 2 * ns, na);
3796 +
3797 + seed_pool = of_get_property(dev_node,
3798 + "fsl,bpool-ethernet-seeds", &lenp);
3799 + dpa_bp[i].seed_pool = !!seed_pool;
3800 +
3801 + } else {
3802 + dev_err(dev,
3803 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3804 + dev_node->full_name);
3805 + dpa_bp = ERR_PTR(-EINVAL);
3806 + goto _return_of_node_put;
3807 + }
3808 + }
3809 +
3810 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3811 +
3812 + return dpa_bp;
3813 +
3814 +_return_of_node_put:
3815 + if (dev_node)
3816 + of_node_put(dev_node);
3817 +
3818 + return dpa_bp;
3819 +}
3820 +EXPORT_SYMBOL(dpa_bp_probe);
3821 +
3822 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3823 + size_t count)
3824 +{
3825 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3826 + int i;
3827 +
3828 + priv->dpa_bp = dpa_bp;
3829 + priv->bp_count = count;
3830 +
3831 + for (i = 0; i < count; i++) {
3832 + int err;
3833 + err = dpa_bp_alloc(&dpa_bp[i]);
3834 + if (err < 0) {
3835 + dpa_bp_free(priv);
3836 + priv->dpa_bp = NULL;
3837 + return err;
3838 + }
3839 + }
3840 +
3841 + return 0;
3842 +}
3843 +EXPORT_SYMBOL(dpa_bp_create);
3844 +
3845 +static int __init __cold dpa_advanced_load(void)
3846 +{
3847 + pr_info(DPA_DESCRIPTION "\n");
3848 +
3849 + return 0;
3850 +}
3851 +module_init(dpa_advanced_load);
3852 +
3853 +static void __exit __cold dpa_advanced_unload(void)
3854 +{
3855 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3856 + KBUILD_BASENAME".c", __func__);
3857 +
3858 +}
3859 +module_exit(dpa_advanced_unload);
3860 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3861 new file mode 100644
3862 index 00000000..6ec68c3c
3863 --- /dev/null
3864 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3865 @@ -0,0 +1,49 @@
3866 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3867 + *
3868 + * Redistribution and use in source and binary forms, with or without
3869 + * modification, are permitted provided that the following conditions are met:
3870 + * * Redistributions of source code must retain the above copyright
3871 + * notice, this list of conditions and the following disclaimer.
3872 + * * Redistributions in binary form must reproduce the above copyright
3873 + * notice, this list of conditions and the following disclaimer in the
3874 + * documentation and/or other materials provided with the distribution.
3875 + * * Neither the name of Freescale Semiconductor nor the
3876 + * names of its contributors may be used to endorse or promote products
3877 + * derived from this software without specific prior written permission.
3878 + *
3879 + *
3880 + * ALTERNATIVELY, this software may be distributed under the terms of the
3881 + * GNU General Public License ("GPL") as published by the Free Software
3882 + * Foundation, either version 2 of that License or (at your option) any
3883 + * later version.
3884 + *
3885 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3886 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3887 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3888 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3889 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3890 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3891 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3892 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3893 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3894 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3895 + */
3896 +
3897 +#ifndef __DPAA_ETH_BASE_H
3898 +#define __DPAA_ETH_BASE_H
3899 +
3900 +#include <linux/etherdevice.h> /* struct net_device */
3901 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3902 +#include <linux/of_platform.h> /* struct platform_device */
3903 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3904 +
3905 +extern uint8_t advanced_debug;
3906 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3907 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3908 +
3909 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3910 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3911 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3912 + size_t count);
3913 +
3914 +#endif /* __DPAA_ETH_BASE_H */
3915 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3916 new file mode 100644
3917 index 00000000..cac613b7
3918 --- /dev/null
3919 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3920 @@ -0,0 +1,1992 @@
3921 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3922 + *
3923 + * Redistribution and use in source and binary forms, with or without
3924 + * modification, are permitted provided that the following conditions are met:
3925 + * * Redistributions of source code must retain the above copyright
3926 + * notice, this list of conditions and the following disclaimer.
3927 + * * Redistributions in binary form must reproduce the above copyright
3928 + * notice, this list of conditions and the following disclaimer in the
3929 + * documentation and/or other materials provided with the distribution.
3930 + * * Neither the name of Freescale Semiconductor nor the
3931 + * names of its contributors may be used to endorse or promote products
3932 + * derived from this software without specific prior written permission.
3933 + *
3934 + *
3935 + * ALTERNATIVELY, this software may be distributed under the terms of the
3936 + * GNU General Public License ("GPL") as published by the Free Software
3937 + * Foundation, either version 2 of that License or (at your option) any
3938 + * later version.
3939 + *
3940 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3941 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3942 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3943 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3944 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3945 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3946 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3947 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3948 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3949 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3950 + */
3951 +
3952 +#include <linux/init.h>
3953 +#include "dpaa_eth_ceetm.h"
3954 +
3955 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3956 +
3957 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3958 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3959 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3960 +};
3961 +
3962 +struct Qdisc_ops ceetm_qdisc_ops;
3963 +
3964 +/* Obtain the DCP and the SP ids from the FMan port */
3965 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3966 + unsigned int *sp_id)
3967 +{
3968 + uint32_t channel;
3969 + t_LnxWrpFmPortDev *port_dev;
3970 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3971 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3972 +
3973 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3974 + channel = port_dev->txCh;
3975 +
3976 + *sp_id = channel & CHANNEL_SP_MASK;
3977 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3978 +
3979 + if (channel < DCP0_MAX_CHANNEL) {
3980 + *dcp_id = qm_dc_portal_fman0;
3981 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3982 + } else {
3983 + *dcp_id = qm_dc_portal_fman1;
3984 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3985 + }
3986 +}
3987 +
3988 +/* Enqueue Rejection Notification callback */
3989 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
3990 + const struct qm_mr_entry *msg)
3991 +{
3992 + struct net_device *net_dev;
3993 + struct ceetm_class *cls;
3994 + struct ceetm_class_stats *cstats = NULL;
3995 + const struct dpa_priv_s *dpa_priv;
3996 + struct dpa_percpu_priv_s *dpa_percpu_priv;
3997 + struct sk_buff *skb;
3998 + struct qm_fd fd = msg->ern.fd;
3999 +
4000 + net_dev = ((struct ceetm_fq *)fq)->net_dev;
4001 + dpa_priv = netdev_priv(net_dev);
4002 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
4003 +
4004 + /* Increment DPA counters */
4005 + dpa_percpu_priv->stats.tx_dropped++;
4006 + dpa_percpu_priv->stats.tx_fifo_errors++;
4007 +
4008 + /* Increment CEETM counters */
4009 + cls = ((struct ceetm_fq *)fq)->ceetm_cls;
4010 + switch (cls->type) {
4011 + case CEETM_PRIO:
4012 + cstats = this_cpu_ptr(cls->prio.cstats);
4013 + break;
4014 + case CEETM_WBFS:
4015 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4016 + break;
4017 + }
4018 +
4019 + if (cstats)
4020 + cstats->ern_drop_count++;
4021 +
4022 + if (fd.bpid != 0xff) {
4023 + dpa_fd_release(net_dev, &fd);
4024 + return;
4025 + }
4026 +
4027 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
4028 + dev_kfree_skb_any(skb);
4029 +}
4030 +
4031 +/* Congestion State Change Notification callback */
4032 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
4033 +{
4034 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
4035 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
4036 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
4037 + struct ceetm_class_stats *cstats = NULL;
4038 +
4039 + switch (cls->type) {
4040 + case CEETM_PRIO:
4041 + cstats = this_cpu_ptr(cls->prio.cstats);
4042 + break;
4043 + case CEETM_WBFS:
4044 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4045 + break;
4046 + }
4047 +
4048 + if (congested) {
4049 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4050 + netif_tx_stop_all_queues(dpa_priv->net_dev);
4051 + dpa_priv->cgr_data.cgr_congested_count++;
4052 + if (cstats)
4053 + cstats->congested_count++;
4054 + } else {
4055 + dpa_priv->cgr_data.congested_jiffies +=
4056 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4057 + netif_tx_wake_all_queues(dpa_priv->net_dev);
4058 + }
4059 +}
4060 +
4061 +/* Allocate a ceetm fq */
4062 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4063 + struct ceetm_class *cls)
4064 +{
4065 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4066 + if (!*fq)
4067 + return -ENOMEM;
4068 +
4069 + (*fq)->net_dev = dev;
4070 + (*fq)->ceetm_cls = cls;
4071 + return 0;
4072 +}
4073 +
4074 +/* Configure a ceetm Class Congestion Group */
4075 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4076 + struct qm_ceetm_channel *channel, unsigned int id,
4077 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4078 +{
4079 + int err;
4080 + u32 cs_th;
4081 + u16 ccg_mask;
4082 + struct qm_ceetm_ccg_params ccg_params;
4083 +
4084 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4085 + if (err)
4086 + return err;
4087 +
4088 + /* Configure the count mode (frames/bytes), enable congestion state
4089 + * notifications, configure the congestion entry and exit thresholds,
4090 + * enable tail-drop, configure the tail-drop mode, and set the
4091 + * overhead accounting limit
4092 + */
4093 + ccg_mask = QM_CCGR_WE_MODE |
4094 + QM_CCGR_WE_CSCN_EN |
4095 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4096 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4097 + QM_CCGR_WE_OAL;
4098 +
4099 + ccg_params.mode = 0; /* count bytes */
4100 + ccg_params.cscn_en = 1; /* generate notifications */
4101 + ccg_params.td_en = 1; /* enable tail-drop */
4102 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4103 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4104 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4105 +
4106 + /* Set the congestion state thresholds according to the link speed */
4107 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4108 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
4109 + else
4110 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
4111 +
4112 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4113 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4114 + cs_th * CEETM_CCGR_RATIO, 1);
4115 +
4116 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4117 + if (err)
4118 + return err;
4119 +
4120 + return 0;
4121 +}
4122 +
4123 +/* Configure a ceetm Logical Frame Queue */
4124 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4125 + struct qm_ceetm_lfq **lfq)
4126 +{
4127 + int err;
4128 + u64 context_a;
4129 + u32 context_b;
4130 +
4131 + err = qman_ceetm_lfq_claim(lfq, cq);
4132 + if (err)
4133 + return err;
4134 +
4135 + /* Get the former contexts in order to preserve context B */
4136 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4137 + if (err)
4138 + return err;
4139 +
4140 + context_a = CEETM_CONTEXT_A;
4141 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4142 + if (err)
4143 + return err;
4144 +
4145 + (*lfq)->ern = ceetm_ern;
4146 +
4147 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4148 + if (err)
4149 + return err;
4150 +
4151 + return 0;
4152 +}
4153 +
4154 +/* Configure a prio ceetm class */
4155 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4156 + struct net_device *dev,
4157 + struct qm_ceetm_channel *channel,
4158 + unsigned int id)
4159 +{
4160 + int err;
4161 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4162 +
4163 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4164 + if (err)
4165 + return err;
4166 +
4167 + /* Claim and configure the CCG */
4168 + err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq,
4169 + dpa_priv);
4170 + if (err)
4171 + return err;
4172 +
4173 + /* Claim and configure the CQ */
4174 + err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg);
4175 + if (err)
4176 + return err;
4177 +
4178 + if (cls->shaped) {
4179 + err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1);
4180 + if (err)
4181 + return err;
4182 +
4183 + err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1);
4184 + if (err)
4185 + return err;
4186 + }
4187 +
4188 + /* Claim and configure a LFQ */
4189 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4190 + if (err)
4191 + return err;
4192 +
4193 + return 0;
4194 +}
4195 +
4196 +/* Configure a wbfs ceetm class */
4197 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4198 + struct net_device *dev,
4199 + struct qm_ceetm_channel *channel,
4200 + unsigned int id, int type)
4201 +{
4202 + int err;
4203 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4204 +
4205 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4206 + if (err)
4207 + return err;
4208 +
4209 + /* Claim and configure the CCG */
4210 + err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq,
4211 + dpa_priv);
4212 + if (err)
4213 + return err;
4214 +
4215 + /* Claim and configure the CQ */
4216 + if (type == WBFS_GRP_B)
4217 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id,
4218 + cls->wbfs.ccg);
4219 + else
4220 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id,
4221 + cls->wbfs.ccg);
4222 + if (err)
4223 + return err;
4224 +
4225 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4226 + * of the fraction
4227 + */
4228 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4229 + cls->wbfs.weight * 100);
4230 + if (err)
4231 + return err;
4232 +
4233 + /* Claim and configure a LFQ */
4234 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4235 + if (err)
4236 + return err;
4237 +
4238 + return 0;
4239 +}
4240 +
4241 +/* Find class in qdisc hash table using given handle */
4242 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4243 +{
4244 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4245 + struct Qdisc_class_common *clc;
4246 +
4247 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4248 + __func__, handle, sch->handle);
4249 +
4250 + clc = qdisc_class_find(&priv->clhash, handle);
4251 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4252 +}
4253 +
4254 +/* Insert a class in the qdisc's class hash */
4255 +static void ceetm_link_class(struct Qdisc *sch,
4256 + struct Qdisc_class_hash *clhash,
4257 + struct Qdisc_class_common *common)
4258 +{
4259 + sch_tree_lock(sch);
4260 + qdisc_class_hash_insert(clhash, common);
4261 + sch_tree_unlock(sch);
4262 + qdisc_class_hash_grow(sch, clhash);
4263 +}
4264 +
4265 +/* Destroy a ceetm class */
4266 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4267 +{
4268 + if (!cl)
4269 + return;
4270 +
4271 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4272 + __func__, cl->common.classid, sch->handle);
4273 +
4274 + switch (cl->type) {
4275 + case CEETM_ROOT:
4276 + if (cl->root.child) {
4277 + qdisc_destroy(cl->root.child);
4278 + cl->root.child = NULL;
4279 + }
4280 +
4281 + if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch))
4282 + pr_err(KBUILD_BASENAME
4283 + " : %s : error releasing the channel %d\n",
4284 + __func__, cl->root.ch->idx);
4285 +
4286 + break;
4287 +
4288 + case CEETM_PRIO:
4289 + if (cl->prio.child) {
4290 + qdisc_destroy(cl->prio.child);
4291 + cl->prio.child = NULL;
4292 + }
4293 +
4294 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4295 + pr_err(KBUILD_BASENAME
4296 + " : %s : error releasing the LFQ %d\n",
4297 + __func__, cl->prio.lfq->idx);
4298 +
4299 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4300 + pr_err(KBUILD_BASENAME
4301 + " : %s : error releasing the CQ %d\n",
4302 + __func__, cl->prio.cq->idx);
4303 +
4304 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4305 + pr_err(KBUILD_BASENAME
4306 + " : %s : error releasing the CCG %d\n",
4307 + __func__, cl->prio.ccg->idx);
4308 +
4309 + kfree(cl->prio.fq);
4310 +
4311 + if (cl->prio.cstats)
4312 + free_percpu(cl->prio.cstats);
4313 +
4314 + break;
4315 +
4316 + case CEETM_WBFS:
4317 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4318 + pr_err(KBUILD_BASENAME
4319 + " : %s : error releasing the LFQ %d\n",
4320 + __func__, cl->wbfs.lfq->idx);
4321 +
4322 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4323 + pr_err(KBUILD_BASENAME
4324 + " : %s : error releasing the CQ %d\n",
4325 + __func__, cl->wbfs.cq->idx);
4326 +
4327 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4328 + pr_err(KBUILD_BASENAME
4329 + " : %s : error releasing the CCG %d\n",
4330 + __func__, cl->wbfs.ccg->idx);
4331 +
4332 + kfree(cl->wbfs.fq);
4333 +
4334 + if (cl->wbfs.cstats)
4335 + free_percpu(cl->wbfs.cstats);
4336 + }
4337 +
4338 + tcf_destroy_chain(&cl->filter_list);
4339 + kfree(cl);
4340 +}
4341 +
4342 +/* Destroy a ceetm qdisc */
4343 +static void ceetm_destroy(struct Qdisc *sch)
4344 +{
4345 + unsigned int ntx, i;
4346 + struct hlist_node *next;
4347 + struct ceetm_class *cl;
4348 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4349 + struct net_device *dev = qdisc_dev(sch);
4350 +
4351 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4352 + __func__, sch->handle);
4353 +
4354 + /* All filters need to be removed before destroying the classes */
4355 + tcf_destroy_chain(&priv->filter_list);
4356 +
4357 + for (i = 0; i < priv->clhash.hashsize; i++) {
4358 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4359 + tcf_destroy_chain(&cl->filter_list);
4360 + }
4361 +
4362 + for (i = 0; i < priv->clhash.hashsize; i++) {
4363 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4364 + common.hnode)
4365 + ceetm_cls_destroy(sch, cl);
4366 + }
4367 +
4368 + qdisc_class_hash_destroy(&priv->clhash);
4369 +
4370 + switch (priv->type) {
4371 + case CEETM_ROOT:
4372 + dpa_disable_ceetm(dev);
4373 +
4374 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4375 + pr_err(KBUILD_BASENAME
4376 + " : %s : error releasing the LNI %d\n",
4377 + __func__, priv->root.lni->idx);
4378 +
4379 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4380 + pr_err(KBUILD_BASENAME
4381 + " : %s : error releasing the SP %d\n",
4382 + __func__, priv->root.sp->idx);
4383 +
4384 + if (priv->root.qstats)
4385 + free_percpu(priv->root.qstats);
4386 +
4387 + if (!priv->root.qdiscs)
4388 + break;
4389 +
4390 + /* Remove the pfifo qdiscs */
4391 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4392 + if (priv->root.qdiscs[ntx])
4393 + qdisc_destroy(priv->root.qdiscs[ntx]);
4394 +
4395 + kfree(priv->root.qdiscs);
4396 + break;
4397 +
4398 + case CEETM_PRIO:
4399 + if (priv->prio.parent)
4400 + priv->prio.parent->root.child = NULL;
4401 + break;
4402 +
4403 + case CEETM_WBFS:
4404 + if (priv->wbfs.parent)
4405 + priv->wbfs.parent->prio.child = NULL;
4406 + break;
4407 + }
4408 +}
4409 +
4410 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4411 +{
4412 + struct Qdisc *qdisc;
4413 + unsigned int ntx, i;
4414 + struct nlattr *nest;
4415 + struct tc_ceetm_qopt qopt;
4416 + struct ceetm_qdisc_stats *qstats;
4417 + struct net_device *dev = qdisc_dev(sch);
4418 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4419 +
4420 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4421 +
4422 + sch_tree_lock(sch);
4423 + memset(&qopt, 0, sizeof(qopt));
4424 + qopt.type = priv->type;
4425 + qopt.shaped = priv->shaped;
4426 +
4427 + switch (priv->type) {
4428 + case CEETM_ROOT:
4429 + /* Gather statistics from the underlying pfifo qdiscs */
4430 + sch->q.qlen = 0;
4431 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4432 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4433 +
4434 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4435 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4436 + sch->q.qlen += qdisc->q.qlen;
4437 + sch->bstats.bytes += qdisc->bstats.bytes;
4438 + sch->bstats.packets += qdisc->bstats.packets;
4439 + sch->qstats.qlen += qdisc->qstats.qlen;
4440 + sch->qstats.backlog += qdisc->qstats.backlog;
4441 + sch->qstats.drops += qdisc->qstats.drops;
4442 + sch->qstats.requeues += qdisc->qstats.requeues;
4443 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4444 + }
4445 +
4446 + for_each_online_cpu(i) {
4447 + qstats = per_cpu_ptr(priv->root.qstats, i);
4448 + sch->qstats.drops += qstats->drops;
4449 + }
4450 +
4451 + qopt.rate = priv->root.rate;
4452 + qopt.ceil = priv->root.ceil;
4453 + qopt.overhead = priv->root.overhead;
4454 + break;
4455 +
4456 + case CEETM_PRIO:
4457 + qopt.qcount = priv->prio.qcount;
4458 + break;
4459 +
4460 + case CEETM_WBFS:
4461 + qopt.qcount = priv->wbfs.qcount;
4462 + qopt.cr = priv->wbfs.cr;
4463 + qopt.er = priv->wbfs.er;
4464 + break;
4465 +
4466 + default:
4467 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4468 + sch_tree_unlock(sch);
4469 + return -EINVAL;
4470 + }
4471 +
4472 + nest = nla_nest_start(skb, TCA_OPTIONS);
4473 + if (!nest)
4474 + goto nla_put_failure;
4475 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4476 + goto nla_put_failure;
4477 + nla_nest_end(skb, nest);
4478 +
4479 + sch_tree_unlock(sch);
4480 + return skb->len;
4481 +
4482 +nla_put_failure:
4483 + sch_tree_unlock(sch);
4484 + nla_nest_cancel(skb, nest);
4485 + return -EMSGSIZE;
4486 +}
4487 +
4488 +/* Configure a root ceetm qdisc */
4489 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4490 + struct tc_ceetm_qopt *qopt)
4491 +{
4492 + struct netdev_queue *dev_queue;
4493 + struct Qdisc *qdisc;
4494 + enum qm_dc_portal dcp_id;
4495 + unsigned int i, sp_id, parent_id;
4496 + int err;
4497 + u64 bps;
4498 + struct qm_ceetm_sp *sp;
4499 + struct qm_ceetm_lni *lni;
4500 + struct net_device *dev = qdisc_dev(sch);
4501 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4502 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4503 +
4504 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4505 +
4506 + /* Validate inputs */
4507 + if (sch->parent != TC_H_ROOT) {
4508 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4509 + tcf_destroy_chain(&priv->filter_list);
4510 + qdisc_class_hash_destroy(&priv->clhash);
4511 + return -EINVAL;
4512 + }
4513 +
4514 + if (!mac_dev) {
4515 + pr_err("CEETM: the interface is lacking a mac\n");
4516 + err = -EINVAL;
4517 + goto err_init_root;
4518 + }
4519 +
4520 + /* pre-allocate underlying pfifo qdiscs */
4521 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4522 + sizeof(priv->root.qdiscs[0]),
4523 + GFP_KERNEL);
4524 + if (!priv->root.qdiscs) {
4525 + err = -ENOMEM;
4526 + goto err_init_root;
4527 + }
4528 +
4529 + for (i = 0; i < dev->num_tx_queues; i++) {
4530 + dev_queue = netdev_get_tx_queue(dev, i);
4531 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4532 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4533 +
4534 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4535 + parent_id);
4536 + if (!qdisc) {
4537 + err = -ENOMEM;
4538 + goto err_init_root;
4539 + }
4540 +
4541 + priv->root.qdiscs[i] = qdisc;
4542 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4543 + }
4544 +
4545 + sch->flags |= TCQ_F_MQROOT;
4546 +
4547 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4548 + if (!priv->root.qstats) {
4549 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4550 + __func__);
4551 + err = -ENOMEM;
4552 + goto err_init_root;
4553 + }
4554 +
4555 + priv->shaped = qopt->shaped;
4556 + priv->root.rate = qopt->rate;
4557 + priv->root.ceil = qopt->ceil;
4558 + priv->root.overhead = qopt->overhead;
4559 +
4560 + /* Claim the SP */
4561 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4562 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4563 + if (err) {
4564 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4565 + __func__);
4566 + goto err_init_root;
4567 + }
4568 +
4569 + priv->root.sp = sp;
4570 +
4571 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4572 + * are connected to the TX FMan ports
4573 + */
4574 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4575 + if (err) {
4576 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4577 + __func__);
4578 + goto err_init_root;
4579 + }
4580 +
4581 + priv->root.lni = lni;
4582 +
4583 + err = qman_ceetm_sp_set_lni(sp, lni);
4584 + if (err) {
4585 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4586 + __func__);
4587 + goto err_init_root;
4588 + }
4589 +
4590 + lni->sp = sp;
4591 +
4592 + /* Configure the LNI shaper */
4593 + if (priv->shaped) {
4594 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4595 + if (err) {
4596 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4597 + __func__);
4598 + goto err_init_root;
4599 + }
4600 +
4601 + bps = priv->root.rate << 3; /* Bps -> bps */
4602 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4603 + if (err) {
4604 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4605 + __func__);
4606 + goto err_init_root;
4607 + }
4608 +
4609 + bps = priv->root.ceil << 3; /* Bps -> bps */
4610 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4611 + if (err) {
4612 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4613 + __func__);
4614 + goto err_init_root;
4615 + }
4616 + }
4617 +
4618 + /* TODO default configuration */
4619 +
4620 + dpa_enable_ceetm(dev);
4621 + return 0;
4622 +
4623 +err_init_root:
4624 + ceetm_destroy(sch);
4625 + return err;
4626 +}
4627 +
4628 +/* Configure a prio ceetm qdisc */
4629 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4630 + struct tc_ceetm_qopt *qopt)
4631 +{
4632 + int err;
4633 + unsigned int i;
4634 + struct ceetm_class *parent_cl, *child_cl;
4635 + struct Qdisc *parent_qdisc;
4636 + struct net_device *dev = qdisc_dev(sch);
4637 +
4638 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4639 +
4640 + if (sch->parent == TC_H_ROOT) {
4641 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4642 + err = -EINVAL;
4643 + goto err_init_prio;
4644 + }
4645 +
4646 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4647 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4648 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4649 + err = -EINVAL;
4650 + goto err_init_prio;
4651 + }
4652 +
4653 + /* Obtain the parent root ceetm_class */
4654 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4655 +
4656 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4657 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4658 + err = -EINVAL;
4659 + goto err_init_prio;
4660 + }
4661 +
4662 + priv->prio.parent = parent_cl;
4663 + parent_cl->root.child = sch;
4664 +
4665 + priv->shaped = parent_cl->shaped;
4666 + priv->prio.qcount = qopt->qcount;
4667 +
4668 + /* Create and configure qcount child classes */
4669 + for (i = 0; i < priv->prio.qcount; i++) {
4670 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4671 + if (!child_cl) {
4672 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4673 + __func__);
4674 + err = -ENOMEM;
4675 + goto err_init_prio;
4676 + }
4677 +
4678 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4679 + if (!child_cl->prio.cstats) {
4680 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4681 + __func__);
4682 + err = -ENOMEM;
4683 + goto err_init_prio_cls;
4684 + }
4685 +
4686 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4687 + child_cl->refcnt = 1;
4688 + child_cl->parent = sch;
4689 + child_cl->type = CEETM_PRIO;
4690 + child_cl->shaped = priv->shaped;
4691 + child_cl->prio.child = NULL;
4692 +
4693 + /* All shaped CQs have CR and ER enabled by default */
4694 + child_cl->prio.cr = child_cl->shaped;
4695 + child_cl->prio.er = child_cl->shaped;
4696 + child_cl->prio.fq = NULL;
4697 + child_cl->prio.cq = NULL;
4698 +
4699 + /* Configure the corresponding hardware CQ */
4700 + err = ceetm_config_prio_cls(child_cl, dev,
4701 + parent_cl->root.ch, i);
4702 + if (err) {
4703 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4704 + __func__, child_cl->common.classid);
4705 + goto err_init_prio_cls;
4706 + }
4707 +
4708 + /* Add class handle in Qdisc */
4709 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4710 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4711 + __func__, child_cl->common.classid,
4712 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4713 + }
4714 +
4715 + return 0;
4716 +
4717 +err_init_prio_cls:
4718 + ceetm_cls_destroy(sch, child_cl);
4719 +err_init_prio:
4720 + ceetm_destroy(sch);
4721 + return err;
4722 +}
4723 +
4724 +/* Configure a wbfs ceetm qdisc */
4725 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4726 + struct tc_ceetm_qopt *qopt)
4727 +{
4728 + int err, group_b, small_group;
4729 + unsigned int i, id, prio_a, prio_b;
4730 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4731 + struct Qdisc *parent_qdisc;
4732 + struct ceetm_qdisc *parent_priv;
4733 + struct qm_ceetm_channel *channel;
4734 + struct net_device *dev = qdisc_dev(sch);
4735 +
4736 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4737 +
4738 + /* Validate inputs */
4739 + if (sch->parent == TC_H_ROOT) {
4740 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4741 + err = -EINVAL;
4742 + goto err_init_wbfs;
4743 + }
4744 +
4745 + /* Obtain the parent prio ceetm qdisc */
4746 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4747 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4748 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4749 + err = -EINVAL;
4750 + goto err_init_wbfs;
4751 + }
4752 +
4753 + /* Obtain the parent prio ceetm class */
4754 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4755 + parent_priv = qdisc_priv(parent_qdisc);
4756 +
4757 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4758 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4759 + err = -EINVAL;
4760 + goto err_init_wbfs;
4761 + }
4762 +
4763 + if (!qopt->qcount || !qopt->qweight[0]) {
4764 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4765 + err = -EINVAL;
4766 + goto err_init_wbfs;
4767 + }
4768 +
4769 + priv->shaped = parent_cl->shaped;
4770 +
4771 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4772 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4773 + err = -EINVAL;
4774 + goto err_init_wbfs;
4775 + }
4776 +
4777 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4778 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4779 + err = -EINVAL;
4780 + goto err_init_wbfs;
4781 + }
4782 +
4783 + /* Obtain the parent root ceetm class */
4784 + root_cl = parent_priv->prio.parent;
4785 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4786 + root_cl->root.wbfs_grp_large) {
4787 + pr_err("CEETM: no more wbfs classes are available\n");
4788 + err = -EINVAL;
4789 + goto err_init_wbfs;
4790 + }
4791 +
4792 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4793 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4794 + pr_err("CEETM: only %d wbfs classes are available\n",
4795 + CEETM_MIN_WBFS_QCOUNT);
4796 + err = -EINVAL;
4797 + goto err_init_wbfs;
4798 + }
4799 +
4800 + priv->wbfs.parent = parent_cl;
4801 + parent_cl->prio.child = sch;
4802 +
4803 + priv->wbfs.qcount = qopt->qcount;
4804 + priv->wbfs.cr = qopt->cr;
4805 + priv->wbfs.er = qopt->er;
4806 +
4807 + channel = root_cl->root.ch;
4808 +
4809 + /* Configure the hardware wbfs channel groups */
4810 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4811 + /* Configure the large group A */
4812 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4813 + small_group = false;
4814 + group_b = false;
4815 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4816 + prio_b = prio_a;
4817 +
4818 + } else if (root_cl->root.wbfs_grp_a) {
4819 + /* Configure the group B */
4820 + priv->wbfs.group_type = WBFS_GRP_B;
4821 +
4822 + err = qman_ceetm_channel_get_group(channel, &small_group,
4823 + &prio_a, &prio_b);
4824 + if (err) {
4825 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4826 + __func__);
4827 + goto err_init_wbfs;
4828 + }
4829 +
4830 + small_group = true;
4831 + group_b = true;
4832 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4833 + /* If group A isn't configured, configure it as group B */
4834 + prio_a = prio_a ? : prio_b;
4835 +
4836 + } else {
4837 + /* Configure the small group A */
4838 + priv->wbfs.group_type = WBFS_GRP_A;
4839 +
4840 + err = qman_ceetm_channel_get_group(channel, &small_group,
4841 + &prio_a, &prio_b);
4842 + if (err) {
4843 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4844 + __func__);
4845 + goto err_init_wbfs;
4846 + }
4847 +
4848 + small_group = true;
4849 + group_b = false;
4850 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4851 + /* If group B isn't configured, configure it as group A */
4852 + prio_b = prio_b ? : prio_a;
4853 + }
4854 +
4855 + err = qman_ceetm_channel_set_group(channel, small_group, prio_a,
4856 + prio_b);
4857 + if (err)
4858 + goto err_init_wbfs;
4859 +
4860 + if (priv->shaped) {
4861 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
4862 + group_b,
4863 + priv->wbfs.cr);
4864 + if (err) {
4865 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4866 + __func__);
4867 + goto err_init_wbfs;
4868 + }
4869 +
4870 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
4871 + group_b,
4872 + priv->wbfs.er);
4873 + if (err) {
4874 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4875 + __func__);
4876 + goto err_init_wbfs;
4877 + }
4878 + }
4879 +
4880 + /* Create qcount child classes */
4881 + for (i = 0; i < priv->wbfs.qcount; i++) {
4882 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4883 + if (!child_cl) {
4884 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4885 + __func__);
4886 + err = -ENOMEM;
4887 + goto err_init_wbfs;
4888 + }
4889 +
4890 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4891 + if (!child_cl->wbfs.cstats) {
4892 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4893 + __func__);
4894 + err = -ENOMEM;
4895 + goto err_init_wbfs_cls;
4896 + }
4897 +
4898 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4899 + child_cl->refcnt = 1;
4900 + child_cl->parent = sch;
4901 + child_cl->type = CEETM_WBFS;
4902 + child_cl->shaped = priv->shaped;
4903 + child_cl->wbfs.fq = NULL;
4904 + child_cl->wbfs.cq = NULL;
4905 + child_cl->wbfs.weight = qopt->qweight[i];
4906 +
4907 + if (priv->wbfs.group_type == WBFS_GRP_B)
4908 + id = WBFS_GRP_B_OFFSET + i;
4909 + else
4910 + id = WBFS_GRP_A_OFFSET + i;
4911 +
4912 + err = ceetm_config_wbfs_cls(child_cl, dev, channel, id,
4913 + priv->wbfs.group_type);
4914 + if (err) {
4915 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
4916 + __func__, child_cl->common.classid);
4917 + goto err_init_wbfs_cls;
4918 + }
4919 +
4920 + /* Add class handle in Qdisc */
4921 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4922 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
4923 + __func__, child_cl->common.classid,
4924 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
4925 + }
4926 +
4927 + /* Signal the root class that a group has been configured */
4928 + switch (priv->wbfs.group_type) {
4929 + case WBFS_GRP_LARGE:
4930 + root_cl->root.wbfs_grp_large = true;
4931 + break;
4932 + case WBFS_GRP_A:
4933 + root_cl->root.wbfs_grp_a = true;
4934 + break;
4935 + case WBFS_GRP_B:
4936 + root_cl->root.wbfs_grp_b = true;
4937 + break;
4938 + }
4939 +
4940 + return 0;
4941 +
4942 +err_init_wbfs_cls:
4943 + ceetm_cls_destroy(sch, child_cl);
4944 +err_init_wbfs:
4945 + ceetm_destroy(sch);
4946 + return err;
4947 +}
4948 +
4949 +/* Configure a generic ceetm qdisc */
4950 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
4951 +{
4952 + struct tc_ceetm_qopt *qopt;
4953 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
4954 + int ret;
4955 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4956 + struct net_device *dev = qdisc_dev(sch);
4957 +
4958 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4959 +
4960 + if (!netif_is_multiqueue(dev))
4961 + return -EOPNOTSUPP;
4962 +
4963 + if (!opt) {
4964 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4965 + return -EINVAL;
4966 + }
4967 +
4968 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
4969 + if (ret < 0) {
4970 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4971 + return ret;
4972 + }
4973 +
4974 + if (!tb[TCA_CEETM_QOPS]) {
4975 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4976 + return -EINVAL;
4977 + }
4978 +
4979 + if (TC_H_MIN(sch->handle)) {
4980 + pr_err("CEETM: a qdisc should not have a minor\n");
4981 + return -EINVAL;
4982 + }
4983 +
4984 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
4985 +
4986 + /* Initialize the class hash list. Each qdisc has its own class hash */
4987 + ret = qdisc_class_hash_init(&priv->clhash);
4988 + if (ret < 0) {
4989 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
4990 + __func__);
4991 + return ret;
4992 + }
4993 +
4994 + priv->type = qopt->type;
4995 +
4996 + switch (priv->type) {
4997 + case CEETM_ROOT:
4998 + ret = ceetm_init_root(sch, priv, qopt);
4999 + break;
5000 + case CEETM_PRIO:
5001 + ret = ceetm_init_prio(sch, priv, qopt);
5002 + break;
5003 + case CEETM_WBFS:
5004 + ret = ceetm_init_wbfs(sch, priv, qopt);
5005 + break;
5006 + default:
5007 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5008 + ceetm_destroy(sch);
5009 + ret = -EINVAL;
5010 + }
5011 +
5012 + return ret;
5013 +}
5014 +
5015 +/* Edit a root ceetm qdisc */
5016 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
5017 + struct net_device *dev,
5018 + struct tc_ceetm_qopt *qopt)
5019 +{
5020 + int err = 0;
5021 + u64 bps;
5022 +
5023 + if (priv->shaped != (bool)qopt->shaped) {
5024 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
5025 + priv->shaped ? "shaped" : "unshaped");
5026 + return -EINVAL;
5027 + }
5028 +
5029 + /* Nothing to modify for unshaped qdiscs */
5030 + if (!priv->shaped)
5031 + return 0;
5032 +
5033 + /* Configure the LNI shaper */
5034 + if (priv->root.overhead != qopt->overhead) {
5035 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
5036 + qopt->overhead);
5037 + if (err)
5038 + goto change_err;
5039 + priv->root.overhead = qopt->overhead;
5040 + }
5041 +
5042 + if (priv->root.rate != qopt->rate) {
5043 + bps = qopt->rate << 3; /* Bps -> bps */
5044 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5045 + dev->mtu);
5046 + if (err)
5047 + goto change_err;
5048 + priv->root.rate = qopt->rate;
5049 + }
5050 +
5051 + if (priv->root.ceil != qopt->ceil) {
5052 + bps = qopt->ceil << 3; /* Bps -> bps */
5053 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5054 + dev->mtu);
5055 + if (err)
5056 + goto change_err;
5057 + priv->root.ceil = qopt->ceil;
5058 + }
5059 +
5060 + return 0;
5061 +
5062 +change_err:
5063 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5064 + __func__, sch->handle);
5065 + return err;
5066 +}
5067 +
5068 +/* Edit a wbfs ceetm qdisc */
5069 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5070 + struct tc_ceetm_qopt *qopt)
5071 +{
5072 + int err;
5073 + bool group_b;
5074 + struct qm_ceetm_channel *channel;
5075 + struct ceetm_class *prio_class, *root_class;
5076 + struct ceetm_qdisc *prio_qdisc;
5077 +
5078 + if (qopt->qcount) {
5079 + pr_err("CEETM: the qcount can not be modified\n");
5080 + return -EINVAL;
5081 + }
5082 +
5083 + if (qopt->qweight[0]) {
5084 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5085 + return -EINVAL;
5086 + }
5087 +
5088 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5089 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5090 + return -EINVAL;
5091 + }
5092 +
5093 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5094 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5095 + return -EINVAL;
5096 + }
5097 +
5098 + /* Nothing to modify for unshaped qdiscs */
5099 + if (!priv->shaped)
5100 + return 0;
5101 +
5102 + prio_class = priv->wbfs.parent;
5103 + prio_qdisc = qdisc_priv(prio_class->parent);
5104 + root_class = prio_qdisc->prio.parent;
5105 + channel = root_class->root.ch;
5106 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5107 +
5108 + if (qopt->cr != priv->wbfs.cr) {
5109 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
5110 + group_b,
5111 + qopt->cr);
5112 + if (err)
5113 + goto change_err;
5114 + priv->wbfs.cr = qopt->cr;
5115 + }
5116 +
5117 + if (qopt->er != priv->wbfs.er) {
5118 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
5119 + group_b,
5120 + qopt->er);
5121 + if (err)
5122 + goto change_err;
5123 + priv->wbfs.er = qopt->er;
5124 + }
5125 +
5126 + return 0;
5127 +
5128 +change_err:
5129 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5130 + __func__, sch->handle);
5131 + return err;
5132 +}
5133 +
5134 +/* Edit a ceetm qdisc */
5135 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5136 +{
5137 + struct tc_ceetm_qopt *qopt;
5138 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5139 + int ret;
5140 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5141 + struct net_device *dev = qdisc_dev(sch);
5142 +
5143 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5144 +
5145 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5146 + if (ret < 0) {
5147 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5148 + return ret;
5149 + }
5150 +
5151 + if (!tb[TCA_CEETM_QOPS]) {
5152 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5153 + return -EINVAL;
5154 + }
5155 +
5156 + if (TC_H_MIN(sch->handle)) {
5157 + pr_err("CEETM: a qdisc should not have a minor\n");
5158 + return -EINVAL;
5159 + }
5160 +
5161 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5162 +
5163 + if (priv->type != qopt->type) {
5164 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5165 + sch->handle);
5166 + return -EINVAL;
5167 + }
5168 +
5169 + switch (priv->type) {
5170 + case CEETM_ROOT:
5171 + ret = ceetm_change_root(sch, priv, dev, qopt);
5172 + break;
5173 + case CEETM_PRIO:
5174 + pr_err("CEETM: prio qdiscs can not be modified\n");
5175 + ret = -EINVAL;
5176 + break;
5177 + case CEETM_WBFS:
5178 + ret = ceetm_change_wbfs(sch, priv, qopt);
5179 + break;
5180 + default:
5181 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5182 + ret = -EINVAL;
5183 + }
5184 +
5185 + return ret;
5186 +}
5187 +
5188 +/* Attach the underlying pfifo qdiscs */
5189 +static void ceetm_attach(struct Qdisc *sch)
5190 +{
5191 + struct net_device *dev = qdisc_dev(sch);
5192 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5193 + struct Qdisc *qdisc, *old_qdisc;
5194 + unsigned int i;
5195 +
5196 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5197 +
5198 + for (i = 0; i < dev->num_tx_queues; i++) {
5199 + qdisc = priv->root.qdiscs[i];
5200 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5201 + if (old_qdisc)
5202 + qdisc_destroy(old_qdisc);
5203 + }
5204 +}
5205 +
5206 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5207 +{
5208 + struct ceetm_class *cl;
5209 +
5210 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5211 + __func__, classid, sch->handle);
5212 + cl = ceetm_find(classid, sch);
5213 +
5214 + if (cl)
5215 + cl->refcnt++; /* Will decrement in put() */
5216 + return (unsigned long)cl;
5217 +}
5218 +
5219 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5220 +{
5221 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5222 +
5223 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5224 + __func__, cl->common.classid, sch->handle);
5225 + cl->refcnt--;
5226 +
5227 + if (cl->refcnt == 0)
5228 + ceetm_cls_destroy(sch, cl);
5229 +}
5230 +
5231 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5232 + struct tc_ceetm_copt *copt,
5233 + struct net_device *dev)
5234 +{
5235 + int err;
5236 + u64 bps;
5237 +
5238 + if ((bool)copt->shaped != cl->shaped) {
5239 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5240 + cl->shaped ? "shaped" : "unshaped");
5241 + return -EINVAL;
5242 + }
5243 +
5244 + if (cl->shaped && cl->root.rate != copt->rate) {
5245 + bps = copt->rate << 3; /* Bps -> bps */
5246 + err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps,
5247 + dev->mtu);
5248 + if (err)
5249 + goto change_cls_err;
5250 + cl->root.rate = copt->rate;
5251 + }
5252 +
5253 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5254 + bps = copt->ceil << 3; /* Bps -> bps */
5255 + err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps,
5256 + dev->mtu);
5257 + if (err)
5258 + goto change_cls_err;
5259 + cl->root.ceil = copt->ceil;
5260 + }
5261 +
5262 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5263 + err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl);
5264 + if (err)
5265 + goto change_cls_err;
5266 + cl->root.tbl = copt->tbl;
5267 + }
5268 +
5269 + return 0;
5270 +
5271 +change_cls_err:
5272 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5273 + __func__, cl->common.classid);
5274 + return err;
5275 +}
5276 +
5277 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5278 + struct tc_ceetm_copt *copt)
5279 +{
5280 + int err;
5281 +
5282 + if (!cl->shaped && (copt->cr || copt->er)) {
5283 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5284 + return -EINVAL;
5285 + }
5286 +
5287 + if (cl->prio.cr != (bool)copt->cr) {
5288 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5289 + cl->prio.cq->parent,
5290 + cl->prio.cq->idx,
5291 + copt->cr);
5292 + if (err)
5293 + goto change_cls_err;
5294 + cl->prio.cr = copt->cr;
5295 + }
5296 +
5297 + if (cl->prio.er != (bool)copt->er) {
5298 + err = qman_ceetm_channel_set_cq_er_eligibility(
5299 + cl->prio.cq->parent,
5300 + cl->prio.cq->idx,
5301 + copt->er);
5302 + if (err)
5303 + goto change_cls_err;
5304 + cl->prio.er = copt->er;
5305 + }
5306 +
5307 + return 0;
5308 +
5309 +change_cls_err:
5310 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5311 + __func__, cl->common.classid);
5312 + return err;
5313 +}
5314 +
5315 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5316 + struct tc_ceetm_copt *copt)
5317 +{
5318 + int err;
5319 +
5320 + if (copt->weight != cl->wbfs.weight) {
5321 + /* Configure the CQ weight: real number multiplied by 100 to
5322 + * get rid of the fraction
5323 + */
5324 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5325 + copt->weight * 100);
5326 +
5327 + if (err) {
5328 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5329 + __func__, cl->common.classid);
5330 + return err;
5331 + }
5332 +
5333 + cl->wbfs.weight = copt->weight;
5334 + }
5335 +
5336 + return 0;
5337 +}
5338 +
5339 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5340 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5341 + struct nlattr **tca, unsigned long *arg)
5342 +{
5343 + int err;
5344 + u64 bps;
5345 + struct ceetm_qdisc *priv;
5346 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5347 + struct nlattr *opt = tca[TCA_OPTIONS];
5348 + struct nlattr *tb[__TCA_CEETM_MAX];
5349 + struct tc_ceetm_copt *copt;
5350 + struct qm_ceetm_channel *channel;
5351 + struct net_device *dev = qdisc_dev(sch);
5352 +
5353 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5354 + __func__, classid, sch->handle);
5355 +
5356 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5357 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5358 + return -EINVAL;
5359 + }
5360 +
5361 + priv = qdisc_priv(sch);
5362 +
5363 + if (!opt) {
5364 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5365 + return -EINVAL;
5366 + }
5367 +
5368 + if (!cl && sch->handle != parentid) {
5369 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5370 + return -EINVAL;
5371 + }
5372 +
5373 + if (!cl && priv->type != CEETM_ROOT) {
5374 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5375 + return -EINVAL;
5376 + }
5377 +
5378 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5379 + if (err < 0) {
5380 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5381 + return -EINVAL;
5382 + }
5383 +
5384 + if (!tb[TCA_CEETM_COPT]) {
5385 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5386 + return -EINVAL;
5387 + }
5388 +
5389 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5390 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5391 + return -EINVAL;
5392 + }
5393 +
5394 + copt = nla_data(tb[TCA_CEETM_COPT]);
5395 +
5396 + /* Configure an existing ceetm class */
5397 + if (cl) {
5398 + if (copt->type != cl->type) {
5399 + pr_err("CEETM: class %X is not of the provided type\n",
5400 + cl->common.classid);
5401 + return -EINVAL;
5402 + }
5403 +
5404 + switch (copt->type) {
5405 + case CEETM_ROOT:
5406 + return ceetm_cls_change_root(cl, copt, dev);
5407 +
5408 + case CEETM_PRIO:
5409 + return ceetm_cls_change_prio(cl, copt);
5410 +
5411 + case CEETM_WBFS:
5412 + return ceetm_cls_change_wbfs(cl, copt);
5413 +
5414 + default:
5415 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5416 + __func__);
5417 + return -EINVAL;
5418 + }
5419 + }
5420 +
5421 + /* Add a new root ceetm class */
5422 + if (copt->type != CEETM_ROOT) {
5423 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5424 + return -EINVAL;
5425 + }
5426 +
5427 + if (copt->shaped && !priv->shaped) {
5428 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5429 + return -EINVAL;
5430 + }
5431 +
5432 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5433 + if (!cl)
5434 + return -ENOMEM;
5435 +
5436 + cl->type = copt->type;
5437 + cl->shaped = copt->shaped;
5438 + cl->root.rate = copt->rate;
5439 + cl->root.ceil = copt->ceil;
5440 + cl->root.tbl = copt->tbl;
5441 +
5442 + cl->common.classid = classid;
5443 + cl->refcnt = 1;
5444 + cl->parent = sch;
5445 + cl->root.child = NULL;
5446 + cl->root.wbfs_grp_a = false;
5447 + cl->root.wbfs_grp_b = false;
5448 + cl->root.wbfs_grp_large = false;
5449 +
5450 + /* Claim a CEETM channel */
5451 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5452 + if (err) {
5453 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5454 + __func__);
5455 + goto claim_err;
5456 + }
5457 +
5458 + cl->root.ch = channel;
5459 +
5460 + if (cl->shaped) {
5461 + /* Configure the channel shaper */
5462 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5463 + if (err)
5464 + goto channel_err;
5465 +
5466 + bps = cl->root.rate << 3; /* Bps -> bps */
5467 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5468 + dev->mtu);
5469 + if (err)
5470 + goto channel_err;
5471 +
5472 + bps = cl->root.ceil << 3; /* Bps -> bps */
5473 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5474 + dev->mtu);
5475 + if (err)
5476 + goto channel_err;
5477 +
5478 + } else {
5479 + /* Configure the uFQ algorithm */
5480 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5481 + if (err)
5482 + goto channel_err;
5483 + }
5484 +
5485 + /* Add class handle in Qdisc */
5486 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5487 +
5488 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5489 + __func__, classid, channel->idx);
5490 + *arg = (unsigned long)cl;
5491 + return 0;
5492 +
5493 +channel_err:
5494 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5495 + __func__, channel->idx);
5496 + if (qman_ceetm_channel_release(channel))
5497 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5498 + __func__, channel->idx);
5499 +claim_err:
5500 + kfree(cl);
5501 + return err;
5502 +}
5503 +
5504 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5505 +{
5506 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5507 + struct ceetm_class *cl;
5508 + unsigned int i;
5509 +
5510 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5511 +
5512 + if (arg->stop)
5513 + return;
5514 +
5515 + for (i = 0; i < priv->clhash.hashsize; i++) {
5516 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5517 + if (arg->count < arg->skip) {
5518 + arg->count++;
5519 + continue;
5520 + }
5521 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5522 + arg->stop = 1;
5523 + return;
5524 + }
5525 + arg->count++;
5526 + }
5527 + }
5528 +}
5529 +
5530 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5531 + struct sk_buff *skb, struct tcmsg *tcm)
5532 +{
5533 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5534 + struct nlattr *nest;
5535 + struct tc_ceetm_copt copt;
5536 +
5537 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5538 + __func__, cl->common.classid, sch->handle);
5539 +
5540 + sch_tree_lock(sch);
5541 +
5542 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5543 + tcm->tcm_handle = cl->common.classid;
5544 +
5545 + memset(&copt, 0, sizeof(copt));
5546 +
5547 + copt.shaped = cl->shaped;
5548 + copt.type = cl->type;
5549 +
5550 + switch (cl->type) {
5551 + case CEETM_ROOT:
5552 + if (cl->root.child)
5553 + tcm->tcm_info = cl->root.child->handle;
5554 +
5555 + copt.rate = cl->root.rate;
5556 + copt.ceil = cl->root.ceil;
5557 + copt.tbl = cl->root.tbl;
5558 + break;
5559 +
5560 + case CEETM_PRIO:
5561 + if (cl->prio.child)
5562 + tcm->tcm_info = cl->prio.child->handle;
5563 +
5564 + copt.cr = cl->prio.cr;
5565 + copt.er = cl->prio.er;
5566 + break;
5567 +
5568 + case CEETM_WBFS:
5569 + copt.weight = cl->wbfs.weight;
5570 + break;
5571 + }
5572 +
5573 + nest = nla_nest_start(skb, TCA_OPTIONS);
5574 + if (!nest)
5575 + goto nla_put_failure;
5576 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5577 + goto nla_put_failure;
5578 + nla_nest_end(skb, nest);
5579 + sch_tree_unlock(sch);
5580 + return skb->len;
5581 +
5582 +nla_put_failure:
5583 + sch_tree_unlock(sch);
5584 + nla_nest_cancel(skb, nest);
5585 + return -EMSGSIZE;
5586 +}
5587 +
5588 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5589 +{
5590 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5591 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5592 +
5593 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5594 + __func__, cl->common.classid, sch->handle);
5595 +
5596 + sch_tree_lock(sch);
5597 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5598 + cl->refcnt--;
5599 +
5600 + /* The refcnt should be at least 1 since we have incremented it in
5601 + * get(). Will decrement again in put() where we will call destroy()
5602 + * to actually free the memory if it reaches 0.
5603 + */
5604 + WARN_ON(cl->refcnt == 0);
5605 +
5606 + sch_tree_unlock(sch);
5607 + return 0;
5608 +}
5609 +
5610 +/* Get the class' child qdisc, if any */
5611 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5612 +{
5613 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5614 +
5615 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5616 + __func__, cl->common.classid, sch->handle);
5617 +
5618 + switch (cl->type) {
5619 + case CEETM_ROOT:
5620 + return cl->root.child;
5621 +
5622 + case CEETM_PRIO:
5623 + return cl->prio.child;
5624 + }
5625 +
5626 + return NULL;
5627 +}
5628 +
5629 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5630 + struct Qdisc *new, struct Qdisc **old)
5631 +{
5632 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5633 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5634 + return -EOPNOTSUPP;
5635 + }
5636 +
5637 + return 0;
5638 +}
5639 +
5640 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5641 + struct gnet_dump *d)
5642 +{
5643 + unsigned int i;
5644 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5645 + struct gnet_stats_basic_packed tmp_bstats;
5646 + struct ceetm_class_stats *cstats = NULL;
5647 + struct qm_ceetm_cq *cq = NULL;
5648 + struct tc_ceetm_xstats xstats;
5649 +
5650 + memset(&xstats, 0, sizeof(xstats));
5651 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5652 +
5653 + switch (cl->type) {
5654 + case CEETM_ROOT:
5655 + return 0;
5656 + case CEETM_PRIO:
5657 + cq = cl->prio.cq;
5658 + break;
5659 + case CEETM_WBFS:
5660 + cq = cl->wbfs.cq;
5661 + break;
5662 + }
5663 +
5664 + for_each_online_cpu(i) {
5665 + switch (cl->type) {
5666 + case CEETM_PRIO:
5667 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5668 + break;
5669 + case CEETM_WBFS:
5670 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5671 + break;
5672 + }
5673 +
5674 + if (cstats) {
5675 + xstats.ern_drop_count += cstats->ern_drop_count;
5676 + xstats.congested_count += cstats->congested_count;
5677 + tmp_bstats.bytes += cstats->bstats.bytes;
5678 + tmp_bstats.packets += cstats->bstats.packets;
5679 + }
5680 + }
5681 +
5682 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5683 + d, NULL, &tmp_bstats) < 0)
5684 + return -1;
5685 +
5686 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5687 + &xstats.frame_count,
5688 + &xstats.byte_count))
5689 + return -1;
5690 +
5691 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5692 +}
5693 +
5694 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5695 +{
5696 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5697 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5698 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5699 +
5700 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5701 + cl ? cl->common.classid : 0, sch->handle);
5702 + return fl;
5703 +}
5704 +
5705 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5706 + u32 classid)
5707 +{
5708 + struct ceetm_class *cl = ceetm_find(classid, sch);
5709 +
5710 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5711 + cl ? cl->common.classid : 0, sch->handle);
5712 + return (unsigned long)cl;
5713 +}
5714 +
5715 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5716 +{
5717 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5718 +
5719 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5720 + cl ? cl->common.classid : 0, sch->handle);
5721 +}
5722 +
5723 +const struct Qdisc_class_ops ceetm_cls_ops = {
5724 + .graft = ceetm_cls_graft,
5725 + .leaf = ceetm_cls_leaf,
5726 + .get = ceetm_cls_get,
5727 + .put = ceetm_cls_put,
5728 + .change = ceetm_cls_change,
5729 + .delete = ceetm_cls_delete,
5730 + .walk = ceetm_cls_walk,
5731 + .tcf_chain = ceetm_tcf_chain,
5732 + .bind_tcf = ceetm_tcf_bind,
5733 + .unbind_tcf = ceetm_tcf_unbind,
5734 + .dump = ceetm_cls_dump,
5735 + .dump_stats = ceetm_cls_dump_stats,
5736 +};
5737 +
5738 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5739 + .id = "ceetm",
5740 + .priv_size = sizeof(struct ceetm_qdisc),
5741 + .cl_ops = &ceetm_cls_ops,
5742 + .init = ceetm_init,
5743 + .destroy = ceetm_destroy,
5744 + .change = ceetm_change,
5745 + .dump = ceetm_dump,
5746 + .attach = ceetm_attach,
5747 + .owner = THIS_MODULE,
5748 +};
5749 +
5750 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5751 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5752 + struct Qdisc *sch, int *qerr,
5753 + bool *act_drop)
5754 +{
5755 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5756 + struct ceetm_class *cl = NULL, *wbfs_cl;
5757 + struct tcf_result res;
5758 + struct tcf_proto *tcf;
5759 + int result;
5760 +
5761 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5762 + tcf = priv->filter_list;
5763 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5764 +#ifdef CONFIG_NET_CLS_ACT
5765 + switch (result) {
5766 + case TC_ACT_QUEUED:
5767 + case TC_ACT_STOLEN:
5768 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5769 + case TC_ACT_SHOT:
5770 + /* No valid class found due to action */
5771 + *act_drop = true;
5772 + return NULL;
5773 + }
5774 +#endif
5775 + cl = (void *)res.class;
5776 + if (!cl) {
5777 + if (res.classid == sch->handle) {
5778 + /* The filter leads to the qdisc */
5779 + /* TODO default qdisc */
5780 + return NULL;
5781 + }
5782 +
5783 + cl = ceetm_find(res.classid, sch);
5784 + if (!cl)
5785 + /* The filter leads to an invalid class */
5786 + break;
5787 + }
5788 +
5789 + /* The class might have its own filters attached */
5790 + tcf = cl->filter_list;
5791 + }
5792 +
5793 + if (!cl) {
5794 + /* No valid class found */
5795 + /* TODO default qdisc */
5796 + return NULL;
5797 + }
5798 +
5799 + switch (cl->type) {
5800 + case CEETM_ROOT:
5801 + if (cl->root.child) {
5802 + /* Run the prio qdisc classifiers */
5803 + return ceetm_classify(skb, cl->root.child, qerr,
5804 + act_drop);
5805 + } else {
5806 + /* The root class does not have a child prio qdisc */
5807 + /* TODO default qdisc */
5808 + return NULL;
5809 + }
5810 + case CEETM_PRIO:
5811 + if (cl->prio.child) {
5812 + /* If filters lead to a wbfs class, return it.
5813 + * Otherwise, return the prio class
5814 + */
5815 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5816 + act_drop);
5817 + /* A NULL result might indicate either an erroneous
5818 + * filter, or no filters at all. We will assume the
5819 + * latter
5820 + */
5821 + return wbfs_cl ? : cl;
5822 + }
5823 + }
5824 +
5825 + /* For wbfs and childless prio classes, return the class directly */
5826 + return cl;
5827 +}
5828 +
5829 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5830 +{
5831 + int ret;
5832 + bool act_drop = false;
5833 + struct Qdisc *sch = net_dev->qdisc;
5834 + struct ceetm_class *cl;
5835 + struct dpa_priv_s *priv_dpa;
5836 + struct qman_fq *egress_fq, *conf_fq;
5837 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5838 + struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats);
5839 + struct ceetm_class_stats *cstats;
5840 + const int queue_mapping = dpa_get_queue_mapping(skb);
5841 + spinlock_t *root_lock = qdisc_lock(sch);
5842 +
5843 + spin_lock(root_lock);
5844 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5845 + spin_unlock(root_lock);
5846 +
5847 +#ifdef CONFIG_NET_CLS_ACT
5848 + if (act_drop) {
5849 + if (ret & __NET_XMIT_BYPASS)
5850 + qstats->drops++;
5851 + goto drop;
5852 + }
5853 +#endif
5854 + /* TODO default class */
5855 + if (unlikely(!cl)) {
5856 + qstats->drops++;
5857 + goto drop;
5858 + }
5859 +
5860 + priv_dpa = netdev_priv(net_dev);
5861 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5862 +
5863 + /* Choose the proper tx fq and update the basic stats (bytes and
5864 + * packets sent by the class)
5865 + */
5866 + switch (cl->type) {
5867 + case CEETM_PRIO:
5868 + egress_fq = &cl->prio.fq->fq;
5869 + cstats = this_cpu_ptr(cl->prio.cstats);
5870 + break;
5871 + case CEETM_WBFS:
5872 + egress_fq = &cl->wbfs.fq->fq;
5873 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5874 + break;
5875 + default:
5876 + qstats->drops++;
5877 + goto drop;
5878 + }
5879 +
5880 + bstats_update(&cstats->bstats, skb);
5881 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
5882 +
5883 +drop:
5884 + dev_kfree_skb_any(skb);
5885 + return NET_XMIT_SUCCESS;
5886 +}
5887 +
5888 +static int __init ceetm_register(void)
5889 +{
5890 + int _errno = 0;
5891 +
5892 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
5893 +
5894 + _errno = register_qdisc(&ceetm_qdisc_ops);
5895 + if (unlikely(_errno))
5896 + pr_err(KBUILD_MODNAME
5897 + ": %s:%hu:%s(): register_qdisc() = %d\n",
5898 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
5899 +
5900 + return _errno;
5901 +}
5902 +
5903 +static void __exit ceetm_unregister(void)
5904 +{
5905 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
5906 + KBUILD_BASENAME ".c", __func__);
5907 +
5908 + unregister_qdisc(&ceetm_qdisc_ops);
5909 +}
5910 +
5911 +module_init(ceetm_register);
5912 +module_exit(ceetm_unregister);
5913 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5914 new file mode 100644
5915 index 00000000..63cc3475
5916 --- /dev/null
5917 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5918 @@ -0,0 +1,237 @@
5919 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5920 + *
5921 + * Redistribution and use in source and binary forms, with or without
5922 + * modification, are permitted provided that the following conditions are met:
5923 + * * Redistributions of source code must retain the above copyright
5924 + * notice, this list of conditions and the following disclaimer.
5925 + * * Redistributions in binary form must reproduce the above copyright
5926 + * notice, this list of conditions and the following disclaimer in the
5927 + * documentation and/or other materials provided with the distribution.
5928 + * * Neither the name of Freescale Semiconductor nor the
5929 + * names of its contributors may be used to endorse or promote products
5930 + * derived from this software without specific prior written permission.
5931 + *
5932 + *
5933 + * ALTERNATIVELY, this software may be distributed under the terms of the
5934 + * GNU General Public License ("GPL") as published by the Free Software
5935 + * Foundation, either version 2 of that License or (at your option) any
5936 + * later version.
5937 + *
5938 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5939 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5940 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5941 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5942 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5943 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5944 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5945 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5946 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5947 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5948 + */
5949 +
5950 +#ifndef __DPAA_ETH_CEETM_H
5951 +#define __DPAA_ETH_CEETM_H
5952 +
5953 +#include <net/pkt_sched.h>
5954 +#include <net/pkt_cls.h>
5955 +#include <net/netlink.h>
5956 +#include <lnxwrp_fm.h>
5957 +
5958 +#include "mac.h"
5959 +#include "dpaa_eth_common.h"
5960 +
5961 +/* Mask to determine the sub-portal id from a channel number */
5962 +#define CHANNEL_SP_MASK 0x1f
5963 +/* The number of the last channel that services DCP0, connected to FMan 0.
5964 + * Value validated for B4 and T series platforms.
5965 + */
5966 +#define DCP0_MAX_CHANNEL 0x80f
5967 +/* A2V=1 - field A2 is valid
5968 + * A0V=1 - field A0 is valid - enables frame confirmation
5969 + * OVOM=1 - override operation mode bits with values from A2
5970 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
5971 + * NL=0 - the BMI releases all the internal buffers
5972 + */
5973 +#define CEETM_CONTEXT_A 0x1a00000080000000
5974 +/* The ratio between the superior and inferior congestion state thresholds. The
5975 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
5976 + * scheduling).
5977 + */
5978 +#define CEETM_CCGR_RATIO 0.875
5979 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
5980 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
5981 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
5982 + * hex).
5983 + */
5984 +#define PFIFO_MIN_OFFSET 0x21
5985 +
5986 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
5987 +#define CEETM_MAX_PRIO_QCOUNT 8
5988 +#define CEETM_MAX_WBFS_QCOUNT 8
5989 +#define CEETM_MIN_WBFS_QCOUNT 4
5990 +
5991 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
5992 + * and/or 12-15 for group B).
5993 + */
5994 +#define WBFS_GRP_A_OFFSET 8
5995 +#define WBFS_GRP_B_OFFSET 12
5996 +
5997 +#define WBFS_GRP_A 1
5998 +#define WBFS_GRP_B 2
5999 +#define WBFS_GRP_LARGE 3
6000 +
6001 +enum {
6002 + TCA_CEETM_UNSPEC,
6003 + TCA_CEETM_COPT,
6004 + TCA_CEETM_QOPS,
6005 + __TCA_CEETM_MAX,
6006 +};
6007 +
6008 +/* CEETM configuration types */
6009 +enum {
6010 + CEETM_ROOT = 1,
6011 + CEETM_PRIO,
6012 + CEETM_WBFS
6013 +};
6014 +
6015 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
6016 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
6017 +
6018 +struct ceetm_class;
6019 +struct ceetm_qdisc_stats;
6020 +struct ceetm_class_stats;
6021 +
6022 +struct ceetm_fq {
6023 + struct qman_fq fq;
6024 + struct net_device *net_dev;
6025 + struct ceetm_class *ceetm_cls;
6026 +};
6027 +
6028 +struct root_q {
6029 + struct Qdisc **qdiscs;
6030 + __u16 overhead;
6031 + __u32 rate;
6032 + __u32 ceil;
6033 + struct qm_ceetm_sp *sp;
6034 + struct qm_ceetm_lni *lni;
6035 + struct ceetm_qdisc_stats __percpu *qstats;
6036 +};
6037 +
6038 +struct prio_q {
6039 + __u16 qcount;
6040 + struct ceetm_class *parent;
6041 +};
6042 +
6043 +struct wbfs_q {
6044 + __u16 qcount;
6045 + int group_type;
6046 + struct ceetm_class *parent;
6047 + __u16 cr;
6048 + __u16 er;
6049 +};
6050 +
6051 +struct ceetm_qdisc {
6052 + int type; /* LNI/CHNL/WBFS */
6053 + bool shaped;
6054 + union {
6055 + struct root_q root;
6056 + struct prio_q prio;
6057 + struct wbfs_q wbfs;
6058 + };
6059 + struct Qdisc_class_hash clhash;
6060 + struct tcf_proto *filter_list; /* qdisc attached filters */
6061 +};
6062 +
6063 +/* CEETM Qdisc configuration parameters */
6064 +struct tc_ceetm_qopt {
6065 + __u32 type;
6066 + __u16 shaped;
6067 + __u16 qcount;
6068 + __u16 overhead;
6069 + __u32 rate;
6070 + __u32 ceil;
6071 + __u16 cr;
6072 + __u16 er;
6073 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6074 +};
6075 +
6076 +struct root_c {
6077 + unsigned int rate;
6078 + unsigned int ceil;
6079 + unsigned int tbl;
6080 + bool wbfs_grp_a;
6081 + bool wbfs_grp_b;
6082 + bool wbfs_grp_large;
6083 + struct Qdisc *child;
6084 + struct qm_ceetm_channel *ch;
6085 +};
6086 +
6087 +struct prio_c {
6088 + bool cr;
6089 + bool er;
6090 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6091 + struct qm_ceetm_lfq *lfq;
6092 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6093 + struct qm_ceetm_ccg *ccg;
6094 + /* only one wbfs can be linked to one priority CQ */
6095 + struct Qdisc *child;
6096 + struct ceetm_class_stats __percpu *cstats;
6097 +};
6098 +
6099 +struct wbfs_c {
6100 + __u8 weight; /* The weight of the class between 1 and 248 */
6101 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6102 + struct qm_ceetm_lfq *lfq;
6103 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6104 + struct qm_ceetm_ccg *ccg;
6105 + struct ceetm_class_stats __percpu *cstats;
6106 +};
6107 +
6108 +struct ceetm_class {
6109 + struct Qdisc_class_common common;
6110 + int refcnt; /* usage count of this class */
6111 + struct tcf_proto *filter_list; /* class attached filters */
6112 + struct Qdisc *parent;
6113 + bool shaped;
6114 + int type; /* ROOT/PRIO/WBFS */
6115 + union {
6116 + struct root_c root;
6117 + struct prio_c prio;
6118 + struct wbfs_c wbfs;
6119 + };
6120 +};
6121 +
6122 +/* CEETM Class configuration parameters */
6123 +struct tc_ceetm_copt {
6124 + __u32 type;
6125 + __u16 shaped;
6126 + __u32 rate;
6127 + __u32 ceil;
6128 + __u16 tbl;
6129 + __u16 cr;
6130 + __u16 er;
6131 + __u8 weight;
6132 +};
6133 +
6134 +/* CEETM stats */
6135 +struct ceetm_qdisc_stats {
6136 + __u32 drops;
6137 +};
6138 +
6139 +struct ceetm_class_stats {
6140 + /* Software counters */
6141 + struct gnet_stats_basic_packed bstats;
6142 + __u32 ern_drop_count;
6143 + __u32 congested_count;
6144 +};
6145 +
6146 +struct tc_ceetm_xstats {
6147 + __u32 ern_drop_count;
6148 + __u32 congested_count;
6149 + /* Hardware counters */
6150 + __u64 frame_count;
6151 + __u64 byte_count;
6152 +};
6153 +
6154 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6155 +#endif
6156 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6157 new file mode 100644
6158 index 00000000..fbe61da2
6159 --- /dev/null
6160 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6161 @@ -0,0 +1,1811 @@
6162 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6163 + *
6164 + * Redistribution and use in source and binary forms, with or without
6165 + * modification, are permitted provided that the following conditions are met:
6166 + * * Redistributions of source code must retain the above copyright
6167 + * notice, this list of conditions and the following disclaimer.
6168 + * * Redistributions in binary form must reproduce the above copyright
6169 + * notice, this list of conditions and the following disclaimer in the
6170 + * documentation and/or other materials provided with the distribution.
6171 + * * Neither the name of Freescale Semiconductor nor the
6172 + * names of its contributors may be used to endorse or promote products
6173 + * derived from this software without specific prior written permission.
6174 + *
6175 + *
6176 + * ALTERNATIVELY, this software may be distributed under the terms of the
6177 + * GNU General Public License ("GPL") as published by the Free Software
6178 + * Foundation, either version 2 of that License or (at your option) any
6179 + * later version.
6180 + *
6181 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6182 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6183 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6184 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6185 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6186 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6187 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6188 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6189 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6190 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6191 + */
6192 +
6193 +#include <linux/init.h>
6194 +#include <linux/module.h>
6195 +#include <linux/of_platform.h>
6196 +#include <linux/of_net.h>
6197 +#include <linux/etherdevice.h>
6198 +#include <linux/kthread.h>
6199 +#include <linux/percpu.h>
6200 +#include <linux/highmem.h>
6201 +#include <linux/sort.h>
6202 +#include <linux/fsl_qman.h>
6203 +#include <linux/ip.h>
6204 +#include <linux/ipv6.h>
6205 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6206 +#include "dpaa_eth.h"
6207 +#include "dpaa_eth_common.h"
6208 +#ifdef CONFIG_FSL_DPAA_1588
6209 +#include "dpaa_1588.h"
6210 +#endif
6211 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6212 +#include "dpaa_debugfs.h"
6213 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6214 +#include "mac.h"
6215 +
6216 +/* Size in bytes of the FQ taildrop threshold */
6217 +#define DPA_FQ_TD 0x200000
6218 +
6219 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6220 +struct ptp_priv_s ptp_priv;
6221 +#endif
6222 +
6223 +static struct dpa_bp *dpa_bp_array[64];
6224 +
6225 +int dpa_max_frm;
6226 +EXPORT_SYMBOL(dpa_max_frm);
6227 +
6228 +int dpa_rx_extra_headroom;
6229 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6230 +
6231 +int dpa_num_cpus = NR_CPUS;
6232 +
6233 +static const struct fqid_cell tx_confirm_fqids[] = {
6234 + {0, DPAA_ETH_TX_QUEUES}
6235 +};
6236 +
6237 +static struct fqid_cell default_fqids[][3] = {
6238 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6239 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6240 +};
6241 +
6242 +static const char fsl_qman_frame_queues[][25] = {
6243 + [RX] = "fsl,qman-frame-queues-rx",
6244 + [TX] = "fsl,qman-frame-queues-tx"
6245 +};
6246 +#ifdef CONFIG_FSL_DPAA_HOOKS
6247 +/* A set of callbacks for hooking into the fastpath at different points. */
6248 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6249 +EXPORT_SYMBOL(dpaa_eth_hooks);
6250 +/* This function should only be called on the probe paths, since it makes no
6251 + * effort to guarantee consistency of the destination hooks structure.
6252 + */
6253 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6254 +{
6255 + if (hooks)
6256 + dpaa_eth_hooks = *hooks;
6257 + else
6258 + pr_err("NULL pointer to hooks!\n");
6259 +}
6260 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6261 +#endif
6262 +
6263 +int dpa_netdev_init(struct net_device *net_dev,
6264 + const uint8_t *mac_addr,
6265 + uint16_t tx_timeout)
6266 +{
6267 + int err;
6268 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6269 + struct device *dev = net_dev->dev.parent;
6270 +
6271 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6272 +
6273 + net_dev->features |= net_dev->hw_features;
6274 + net_dev->vlan_features = net_dev->features;
6275 +
6276 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6277 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6278 +
6279 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6280 +
6281 + net_dev->needed_headroom = priv->tx_headroom;
6282 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6283 +
6284 + err = register_netdev(net_dev);
6285 + if (err < 0) {
6286 + dev_err(dev, "register_netdev() = %d\n", err);
6287 + return err;
6288 + }
6289 +
6290 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6291 + /* create debugfs entry for this net_device */
6292 + err = dpa_netdev_debugfs_create(net_dev);
6293 + if (err) {
6294 + unregister_netdev(net_dev);
6295 + return err;
6296 + }
6297 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6298 +
6299 + return 0;
6300 +}
6301 +EXPORT_SYMBOL(dpa_netdev_init);
6302 +
6303 +int __cold dpa_start(struct net_device *net_dev)
6304 +{
6305 + int err, i;
6306 + struct dpa_priv_s *priv;
6307 + struct mac_device *mac_dev;
6308 +
6309 + priv = netdev_priv(net_dev);
6310 + mac_dev = priv->mac_dev;
6311 +
6312 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6313 + if (err < 0) {
6314 + if (netif_msg_ifup(priv))
6315 + netdev_err(net_dev, "init_phy() = %d\n", err);
6316 + return err;
6317 + }
6318 +
6319 + for_each_port_device(i, mac_dev->port_dev) {
6320 + err = fm_port_enable(mac_dev->port_dev[i]);
6321 + if (err)
6322 + goto mac_start_failed;
6323 + }
6324 +
6325 + err = priv->mac_dev->start(mac_dev);
6326 + if (err < 0) {
6327 + if (netif_msg_ifup(priv))
6328 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6329 + goto mac_start_failed;
6330 + }
6331 +
6332 + netif_tx_start_all_queues(net_dev);
6333 +
6334 + return 0;
6335 +
6336 +mac_start_failed:
6337 + for_each_port_device(i, mac_dev->port_dev)
6338 + fm_port_disable(mac_dev->port_dev[i]);
6339 +
6340 + return err;
6341 +}
6342 +EXPORT_SYMBOL(dpa_start);
6343 +
6344 +int __cold dpa_stop(struct net_device *net_dev)
6345 +{
6346 + int _errno, i, err;
6347 + struct dpa_priv_s *priv;
6348 + struct mac_device *mac_dev;
6349 +
6350 + priv = netdev_priv(net_dev);
6351 + mac_dev = priv->mac_dev;
6352 +
6353 + netif_tx_stop_all_queues(net_dev);
6354 + /* Allow the Fman (Tx) port to process in-flight frames before we
6355 + * try switching it off.
6356 + */
6357 + usleep_range(5000, 10000);
6358 +
6359 + _errno = mac_dev->stop(mac_dev);
6360 + if (unlikely(_errno < 0))
6361 + if (netif_msg_ifdown(priv))
6362 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6363 + _errno);
6364 +
6365 + for_each_port_device(i, mac_dev->port_dev) {
6366 + err = fm_port_disable(mac_dev->port_dev[i]);
6367 + _errno = err ? err : _errno;
6368 + }
6369 +
6370 + if (mac_dev->phy_dev)
6371 + phy_disconnect(mac_dev->phy_dev);
6372 + mac_dev->phy_dev = NULL;
6373 +
6374 + return _errno;
6375 +}
6376 +EXPORT_SYMBOL(dpa_stop);
6377 +
6378 +void __cold dpa_timeout(struct net_device *net_dev)
6379 +{
6380 + const struct dpa_priv_s *priv;
6381 + struct dpa_percpu_priv_s *percpu_priv;
6382 +
6383 + priv = netdev_priv(net_dev);
6384 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6385 +
6386 + if (netif_msg_timer(priv))
6387 + netdev_crit(net_dev, "Transmit timeout!\n");
6388 +
6389 + percpu_priv->stats.tx_errors++;
6390 +}
6391 +EXPORT_SYMBOL(dpa_timeout);
6392 +
6393 +/* net_device */
6394 +
6395 +/**
6396 + * @param net_dev the device for which statistics are calculated
6397 + * @param stats the function fills this structure with the device's statistics
6398 + * @return the address of the structure containing the statistics
6399 + *
6400 + * Calculates the statistics for the given device by adding the statistics
6401 + * collected by each CPU.
6402 + */
6403 +void __cold
6404 +dpa_get_stats64(struct net_device *net_dev,
6405 + struct rtnl_link_stats64 *stats)
6406 +{
6407 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6408 + u64 *cpustats;
6409 + u64 *netstats = (u64 *)stats;
6410 + int i, j;
6411 + struct dpa_percpu_priv_s *percpu_priv;
6412 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6413 +
6414 + for_each_possible_cpu(i) {
6415 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6416 +
6417 + cpustats = (u64 *)&percpu_priv->stats;
6418 +
6419 + for (j = 0; j < numstats; j++)
6420 + netstats[j] += cpustats[j];
6421 + }
6422 +}
6423 +EXPORT_SYMBOL(dpa_get_stats64);
6424 +
6425 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6426 +{
6427 + const int max_mtu = dpa_get_max_mtu();
6428 +
6429 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6430 + if (new_mtu < 68 || new_mtu > max_mtu) {
6431 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6432 + new_mtu, 68, max_mtu);
6433 + return -EINVAL;
6434 + }
6435 + net_dev->mtu = new_mtu;
6436 +
6437 + return 0;
6438 +}
6439 +EXPORT_SYMBOL(dpa_change_mtu);
6440 +
6441 +/* .ndo_init callback */
6442 +int dpa_ndo_init(struct net_device *net_dev)
6443 +{
6444 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6445 + * we choose conservatively and let the user explicitly set a higher
6446 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6447 + * in the same LAN.
6448 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6449 + * start with the maximum allowed.
6450 + */
6451 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6452 +
6453 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6454 + net_dev->mtu = init_mtu;
6455 +
6456 + return 0;
6457 +}
6458 +EXPORT_SYMBOL(dpa_ndo_init);
6459 +
6460 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6461 +{
6462 + /* Not much to do here for now */
6463 + dev->features = features;
6464 + return 0;
6465 +}
6466 +EXPORT_SYMBOL(dpa_set_features);
6467 +
6468 +netdev_features_t dpa_fix_features(struct net_device *dev,
6469 + netdev_features_t features)
6470 +{
6471 + netdev_features_t unsupported_features = 0;
6472 +
6473 + /* In theory we should never be requested to enable features that
6474 + * we didn't set in netdev->features and netdev->hw_features at probe
6475 + * time, but double check just to be on the safe side.
6476 + * We don't support enabling Rx csum through ethtool yet
6477 + */
6478 + unsupported_features |= NETIF_F_RXCSUM;
6479 +
6480 + features &= ~unsupported_features;
6481 +
6482 + return features;
6483 +}
6484 +EXPORT_SYMBOL(dpa_fix_features);
6485 +
6486 +#ifdef CONFIG_FSL_DPAA_TS
6487 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6488 + const void *data)
6489 +{
6490 + u64 *ts, ns;
6491 +
6492 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6493 + data);
6494 +
6495 + if (!ts || *ts == 0)
6496 + return 0;
6497 +
6498 + be64_to_cpus(ts);
6499 +
6500 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6501 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6502 +
6503 + return ns;
6504 +}
6505 +
6506 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6507 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6508 +{
6509 + u64 ns;
6510 +
6511 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6512 +
6513 + if (ns == 0)
6514 + return -EINVAL;
6515 +
6516 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6517 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6518 +
6519 + return 0;
6520 +}
6521 +
6522 +static void dpa_ts_tx_enable(struct net_device *dev)
6523 +{
6524 + struct dpa_priv_s *priv = netdev_priv(dev);
6525 + struct mac_device *mac_dev = priv->mac_dev;
6526 +
6527 + if (mac_dev->fm_rtc_enable)
6528 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6529 + if (mac_dev->ptp_enable)
6530 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6531 +
6532 + priv->ts_tx_en = true;
6533 +}
6534 +
6535 +static void dpa_ts_tx_disable(struct net_device *dev)
6536 +{
6537 + struct dpa_priv_s *priv = netdev_priv(dev);
6538 +
6539 +#if 0
6540 +/* the RTC might be needed by the Rx Ts, cannot disable here
6541 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6542 + */
6543 + struct mac_device *mac_dev = priv->mac_dev;
6544 +
6545 + if (mac_dev->fm_rtc_disable)
6546 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6547 +
6548 + if (mac_dev->ptp_disable)
6549 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6550 +#endif
6551 +
6552 + priv->ts_tx_en = false;
6553 +}
6554 +
6555 +static void dpa_ts_rx_enable(struct net_device *dev)
6556 +{
6557 + struct dpa_priv_s *priv = netdev_priv(dev);
6558 + struct mac_device *mac_dev = priv->mac_dev;
6559 +
6560 + if (mac_dev->fm_rtc_enable)
6561 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6562 + if (mac_dev->ptp_enable)
6563 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6564 +
6565 + priv->ts_rx_en = true;
6566 +}
6567 +
6568 +static void dpa_ts_rx_disable(struct net_device *dev)
6569 +{
6570 + struct dpa_priv_s *priv = netdev_priv(dev);
6571 +
6572 +#if 0
6573 +/* the RTC might be needed by the Tx Ts, cannot disable here
6574 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6575 + */
6576 + struct mac_device *mac_dev = priv->mac_dev;
6577 +
6578 + if (mac_dev->fm_rtc_disable)
6579 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6580 +
6581 + if (mac_dev->ptp_disable)
6582 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6583 +#endif
6584 +
6585 + priv->ts_rx_en = false;
6586 +}
6587 +
6588 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6589 +{
6590 + struct hwtstamp_config config;
6591 +
6592 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6593 + return -EFAULT;
6594 +
6595 + switch (config.tx_type) {
6596 + case HWTSTAMP_TX_OFF:
6597 + dpa_ts_tx_disable(dev);
6598 + break;
6599 + case HWTSTAMP_TX_ON:
6600 + dpa_ts_tx_enable(dev);
6601 + break;
6602 + default:
6603 + return -ERANGE;
6604 + }
6605 +
6606 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6607 + dpa_ts_rx_disable(dev);
6608 + else {
6609 + dpa_ts_rx_enable(dev);
6610 + /* TS is set for all frame types, not only those requested */
6611 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6612 + }
6613 +
6614 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6615 + -EFAULT : 0;
6616 +}
6617 +#endif /* CONFIG_FSL_DPAA_TS */
6618 +
6619 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6620 +{
6621 +#ifdef CONFIG_FSL_DPAA_1588
6622 + struct dpa_priv_s *priv = netdev_priv(dev);
6623 +#endif
6624 + int ret = 0;
6625 +
6626 + /* at least one timestamping feature must be enabled */
6627 +#ifdef CONFIG_FSL_DPAA_TS
6628 + if (!netif_running(dev))
6629 +#endif
6630 + return -EINVAL;
6631 +
6632 +#ifdef CONFIG_FSL_DPAA_TS
6633 + if (cmd == SIOCSHWTSTAMP)
6634 + return dpa_ts_ioctl(dev, rq, cmd);
6635 +#endif /* CONFIG_FSL_DPAA_TS */
6636 +
6637 +#ifdef CONFIG_FSL_DPAA_1588
6638 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6639 + if (priv->tsu && priv->tsu->valid)
6640 + ret = dpa_ioctl_1588(dev, rq, cmd);
6641 + else
6642 + ret = -ENODEV;
6643 + }
6644 +#endif
6645 +
6646 + return ret;
6647 +}
6648 +EXPORT_SYMBOL(dpa_ioctl);
6649 +
6650 +int __cold dpa_remove(struct platform_device *of_dev)
6651 +{
6652 + int err;
6653 + struct device *dev;
6654 + struct net_device *net_dev;
6655 + struct dpa_priv_s *priv;
6656 +
6657 + dev = &of_dev->dev;
6658 + net_dev = dev_get_drvdata(dev);
6659 +
6660 + priv = netdev_priv(net_dev);
6661 +
6662 + dpaa_eth_sysfs_remove(dev);
6663 +
6664 + dev_set_drvdata(dev, NULL);
6665 + unregister_netdev(net_dev);
6666 +
6667 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6668 +
6669 + qman_delete_cgr_safe(&priv->ingress_cgr);
6670 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6671 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6672 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6673 +
6674 + dpa_private_napi_del(net_dev);
6675 +
6676 + dpa_bp_free(priv);
6677 +
6678 + if (priv->buf_layout)
6679 + devm_kfree(dev, priv->buf_layout);
6680 +
6681 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6682 + /* remove debugfs entry for this net_device */
6683 + dpa_netdev_debugfs_remove(net_dev);
6684 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6685 +
6686 +#ifdef CONFIG_FSL_DPAA_1588
6687 + if (priv->tsu && priv->tsu->valid)
6688 + dpa_ptp_cleanup(priv);
6689 +#endif
6690 +
6691 + free_netdev(net_dev);
6692 +
6693 + return err;
6694 +}
6695 +EXPORT_SYMBOL(dpa_remove);
6696 +
6697 +struct mac_device * __cold __must_check
6698 +__attribute__((nonnull))
6699 +dpa_mac_probe(struct platform_device *_of_dev)
6700 +{
6701 + struct device *dpa_dev, *dev;
6702 + struct device_node *mac_node;
6703 + struct platform_device *of_dev;
6704 + struct mac_device *mac_dev;
6705 +#ifdef CONFIG_FSL_DPAA_1588
6706 + int lenp;
6707 + const phandle *phandle_prop;
6708 + struct net_device *net_dev = NULL;
6709 + struct dpa_priv_s *priv = NULL;
6710 + struct device_node *timer_node;
6711 +#endif
6712 + dpa_dev = &_of_dev->dev;
6713 +
6714 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6715 + if (unlikely(mac_node == NULL)) {
6716 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6717 + return ERR_PTR(-EFAULT);
6718 + }
6719 +
6720 + of_dev = of_find_device_by_node(mac_node);
6721 + if (unlikely(of_dev == NULL)) {
6722 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6723 + mac_node->full_name);
6724 + of_node_put(mac_node);
6725 + return ERR_PTR(-EINVAL);
6726 + }
6727 + of_node_put(mac_node);
6728 +
6729 + dev = &of_dev->dev;
6730 +
6731 + mac_dev = dev_get_drvdata(dev);
6732 + if (unlikely(mac_dev == NULL)) {
6733 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6734 + dev_name(dev));
6735 + return ERR_PTR(-EINVAL);
6736 + }
6737 +
6738 +#ifdef CONFIG_FSL_DPAA_1588
6739 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6740 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6741 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6742 + (mac_dev->speed == SPEED_1000)))) {
6743 + timer_node = of_find_node_by_phandle(*phandle_prop);
6744 + if (timer_node)
6745 + net_dev = dev_get_drvdata(dpa_dev);
6746 + if (timer_node && net_dev) {
6747 + priv = netdev_priv(net_dev);
6748 + if (!dpa_ptp_init(priv))
6749 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6750 + mac_node->full_name);
6751 + }
6752 + }
6753 +#endif
6754 +
6755 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6756 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6757 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6758 + (mac_dev->speed == SPEED_1000))) {
6759 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6760 + if (ptp_priv.node) {
6761 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6762 + if (unlikely(ptp_priv.of_dev == NULL)) {
6763 + dev_err(dpa_dev,
6764 + "Cannot find device represented by timer_node\n");
6765 + of_node_put(ptp_priv.node);
6766 + return ERR_PTR(-EINVAL);
6767 + }
6768 + ptp_priv.mac_dev = mac_dev;
6769 + }
6770 + }
6771 +#endif
6772 + return mac_dev;
6773 +}
6774 +EXPORT_SYMBOL(dpa_mac_probe);
6775 +
6776 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6777 +{
6778 + const struct dpa_priv_s *priv;
6779 + int _errno;
6780 + struct mac_device *mac_dev;
6781 +
6782 + priv = netdev_priv(net_dev);
6783 +
6784 + _errno = eth_mac_addr(net_dev, addr);
6785 + if (_errno < 0) {
6786 + if (netif_msg_drv(priv))
6787 + netdev_err(net_dev,
6788 + "eth_mac_addr() = %d\n",
6789 + _errno);
6790 + return _errno;
6791 + }
6792 +
6793 + mac_dev = priv->mac_dev;
6794 +
6795 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6796 + net_dev->dev_addr);
6797 + if (_errno < 0) {
6798 + if (netif_msg_drv(priv))
6799 + netdev_err(net_dev,
6800 + "mac_dev->change_addr() = %d\n",
6801 + _errno);
6802 + return _errno;
6803 + }
6804 +
6805 + return 0;
6806 +}
6807 +EXPORT_SYMBOL(dpa_set_mac_address);
6808 +
6809 +void dpa_set_rx_mode(struct net_device *net_dev)
6810 +{
6811 + int _errno;
6812 + const struct dpa_priv_s *priv;
6813 +
6814 + priv = netdev_priv(net_dev);
6815 +
6816 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6817 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6818 + _errno = priv->mac_dev->set_promisc(
6819 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6820 + priv->mac_dev->promisc);
6821 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6822 + netdev_err(net_dev,
6823 + "mac_dev->set_promisc() = %d\n",
6824 + _errno);
6825 + }
6826 +
6827 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6828 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6829 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6830 +}
6831 +EXPORT_SYMBOL(dpa_set_rx_mode);
6832 +
6833 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6834 + struct dpa_buffer_layout_s *layout)
6835 +{
6836 + struct fm_port_params params;
6837 +
6838 + /* Rx */
6839 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6840 + layout[RX].parse_results = true;
6841 + layout[RX].hash_results = true;
6842 +#ifdef CONFIG_FSL_DPAA_TS
6843 + layout[RX].time_stamp = true;
6844 +#endif
6845 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6846 + layout[RX].manip_extra_space = params.manip_extra_space;
6847 + /* a value of zero for data alignment means "don't care", so align to
6848 + * a non-zero value to prevent FMD from using its own default
6849 + */
6850 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6851 +
6852 + /* Tx */
6853 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6854 + layout[TX].parse_results = true;
6855 + layout[TX].hash_results = true;
6856 +#ifdef CONFIG_FSL_DPAA_TS
6857 + layout[TX].time_stamp = true;
6858 +#endif
6859 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6860 + layout[TX].manip_extra_space = params.manip_extra_space;
6861 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6862 +}
6863 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6864 +
6865 +int __attribute__((nonnull))
6866 +dpa_bp_alloc(struct dpa_bp *dpa_bp)
6867 +{
6868 + int err;
6869 + struct bman_pool_params bp_params;
6870 + struct platform_device *pdev;
6871 +
6872 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6873 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6874 + return -EINVAL;
6875 + }
6876 +
6877 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
6878 +#ifdef CONFIG_FMAN_PFC
6879 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
6880 + bp_params.thresholds[0] = bp_params.thresholds[2] =
6881 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
6882 + bp_params.thresholds[1] = bp_params.thresholds[3] =
6883 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
6884 +#endif
6885 +
6886 + /* If the pool is already specified, we only create one per bpid */
6887 + if (dpa_bpid2pool_use(dpa_bp->bpid))
6888 + return 0;
6889 +
6890 + if (dpa_bp->bpid == 0)
6891 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
6892 + else
6893 + bp_params.bpid = dpa_bp->bpid;
6894 +
6895 + dpa_bp->pool = bman_new_pool(&bp_params);
6896 + if (unlikely(dpa_bp->pool == NULL)) {
6897 + pr_err("bman_new_pool() failed\n");
6898 + return -ENODEV;
6899 + }
6900 +
6901 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
6902 +
6903 + pdev = platform_device_register_simple("dpaa_eth_bpool",
6904 + dpa_bp->bpid, NULL, 0);
6905 + if (IS_ERR(pdev)) {
6906 + pr_err("platform_device_register_simple() failed\n");
6907 + err = PTR_ERR(pdev);
6908 + goto pdev_register_failed;
6909 + }
6910 + {
6911 + struct dma_map_ops *ops = get_dma_ops(&pdev->dev);
6912 + ops->dma_supported = NULL;
6913 + }
6914 + err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
6915 + if (err) {
6916 + pr_err("dma_coerce_mask_and_coherent() failed\n");
6917 + goto pdev_mask_failed;
6918 + }
6919 +#ifdef CONFIG_FMAN_ARM
6920 + /* force coherency */
6921 + pdev->dev.archdata.dma_coherent = true;
6922 + arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
6923 +#endif
6924 +
6925 + dpa_bp->dev = &pdev->dev;
6926 +
6927 + if (dpa_bp->seed_cb) {
6928 + err = dpa_bp->seed_cb(dpa_bp);
6929 + if (err)
6930 + goto pool_seed_failed;
6931 + }
6932 +
6933 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
6934 +
6935 + return 0;
6936 +
6937 +pool_seed_failed:
6938 +pdev_mask_failed:
6939 + platform_device_unregister(pdev);
6940 +pdev_register_failed:
6941 + bman_free_pool(dpa_bp->pool);
6942 +
6943 + return err;
6944 +}
6945 +EXPORT_SYMBOL(dpa_bp_alloc);
6946 +
6947 +void dpa_bp_drain(struct dpa_bp *bp)
6948 +{
6949 + int ret, num = 8;
6950 +
6951 + do {
6952 + struct bm_buffer bmb[8];
6953 + int i;
6954 +
6955 + ret = bman_acquire(bp->pool, bmb, num, 0);
6956 + if (ret < 0) {
6957 + if (num == 8) {
6958 + /* we have less than 8 buffers left;
6959 + * drain them one by one
6960 + */
6961 + num = 1;
6962 + ret = 1;
6963 + continue;
6964 + } else {
6965 + /* Pool is fully drained */
6966 + break;
6967 + }
6968 + }
6969 +
6970 + for (i = 0; i < num; i++) {
6971 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
6972 +
6973 + dma_unmap_single(bp->dev, addr, bp->size,
6974 + DMA_BIDIRECTIONAL);
6975 +
6976 + bp->free_buf_cb(phys_to_virt(addr));
6977 + }
6978 + } while (ret > 0);
6979 +}
6980 +EXPORT_SYMBOL(dpa_bp_drain);
6981 +
6982 +static void __cold __attribute__((nonnull))
6983 +_dpa_bp_free(struct dpa_bp *dpa_bp)
6984 +{
6985 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
6986 +
6987 + /* the mapping between bpid and dpa_bp is done very late in the
6988 + * allocation procedure; if something failed before the mapping, the bp
6989 + * was not configured, therefore we don't need the below instructions
6990 + */
6991 + if (!bp)
6992 + return;
6993 +
6994 + if (!atomic_dec_and_test(&bp->refs))
6995 + return;
6996 +
6997 + if (bp->free_buf_cb)
6998 + dpa_bp_drain(bp);
6999 +
7000 + dpa_bp_array[bp->bpid] = NULL;
7001 + bman_free_pool(bp->pool);
7002 +
7003 + if (bp->dev)
7004 + platform_device_unregister(to_platform_device(bp->dev));
7005 +}
7006 +
7007 +void __cold __attribute__((nonnull))
7008 +dpa_bp_free(struct dpa_priv_s *priv)
7009 +{
7010 + int i;
7011 +
7012 + if (priv->dpa_bp)
7013 + for (i = 0; i < priv->bp_count; i++)
7014 + _dpa_bp_free(&priv->dpa_bp[i]);
7015 +}
7016 +EXPORT_SYMBOL(dpa_bp_free);
7017 +
7018 +struct dpa_bp *dpa_bpid2pool(int bpid)
7019 +{
7020 + return dpa_bp_array[bpid];
7021 +}
7022 +EXPORT_SYMBOL(dpa_bpid2pool);
7023 +
7024 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
7025 +{
7026 + dpa_bp_array[bpid] = dpa_bp;
7027 + atomic_set(&dpa_bp->refs, 1);
7028 +}
7029 +
7030 +bool dpa_bpid2pool_use(int bpid)
7031 +{
7032 + if (dpa_bpid2pool(bpid)) {
7033 + atomic_inc(&dpa_bp_array[bpid]->refs);
7034 + return true;
7035 + }
7036 +
7037 + return false;
7038 +}
7039 +
7040 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7041 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7042 + void *accel_priv, select_queue_fallback_t fallback)
7043 +{
7044 + return dpa_get_queue_mapping(skb);
7045 +}
7046 +EXPORT_SYMBOL(dpa_select_queue);
7047 +#endif
7048 +
7049 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7050 + u32 fq_start,
7051 + u32 fq_count,
7052 + struct list_head *list,
7053 + enum dpa_fq_type fq_type)
7054 +{
7055 + int i;
7056 + struct dpa_fq *dpa_fq;
7057 +
7058 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7059 + if (dpa_fq == NULL)
7060 + return NULL;
7061 +
7062 + for (i = 0; i < fq_count; i++) {
7063 + dpa_fq[i].fq_type = fq_type;
7064 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7065 + dpa_fq[i].fqid = fq_start ?
7066 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7067 + else
7068 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7069 +
7070 + list_add_tail(&dpa_fq[i].list, list);
7071 + }
7072 +
7073 +#ifdef CONFIG_FMAN_PFC
7074 + if (fq_type == FQ_TYPE_TX)
7075 + for (i = 0; i < fq_count; i++)
7076 + dpa_fq[i].wq = i / dpa_num_cpus;
7077 + else
7078 +#endif
7079 + for (i = 0; i < fq_count; i++)
7080 + _dpa_assign_wq(dpa_fq + i);
7081 +
7082 + return dpa_fq;
7083 +}
7084 +EXPORT_SYMBOL(dpa_fq_alloc);
7085 +
7086 +/* Probing of FQs for MACful ports */
7087 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7088 + struct fm_port_fqs *port_fqs,
7089 + bool alloc_tx_conf_fqs,
7090 + enum port_type ptype)
7091 +{
7092 + struct fqid_cell *fqids = NULL;
7093 + const void *fqids_off = NULL;
7094 + struct dpa_fq *dpa_fq = NULL;
7095 + struct device_node *np = dev->of_node;
7096 + int num_ranges;
7097 + int i, lenp;
7098 +
7099 + if (ptype == TX && alloc_tx_conf_fqs) {
7100 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7101 + tx_confirm_fqids->count, list,
7102 + FQ_TYPE_TX_CONF_MQ))
7103 + goto fq_alloc_failed;
7104 + }
7105 +
7106 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7107 + if (fqids_off == NULL) {
7108 + /* No dts definition, so use the defaults. */
7109 + fqids = default_fqids[ptype];
7110 + num_ranges = 3;
7111 + } else {
7112 + num_ranges = lenp / sizeof(*fqids);
7113 +
7114 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7115 + GFP_KERNEL);
7116 + if (fqids == NULL)
7117 + goto fqids_alloc_failed;
7118 +
7119 + /* convert to CPU endianess */
7120 + for (i = 0; i < num_ranges; i++) {
7121 + fqids[i].start = be32_to_cpup(fqids_off +
7122 + i * sizeof(*fqids));
7123 + fqids[i].count = be32_to_cpup(fqids_off +
7124 + i * sizeof(*fqids) + sizeof(__be32));
7125 + }
7126 + }
7127 +
7128 + for (i = 0; i < num_ranges; i++) {
7129 + switch (i) {
7130 + case 0:
7131 + /* The first queue is the error queue */
7132 + if (fqids[i].count != 1)
7133 + goto invalid_error_queue;
7134 +
7135 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7136 + fqids[i].count, list,
7137 + ptype == RX ?
7138 + FQ_TYPE_RX_ERROR :
7139 + FQ_TYPE_TX_ERROR);
7140 + if (dpa_fq == NULL)
7141 + goto fq_alloc_failed;
7142 +
7143 + if (ptype == RX)
7144 + port_fqs->rx_errq = &dpa_fq[0];
7145 + else
7146 + port_fqs->tx_errq = &dpa_fq[0];
7147 + break;
7148 + case 1:
7149 + /* the second queue is the default queue */
7150 + if (fqids[i].count != 1)
7151 + goto invalid_default_queue;
7152 +
7153 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7154 + fqids[i].count, list,
7155 + ptype == RX ?
7156 + FQ_TYPE_RX_DEFAULT :
7157 + FQ_TYPE_TX_CONFIRM);
7158 + if (dpa_fq == NULL)
7159 + goto fq_alloc_failed;
7160 +
7161 + if (ptype == RX)
7162 + port_fqs->rx_defq = &dpa_fq[0];
7163 + else
7164 + port_fqs->tx_defq = &dpa_fq[0];
7165 + break;
7166 + default:
7167 + /* all subsequent queues are either RX* PCD or Tx */
7168 + if (ptype == RX) {
7169 + if (!dpa_fq_alloc(dev, fqids[i].start,
7170 + fqids[i].count, list,
7171 + FQ_TYPE_RX_PCD) ||
7172 + !dpa_fq_alloc(dev, fqids[i].start,
7173 + fqids[i].count, list,
7174 + FQ_TYPE_RX_PCD_HI_PRIO))
7175 + goto fq_alloc_failed;
7176 + } else {
7177 + if (!dpa_fq_alloc(dev, fqids[i].start,
7178 + fqids[i].count, list,
7179 + FQ_TYPE_TX))
7180 + goto fq_alloc_failed;
7181 + }
7182 + break;
7183 + }
7184 + }
7185 +
7186 + return 0;
7187 +
7188 +fq_alloc_failed:
7189 +fqids_alloc_failed:
7190 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7191 + return -ENOMEM;
7192 +
7193 +invalid_default_queue:
7194 +invalid_error_queue:
7195 + dev_err(dev, "Too many default or error queues\n");
7196 + return -EINVAL;
7197 +}
7198 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7199 +
7200 +static u32 rx_pool_channel;
7201 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7202 +
7203 +int dpa_get_channel(void)
7204 +{
7205 + spin_lock(&rx_pool_channel_init);
7206 + if (!rx_pool_channel) {
7207 + u32 pool;
7208 + int ret = qman_alloc_pool(&pool);
7209 + if (!ret)
7210 + rx_pool_channel = pool;
7211 + }
7212 + spin_unlock(&rx_pool_channel_init);
7213 + if (!rx_pool_channel)
7214 + return -ENOMEM;
7215 + return rx_pool_channel;
7216 +}
7217 +EXPORT_SYMBOL(dpa_get_channel);
7218 +
7219 +void dpa_release_channel(void)
7220 +{
7221 + qman_release_pool(rx_pool_channel);
7222 +}
7223 +EXPORT_SYMBOL(dpa_release_channel);
7224 +
7225 +void dpaa_eth_add_channel(u16 channel)
7226 +{
7227 + const cpumask_t *cpus = qman_affine_cpus();
7228 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7229 + int cpu;
7230 + struct qman_portal *portal;
7231 +
7232 + for_each_cpu(cpu, cpus) {
7233 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7234 + qman_p_static_dequeue_add(portal, pool);
7235 + }
7236 +}
7237 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7238 +
7239 +/**
7240 + * Congestion group state change notification callback.
7241 + * Stops the device's egress queues while they are congested and
7242 + * wakes them upon exiting congested state.
7243 + * Also updates some CGR-related stats.
7244 + */
7245 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7246 +
7247 + int congested)
7248 +{
7249 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7250 + struct dpa_priv_s, cgr_data.cgr);
7251 +
7252 + if (congested) {
7253 + priv->cgr_data.congestion_start_jiffies = jiffies;
7254 + netif_tx_stop_all_queues(priv->net_dev);
7255 + priv->cgr_data.cgr_congested_count++;
7256 + } else {
7257 + priv->cgr_data.congested_jiffies +=
7258 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7259 + netif_tx_wake_all_queues(priv->net_dev);
7260 + }
7261 +}
7262 +
7263 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7264 +{
7265 + struct qm_mcc_initcgr initcgr;
7266 + u32 cs_th;
7267 + int err;
7268 +
7269 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7270 + if (err < 0) {
7271 + pr_err("Error %d allocating CGR ID\n", err);
7272 + goto out_error;
7273 + }
7274 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7275 +
7276 + /* Enable Congestion State Change Notifications and CS taildrop */
7277 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7278 + initcgr.cgr.cscn_en = QM_CGR_EN;
7279 +
7280 + /* Set different thresholds based on the MAC speed.
7281 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7282 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7283 + * In such cases, we ought to reconfigure the threshold, too.
7284 + */
7285 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7286 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7287 + else
7288 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7289 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7290 +
7291 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7292 + initcgr.cgr.cstd_en = QM_CGR_EN;
7293 +
7294 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7295 + &initcgr);
7296 + if (err < 0) {
7297 + pr_err("Error %d creating CGR with ID %d\n", err,
7298 + priv->cgr_data.cgr.cgrid);
7299 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7300 + goto out_error;
7301 + }
7302 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7303 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7304 + priv->cgr_data.cgr.chan);
7305 +
7306 +out_error:
7307 + return err;
7308 +}
7309 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7310 +
7311 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7312 + struct dpa_fq *fq,
7313 + const struct qman_fq *template)
7314 +{
7315 + fq->fq_base = *template;
7316 + fq->net_dev = priv->net_dev;
7317 +
7318 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7319 + fq->channel = priv->channel;
7320 +}
7321 +
7322 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7323 + struct dpa_fq *fq,
7324 + struct fm_port *port,
7325 + const struct qman_fq *template)
7326 +{
7327 + fq->fq_base = *template;
7328 + fq->net_dev = priv->net_dev;
7329 +
7330 + if (port) {
7331 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7332 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7333 + } else {
7334 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7335 + }
7336 +}
7337 +
7338 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7339 + struct fm_port *tx_port)
7340 +{
7341 + struct dpa_fq *fq;
7342 + uint16_t portals[NR_CPUS];
7343 + int cpu, portal_cnt = 0, num_portals = 0;
7344 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7345 + const cpumask_t *affine_cpus = qman_affine_cpus();
7346 + int egress_cnt = 0, conf_cnt = 0;
7347 +
7348 + /* Prepare for PCD FQs init */
7349 + for_each_cpu(cpu, affine_cpus)
7350 + portals[num_portals++] = qman_affine_channel(cpu);
7351 + if (num_portals == 0)
7352 + dev_err(priv->net_dev->dev.parent,
7353 + "No Qman software (affine) channels found");
7354 +
7355 + pcd_fqid = (priv->mac_dev) ?
7356 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7357 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7358 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7359 +
7360 + /* Initialize each FQ in the list */
7361 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7362 + switch (fq->fq_type) {
7363 + case FQ_TYPE_RX_DEFAULT:
7364 + BUG_ON(!priv->mac_dev);
7365 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7366 + break;
7367 + case FQ_TYPE_RX_ERROR:
7368 + BUG_ON(!priv->mac_dev);
7369 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7370 + break;
7371 + case FQ_TYPE_RX_PCD:
7372 + /* For MACless we can't have dynamic Rx queues */
7373 + BUG_ON(!priv->mac_dev && !fq->fqid);
7374 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7375 + if (!fq->fqid)
7376 + fq->fqid = pcd_fqid++;
7377 + fq->channel = portals[portal_cnt];
7378 + portal_cnt = (portal_cnt + 1) % num_portals;
7379 + break;
7380 + case FQ_TYPE_RX_PCD_HI_PRIO:
7381 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7382 + BUG_ON(!priv->mac_dev && !fq->fqid);
7383 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7384 + if (!fq->fqid)
7385 + fq->fqid = pcd_fqid_hi_prio++;
7386 + fq->channel = portals[portal_cnt];
7387 + portal_cnt = (portal_cnt + 1) % num_portals;
7388 + break;
7389 + case FQ_TYPE_TX:
7390 + dpa_setup_egress(priv, fq, tx_port,
7391 + &fq_cbs->egress_ern);
7392 + /* If we have more Tx queues than the number of cores,
7393 + * just ignore the extra ones.
7394 + */
7395 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7396 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7397 + break;
7398 + case FQ_TYPE_TX_CONFIRM:
7399 + BUG_ON(!priv->mac_dev);
7400 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7401 + break;
7402 + case FQ_TYPE_TX_CONF_MQ:
7403 + BUG_ON(!priv->mac_dev);
7404 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7405 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7406 + break;
7407 + case FQ_TYPE_TX_ERROR:
7408 + BUG_ON(!priv->mac_dev);
7409 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7410 + break;
7411 + default:
7412 + dev_warn(priv->net_dev->dev.parent,
7413 + "Unknown FQ type detected!\n");
7414 + break;
7415 + }
7416 + }
7417 +
7418 + /* The number of Tx queues may be smaller than the number of cores, if
7419 + * the Tx queue range is specified in the device tree instead of being
7420 + * dynamically allocated.
7421 + * Make sure all CPUs receive a corresponding Tx queue.
7422 + */
7423 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7424 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7425 + if (fq->fq_type != FQ_TYPE_TX)
7426 + continue;
7427 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7428 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7429 + break;
7430 + }
7431 + }
7432 +}
7433 +EXPORT_SYMBOL(dpa_fq_setup);
7434 +
7435 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7436 +{
7437 + int _errno;
7438 + const struct dpa_priv_s *priv;
7439 + struct device *dev;
7440 + struct qman_fq *fq;
7441 + struct qm_mcc_initfq initfq;
7442 + struct qman_fq *confq;
7443 + int queue_id;
7444 +
7445 + priv = netdev_priv(dpa_fq->net_dev);
7446 + dev = dpa_fq->net_dev->dev.parent;
7447 +
7448 + if (dpa_fq->fqid == 0)
7449 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7450 +
7451 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7452 +
7453 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7454 + if (_errno) {
7455 + dev_err(dev, "qman_create_fq() failed\n");
7456 + return _errno;
7457 + }
7458 + fq = &dpa_fq->fq_base;
7459 +
7460 + if (dpa_fq->init) {
7461 + memset(&initfq, 0, sizeof(initfq));
7462 +
7463 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7464 + /* FIXME: why would we want to keep an empty FQ in cache? */
7465 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7466 +
7467 + /* Try to reduce the number of portal interrupts for
7468 + * Tx Confirmation FQs.
7469 + */
7470 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7471 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7472 +
7473 + /* FQ placement */
7474 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7475 +
7476 + initfq.fqd.dest.channel = dpa_fq->channel;
7477 + initfq.fqd.dest.wq = dpa_fq->wq;
7478 +
7479 + /* Put all egress queues in a congestion group of their own.
7480 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7481 + * rather than Tx - but they nonetheless account for the
7482 + * memory footprint on behalf of egress traffic. We therefore
7483 + * place them in the netdev's CGR, along with the Tx FQs.
7484 + */
7485 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7486 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7487 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7488 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7489 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7490 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7491 + /* Set a fixed overhead accounting, in an attempt to
7492 + * reduce the impact of fixed-size skb shells and the
7493 + * driver's needed headroom on system memory. This is
7494 + * especially the case when the egress traffic is
7495 + * composed of small datagrams.
7496 + * Unfortunately, QMan's OAL value is capped to an
7497 + * insufficient value, but even that is better than
7498 + * no overhead accounting at all.
7499 + */
7500 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7501 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7502 + initfq.fqd.oac_init.oal =
7503 + (signed char)(min(sizeof(struct sk_buff) +
7504 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7505 + }
7506 +
7507 + if (td_enable) {
7508 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7509 + qm_fqd_taildrop_set(&initfq.fqd.td,
7510 + DPA_FQ_TD, 1);
7511 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7512 + }
7513 +
7514 + /* Configure the Tx confirmation queue, now that we know
7515 + * which Tx queue it pairs with.
7516 + */
7517 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7518 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7519 + if (queue_id >= 0) {
7520 + confq = priv->conf_fqs[queue_id];
7521 + if (confq) {
7522 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7523 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7524 + * A2V=1 (contextA A2 field is valid)
7525 + * A0V=1 (contextA A0 field is valid)
7526 + * B0V=1 (contextB field is valid)
7527 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7528 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7529 + */
7530 + initfq.fqd.context_a.hi = 0x1e000000;
7531 + initfq.fqd.context_a.lo = 0x80000000;
7532 + }
7533 + }
7534 + }
7535 +
7536 + /* Put all *private* ingress queues in our "ingress CGR". */
7537 + if (priv->use_ingress_cgr &&
7538 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7539 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7540 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7541 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7542 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7543 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7544 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7545 + /* Set a fixed overhead accounting, just like for the
7546 + * egress CGR.
7547 + */
7548 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7549 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7550 + initfq.fqd.oac_init.oal =
7551 + (signed char)(min(sizeof(struct sk_buff) +
7552 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7553 + }
7554 +
7555 + /* Initialization common to all ingress queues */
7556 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7557 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7558 + initfq.fqd.fq_ctrl |=
7559 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7560 + initfq.fqd.context_a.stashing.exclusive =
7561 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7562 + QM_STASHING_EXCL_ANNOTATION;
7563 + initfq.fqd.context_a.stashing.data_cl = 2;
7564 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7565 + initfq.fqd.context_a.stashing.context_cl =
7566 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7567 + }
7568 +
7569 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7570 + if (_errno < 0) {
7571 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7572 + dpa_fq->init = 0;
7573 + } else {
7574 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7575 + qman_fq_fqid(fq), _errno);
7576 + qman_destroy_fq(fq, 0);
7577 + }
7578 + return _errno;
7579 + }
7580 + }
7581 +
7582 + dpa_fq->fqid = qman_fq_fqid(fq);
7583 +
7584 + return 0;
7585 +}
7586 +EXPORT_SYMBOL(dpa_fq_init);
7587 +
7588 +int __cold __attribute__((nonnull))
7589 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7590 +{
7591 + int _errno, __errno;
7592 + struct dpa_fq *dpa_fq;
7593 + const struct dpa_priv_s *priv;
7594 +
7595 + _errno = 0;
7596 +
7597 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7598 + priv = netdev_priv(dpa_fq->net_dev);
7599 +
7600 + if (dpa_fq->init) {
7601 + _errno = qman_retire_fq(fq, NULL);
7602 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7603 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7604 + qman_fq_fqid(fq), _errno);
7605 +
7606 + __errno = qman_oos_fq(fq);
7607 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7608 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7609 + qman_fq_fqid(fq), __errno);
7610 + if (_errno >= 0)
7611 + _errno = __errno;
7612 + }
7613 + }
7614 +
7615 + qman_destroy_fq(fq, 0);
7616 + list_del(&dpa_fq->list);
7617 +
7618 + return _errno;
7619 +}
7620 +EXPORT_SYMBOL(_dpa_fq_free);
7621 +
7622 +int __cold __attribute__((nonnull))
7623 +dpa_fq_free(struct device *dev, struct list_head *list)
7624 +{
7625 + int _errno, __errno;
7626 + struct dpa_fq *dpa_fq, *tmp;
7627 +
7628 + _errno = 0;
7629 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7630 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7631 + if (unlikely(__errno < 0) && _errno >= 0)
7632 + _errno = __errno;
7633 + }
7634 +
7635 + return _errno;
7636 +}
7637 +EXPORT_SYMBOL(dpa_fq_free);
7638 +
7639 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7640 +{
7641 + int _errno, __errno;
7642 + struct dpa_fq *dpa_fq, *tmp;
7643 + static bool print_msg __read_mostly;
7644 +
7645 + _errno = 0;
7646 + print_msg = true;
7647 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7648 + __errno = dpa_fq_init(dpa_fq, td_enable);
7649 + if (unlikely(__errno < 0) && _errno >= 0) {
7650 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7651 + if (print_msg) {
7652 + dev_warn(dev,
7653 + "Skip RX PCD High Priority FQs initialization\n");
7654 + print_msg = false;
7655 + }
7656 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7657 + dev_warn(dev,
7658 + "Error freeing frame queues\n");
7659 + } else {
7660 + _errno = __errno;
7661 + break;
7662 + }
7663 + }
7664 + }
7665 +
7666 + return _errno;
7667 +}
7668 +EXPORT_SYMBOL(dpa_fqs_init);
7669 +static void
7670 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7671 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7672 +{
7673 + struct fm_port_params tx_port_param;
7674 + bool frag_enabled = false;
7675 +
7676 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7677 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7678 + buf_layout, frag_enabled);
7679 +}
7680 +
7681 +static void
7682 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7683 + struct dpa_fq *errq, struct dpa_fq *defq,
7684 + struct dpa_buffer_layout_s *buf_layout)
7685 +{
7686 + struct fm_port_params rx_port_param;
7687 + int i;
7688 + bool frag_enabled = false;
7689 +
7690 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7691 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7692 + rx_port_param.num_pools = (uint8_t)count;
7693 + for (i = 0; i < count; i++) {
7694 + if (i >= rx_port_param.num_pools)
7695 + break;
7696 + rx_port_param.pool_param[i].id = bp[i].bpid;
7697 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7698 + }
7699 +
7700 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7701 + buf_layout, frag_enabled);
7702 +}
7703 +
7704 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7705 +/* Defined as weak, to be implemented by fman pcd tester. */
7706 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7707 +__attribute__((weak));
7708 +
7709 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7710 +#else
7711 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7712 +
7713 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7714 +
7715 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7716 +
7717 +
7718 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7719 + uint8_t alignment, uint32_t *base_fqid)
7720 +{
7721 + dev_crit(dev, "callback not implemented!\n");
7722 +
7723 + return 0;
7724 +}
7725 +
7726 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7727 +{
7728 +
7729 + dev_crit(dev, "callback not implemented!\n");
7730 +
7731 + return 0;
7732 +}
7733 +
7734 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7735 + struct dpa_bp *bp, size_t count,
7736 + struct fm_port_fqs *port_fqs,
7737 + struct dpa_buffer_layout_s *buf_layout,
7738 + struct device *dev)
7739 +{
7740 + struct fm_port_pcd_param rx_port_pcd_param;
7741 + struct fm_port *rxport = mac_dev->port_dev[RX];
7742 + struct fm_port *txport = mac_dev->port_dev[TX];
7743 +
7744 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7745 + port_fqs->tx_defq, &buf_layout[TX]);
7746 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7747 + port_fqs->rx_defq, &buf_layout[RX]);
7748 +
7749 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7750 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7751 + rx_port_pcd_param.dev = dev;
7752 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7753 +}
7754 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7755 +
7756 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7757 +{
7758 + struct dpa_bp *dpa_bp;
7759 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7760 + uint8_t i = 0, j;
7761 +
7762 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7763 +
7764 + do {
7765 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7766 + DPA_BUG_ON(!dpa_bp);
7767 +
7768 + j = 0;
7769 + do {
7770 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7771 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7772 +
7773 + j++; i++;
7774 + } while (j < ARRAY_SIZE(bmb) &&
7775 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7776 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7777 + qm_sg_entry_get_bpid(&sgt[i]));
7778 +
7779 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7780 + cpu_relax();
7781 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7782 +}
7783 +EXPORT_SYMBOL(dpa_release_sgt);
7784 +
7785 +void __attribute__((nonnull))
7786 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7787 +{
7788 + struct qm_sg_entry *sgt;
7789 + struct dpa_bp *dpa_bp;
7790 + struct bm_buffer bmb;
7791 + dma_addr_t addr;
7792 + void *vaddr;
7793 +
7794 + bmb.opaque = 0;
7795 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7796 +
7797 + dpa_bp = dpa_bpid2pool(fd->bpid);
7798 + DPA_BUG_ON(!dpa_bp);
7799 +
7800 + if (fd->format == qm_fd_sg) {
7801 + vaddr = phys_to_virt(qm_fd_addr(fd));
7802 + sgt = vaddr + dpa_fd_offset(fd);
7803 +
7804 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7805 + DMA_BIDIRECTIONAL);
7806 +
7807 + dpa_release_sgt(sgt);
7808 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7809 + DMA_BIDIRECTIONAL);
7810 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7811 + dev_err(dpa_bp->dev, "DMA mapping failed");
7812 + return;
7813 + }
7814 + bm_buffer_set64(&bmb, addr);
7815 + }
7816 +
7817 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7818 + cpu_relax();
7819 +}
7820 +EXPORT_SYMBOL(dpa_fd_release);
7821 +
7822 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7823 + const struct qm_mr_entry *msg)
7824 +{
7825 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7826 + case QM_MR_RC_CGR_TAILDROP:
7827 + percpu_priv->ern_cnt.cg_tdrop++;
7828 + break;
7829 + case QM_MR_RC_WRED:
7830 + percpu_priv->ern_cnt.wred++;
7831 + break;
7832 + case QM_MR_RC_ERROR:
7833 + percpu_priv->ern_cnt.err_cond++;
7834 + break;
7835 + case QM_MR_RC_ORPWINDOW_EARLY:
7836 + percpu_priv->ern_cnt.early_window++;
7837 + break;
7838 + case QM_MR_RC_ORPWINDOW_LATE:
7839 + percpu_priv->ern_cnt.late_window++;
7840 + break;
7841 + case QM_MR_RC_FQ_TAILDROP:
7842 + percpu_priv->ern_cnt.fq_tdrop++;
7843 + break;
7844 + case QM_MR_RC_ORPWINDOW_RETIRED:
7845 + percpu_priv->ern_cnt.fq_retired++;
7846 + break;
7847 + case QM_MR_RC_ORP_ZERO:
7848 + percpu_priv->ern_cnt.orp_zero++;
7849 + break;
7850 + }
7851 +}
7852 +EXPORT_SYMBOL(count_ern);
7853 +
7854 +/**
7855 + * Turn on HW checksum computation for this outgoing frame.
7856 + * If the current protocol is not something we support in this regard
7857 + * (or if the stack has already computed the SW checksum), we do nothing.
7858 + *
7859 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7860 + * otherwise.
7861 + *
7862 + * Note that this function may modify the fd->cmd field and the skb data buffer
7863 + * (the Parse Results area).
7864 + */
7865 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7866 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7867 +{
7868 + fm_prs_result_t *parse_result;
7869 + struct iphdr *iph;
7870 + struct ipv6hdr *ipv6h = NULL;
7871 + u8 l4_proto;
7872 + u16 ethertype = ntohs(skb->protocol);
7873 + int retval = 0;
7874 +
7875 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7876 + return 0;
7877 +
7878 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7879 + * L4 alone from the FM configuration anyway.
7880 + */
7881 +
7882 + /* Fill in some fields of the Parse Results array, so the FMan
7883 + * can find them as if they came from the FMan Parser.
7884 + */
7885 + parse_result = (fm_prs_result_t *)parse_results;
7886 +
7887 + /* If we're dealing with VLAN, get the real Ethernet type */
7888 + if (ethertype == ETH_P_8021Q) {
7889 + /* We can't always assume the MAC header is set correctly
7890 + * by the stack, so reset to beginning of skb->data
7891 + */
7892 + skb_reset_mac_header(skb);
7893 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7894 + }
7895 +
7896 + /* Fill in the relevant L3 parse result fields
7897 + * and read the L4 protocol type
7898 + */
7899 + switch (ethertype) {
7900 + case ETH_P_IP:
7901 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
7902 + iph = ip_hdr(skb);
7903 + DPA_BUG_ON(iph == NULL);
7904 + l4_proto = iph->protocol;
7905 + break;
7906 + case ETH_P_IPV6:
7907 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
7908 + ipv6h = ipv6_hdr(skb);
7909 + DPA_BUG_ON(ipv6h == NULL);
7910 + l4_proto = ipv6h->nexthdr;
7911 + break;
7912 + default:
7913 + /* We shouldn't even be here */
7914 + if (netif_msg_tx_err(priv) && net_ratelimit())
7915 + netdev_alert(priv->net_dev,
7916 + "Can't compute HW csum for L3 proto 0x%x\n",
7917 + ntohs(skb->protocol));
7918 + retval = -EIO;
7919 + goto return_error;
7920 + }
7921 +
7922 + /* Fill in the relevant L4 parse result fields */
7923 + switch (l4_proto) {
7924 + case IPPROTO_UDP:
7925 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
7926 + break;
7927 + case IPPROTO_TCP:
7928 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
7929 + break;
7930 + default:
7931 + /* This can as well be a BUG() */
7932 + if (netif_msg_tx_err(priv) && net_ratelimit())
7933 + netdev_alert(priv->net_dev,
7934 + "Can't compute HW csum for L4 proto 0x%x\n",
7935 + l4_proto);
7936 + retval = -EIO;
7937 + goto return_error;
7938 + }
7939 +
7940 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
7941 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
7942 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
7943 +
7944 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
7945 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
7946 +
7947 + /* On P1023 and similar platforms fd->cmd interpretation could
7948 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
7949 + * is not set so we do not need to check; in the future, if/when
7950 + * using context_a we need to check this bit
7951 + */
7952 +
7953 +return_error:
7954 + return retval;
7955 +}
7956 +EXPORT_SYMBOL(dpa_enable_tx_csum);
7957 +
7958 +#ifdef CONFIG_FSL_DPAA_CEETM
7959 +void dpa_enable_ceetm(struct net_device *dev)
7960 +{
7961 + struct dpa_priv_s *priv = netdev_priv(dev);
7962 + priv->ceetm_en = true;
7963 +}
7964 +EXPORT_SYMBOL(dpa_enable_ceetm);
7965 +
7966 +void dpa_disable_ceetm(struct net_device *dev)
7967 +{
7968 + struct dpa_priv_s *priv = netdev_priv(dev);
7969 + priv->ceetm_en = false;
7970 +}
7971 +EXPORT_SYMBOL(dpa_disable_ceetm);
7972 +#endif
7973 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7974 new file mode 100644
7975 index 00000000..41db4302
7976 --- /dev/null
7977 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7978 @@ -0,0 +1,225 @@
7979 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7980 + *
7981 + * Redistribution and use in source and binary forms, with or without
7982 + * modification, are permitted provided that the following conditions are met:
7983 + * * Redistributions of source code must retain the above copyright
7984 + * notice, this list of conditions and the following disclaimer.
7985 + * * Redistributions in binary form must reproduce the above copyright
7986 + * notice, this list of conditions and the following disclaimer in the
7987 + * documentation and/or other materials provided with the distribution.
7988 + * * Neither the name of Freescale Semiconductor nor the
7989 + * names of its contributors may be used to endorse or promote products
7990 + * derived from this software without specific prior written permission.
7991 + *
7992 + *
7993 + * ALTERNATIVELY, this software may be distributed under the terms of the
7994 + * GNU General Public License ("GPL") as published by the Free Software
7995 + * Foundation, either version 2 of that License or (at your option) any
7996 + * later version.
7997 + *
7998 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7999 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8000 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8001 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8002 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8003 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8004 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8005 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8006 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8007 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8008 + */
8009 +
8010 +#ifndef __DPAA_ETH_COMMON_H
8011 +#define __DPAA_ETH_COMMON_H
8012 +
8013 +#include <linux/etherdevice.h> /* struct net_device */
8014 +#include <linux/fsl_bman.h> /* struct bm_buffer */
8015 +#include <linux/of_platform.h> /* struct platform_device */
8016 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
8017 +
8018 +#include "dpaa_eth.h"
8019 +#include "lnxwrp_fsl_fman.h"
8020 +
8021 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
8022 + frag_enabled) \
8023 +{ \
8024 + param.errq = errq_id; \
8025 + param.defq = defq_id; \
8026 + param.priv_data_size = buf_layout->priv_data_size; \
8027 + param.parse_results = buf_layout->parse_results; \
8028 + param.hash_results = buf_layout->hash_results; \
8029 + param.frag_enable = frag_enabled; \
8030 + param.time_stamp = buf_layout->time_stamp; \
8031 + param.manip_extra_space = buf_layout->manip_extra_space; \
8032 + param.data_align = buf_layout->data_align; \
8033 + fm_set_##type##_port_params(port, &param); \
8034 +}
8035 +
8036 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
8037 +
8038 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
8039 +
8040 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
8041 +
8042 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
8043 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8044 + (_errno == -EIO))
8045 +/* return codes for the dpaa-eth hooks */
8046 +enum dpaa_eth_hook_result {
8047 + /* fd/skb was retained by the hook.
8048 + *
8049 + * On the Rx path, this means the Ethernet driver will _not_
8050 + * deliver the skb to the stack. Instead, the hook implementation
8051 + * is expected to properly dispose of the skb.
8052 + *
8053 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8054 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8055 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8056 + * unless you know exactly what you're doing!
8057 + *
8058 + * On the confirmation/error paths, the Ethernet driver will _not_
8059 + * perform any fd cleanup, nor update the interface statistics.
8060 + */
8061 + DPAA_ETH_STOLEN,
8062 + /* fd/skb was returned to the Ethernet driver for regular processing.
8063 + * The hook is not allowed to, for instance, reallocate the skb (as if
8064 + * by linearizing, copying, cloning or reallocating the headroom).
8065 + */
8066 + DPAA_ETH_CONTINUE
8067 +};
8068 +
8069 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8070 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8071 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8072 + struct sk_buff *skb, struct net_device *net_dev);
8073 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8074 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8075 +
8076 +/* used in napi related functions */
8077 +extern u16 qman_portal_max;
8078 +
8079 +/* from dpa_ethtool.c */
8080 +extern const struct ethtool_ops dpa_ethtool_ops;
8081 +
8082 +#ifdef CONFIG_FSL_DPAA_HOOKS
8083 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8084 + * Currently only one set of such hooks is supported.
8085 + */
8086 +struct dpaa_eth_hooks_s {
8087 + /* Invoked on the Tx private path, immediately after receiving the skb
8088 + * from the stack.
8089 + */
8090 + dpaa_eth_egress_hook_t tx;
8091 +
8092 + /* Invoked on the Rx private path, right before passing the skb
8093 + * up the stack. At that point, the packet's protocol id has already
8094 + * been set. The skb's data pointer is now at the L3 header, and
8095 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8096 + * to be the length of L3+payload (i.e., the length of the
8097 + * original frame minus the L2 header len).
8098 + * For more details on what the skb looks like, see eth_type_trans().
8099 + */
8100 + dpaa_eth_ingress_hook_t rx_default;
8101 +
8102 + /* Driver hook for the Rx error private path. */
8103 + dpaa_eth_confirm_hook_t rx_error;
8104 + /* Driver hook for the Tx confirmation private path. */
8105 + dpaa_eth_confirm_hook_t tx_confirm;
8106 + /* Driver hook for the Tx error private path. */
8107 + dpaa_eth_confirm_hook_t tx_error;
8108 +};
8109 +
8110 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8111 +
8112 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8113 +#endif
8114 +
8115 +int dpa_netdev_init(struct net_device *net_dev,
8116 + const uint8_t *mac_addr,
8117 + uint16_t tx_timeout);
8118 +int __cold dpa_start(struct net_device *net_dev);
8119 +int __cold dpa_stop(struct net_device *net_dev);
8120 +void __cold dpa_timeout(struct net_device *net_dev);
8121 +void __cold
8122 +dpa_get_stats64(struct net_device *net_dev,
8123 + struct rtnl_link_stats64 *stats);
8124 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8125 +int dpa_ndo_init(struct net_device *net_dev);
8126 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8127 +netdev_features_t dpa_fix_features(struct net_device *dev,
8128 + netdev_features_t features);
8129 +#ifdef CONFIG_FSL_DPAA_TS
8130 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8131 + enum port_type rx_tx, const void *data);
8132 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8133 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8134 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8135 +#endif /* CONFIG_FSL_DPAA_TS */
8136 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8137 +int __cold dpa_remove(struct platform_device *of_dev);
8138 +struct mac_device * __cold __must_check
8139 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8140 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8141 +void dpa_set_rx_mode(struct net_device *net_dev);
8142 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8143 + struct dpa_buffer_layout_s *layout);
8144 +int __attribute__((nonnull))
8145 +dpa_bp_alloc(struct dpa_bp *dpa_bp);
8146 +void __cold __attribute__((nonnull))
8147 +dpa_bp_free(struct dpa_priv_s *priv);
8148 +struct dpa_bp *dpa_bpid2pool(int bpid);
8149 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8150 +bool dpa_bpid2pool_use(int bpid);
8151 +void dpa_bp_drain(struct dpa_bp *bp);
8152 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8153 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8154 + void *accel_priv, select_queue_fallback_t fallback);
8155 +#endif
8156 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8157 + u32 fq_start,
8158 + u32 fq_count,
8159 + struct list_head *list,
8160 + enum dpa_fq_type fq_type);
8161 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8162 + struct fm_port_fqs *port_fqs,
8163 + bool tx_conf_fqs_per_core,
8164 + enum port_type ptype);
8165 +int dpa_get_channel(void);
8166 +void dpa_release_channel(void);
8167 +void dpaa_eth_add_channel(u16 channel);
8168 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8169 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8170 + struct fm_port *tx_port);
8171 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8172 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8173 +int __cold __attribute__((nonnull))
8174 +dpa_fq_free(struct device *dev, struct list_head *list);
8175 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8176 + struct dpa_bp *bp, size_t count,
8177 + struct fm_port_fqs *port_fqs,
8178 + struct dpa_buffer_layout_s *buf_layout,
8179 + struct device *dev);
8180 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8181 +void __attribute__((nonnull))
8182 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8183 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8184 + const struct qm_mr_entry *msg);
8185 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8186 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8187 +#ifdef CONFIG_FSL_DPAA_CEETM
8188 +void dpa_enable_ceetm(struct net_device *dev);
8189 +void dpa_disable_ceetm(struct net_device *dev);
8190 +#endif
8191 +struct proxy_device {
8192 + struct mac_device *mac_dev;
8193 +};
8194 +
8195 +/* mac device control functions exposed by proxy interface*/
8196 +int dpa_proxy_start(struct net_device *net_dev);
8197 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8198 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8199 + struct net_device *net_dev);
8200 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8201 + struct net_device *net_dev);
8202 +
8203 +#endif /* __DPAA_ETH_COMMON_H */
8204 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8205 new file mode 100644
8206 index 00000000..994d38cd
8207 --- /dev/null
8208 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8209 @@ -0,0 +1,381 @@
8210 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8211 + *
8212 + * Redistribution and use in source and binary forms, with or without
8213 + * modification, are permitted provided that the following conditions are met:
8214 + * * Redistributions of source code must retain the above copyright
8215 + * notice, this list of conditions and the following disclaimer.
8216 + * * Redistributions in binary form must reproduce the above copyright
8217 + * notice, this list of conditions and the following disclaimer in the
8218 + * documentation and/or other materials provided with the distribution.
8219 + * * Neither the name of Freescale Semiconductor nor the
8220 + * names of its contributors may be used to endorse or promote products
8221 + * derived from this software without specific prior written permission.
8222 + *
8223 + *
8224 + * ALTERNATIVELY, this software may be distributed under the terms of the
8225 + * GNU General Public License ("GPL") as published by the Free Software
8226 + * Foundation, either version 2 of that License or (at your option) any
8227 + * later version.
8228 + *
8229 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8230 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8231 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8232 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8233 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8234 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8235 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8236 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8237 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8238 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8239 + */
8240 +
8241 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8242 +#define pr_fmt(fmt) \
8243 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8244 + KBUILD_BASENAME".c", __LINE__, __func__
8245 +#else
8246 +#define pr_fmt(fmt) \
8247 + KBUILD_MODNAME ": " fmt
8248 +#endif
8249 +
8250 +#include <linux/init.h>
8251 +#include <linux/module.h>
8252 +#include <linux/of_platform.h>
8253 +#include "dpaa_eth.h"
8254 +#include "dpaa_eth_common.h"
8255 +#include "dpaa_eth_base.h"
8256 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8257 +#include "mac.h"
8258 +
8259 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8260 +
8261 +MODULE_LICENSE("Dual BSD/GPL");
8262 +
8263 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8264 +
8265 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8266 +#ifdef CONFIG_PM
8267 +
8268 +static int proxy_suspend(struct device *dev)
8269 +{
8270 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8271 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8272 + int err = 0;
8273 +
8274 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8275 + if (err)
8276 + goto port_suspend_failed;
8277 +
8278 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8279 + if (err)
8280 + err = fm_port_resume(mac_dev->port_dev[RX]);
8281 +
8282 +port_suspend_failed:
8283 + return err;
8284 +}
8285 +
8286 +static int proxy_resume(struct device *dev)
8287 +{
8288 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8289 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8290 + int err = 0;
8291 +
8292 + err = fm_port_resume(mac_dev->port_dev[TX]);
8293 + if (err)
8294 + goto port_resume_failed;
8295 +
8296 + err = fm_port_resume(mac_dev->port_dev[RX]);
8297 + if (err)
8298 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8299 +
8300 +port_resume_failed:
8301 + return err;
8302 +}
8303 +
8304 +static const struct dev_pm_ops proxy_pm_ops = {
8305 + .suspend = proxy_suspend,
8306 + .resume = proxy_resume,
8307 +};
8308 +
8309 +#define PROXY_PM_OPS (&proxy_pm_ops)
8310 +
8311 +#else /* CONFIG_PM */
8312 +
8313 +#define PROXY_PM_OPS NULL
8314 +
8315 +#endif /* CONFIG_PM */
8316 +
8317 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8318 +{
8319 + int err = 0, i;
8320 + struct device *dev;
8321 + struct device_node *dpa_node;
8322 + struct dpa_bp *dpa_bp;
8323 + struct list_head proxy_fq_list;
8324 + size_t count;
8325 + struct fm_port_fqs port_fqs;
8326 + struct dpa_buffer_layout_s *buf_layout = NULL;
8327 + struct mac_device *mac_dev;
8328 + struct proxy_device *proxy_dev;
8329 +
8330 + dev = &_of_dev->dev;
8331 +
8332 + dpa_node = dev->of_node;
8333 +
8334 + if (!of_device_is_available(dpa_node))
8335 + return -ENODEV;
8336 +
8337 + /* Get the buffer pools assigned to this interface */
8338 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8339 + if (IS_ERR(dpa_bp))
8340 + return PTR_ERR(dpa_bp);
8341 +
8342 + mac_dev = dpa_mac_probe(_of_dev);
8343 + if (IS_ERR(mac_dev))
8344 + return PTR_ERR(mac_dev);
8345 +
8346 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8347 + if (!proxy_dev) {
8348 + dev_err(dev, "devm_kzalloc() failed\n");
8349 + return -ENOMEM;
8350 + }
8351 +
8352 + proxy_dev->mac_dev = mac_dev;
8353 + dev_set_drvdata(dev, proxy_dev);
8354 +
8355 + /* We have physical ports, so we need to establish
8356 + * the buffer layout.
8357 + */
8358 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8359 + GFP_KERNEL);
8360 + if (!buf_layout) {
8361 + dev_err(dev, "devm_kzalloc() failed\n");
8362 + return -ENOMEM;
8363 + }
8364 + dpa_set_buffers_layout(mac_dev, buf_layout);
8365 +
8366 + INIT_LIST_HEAD(&proxy_fq_list);
8367 +
8368 + memset(&port_fqs, 0, sizeof(port_fqs));
8369 +
8370 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8371 + if (!err)
8372 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8373 + TX);
8374 + if (err < 0) {
8375 + devm_kfree(dev, buf_layout);
8376 + return err;
8377 + }
8378 +
8379 + /* Proxy initializer - Just configures the MAC on behalf of
8380 + * another partition.
8381 + */
8382 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8383 + buf_layout, dev);
8384 +
8385 + /* Proxy interfaces need to be started, and the allocated
8386 + * memory freed
8387 + */
8388 + devm_kfree(dev, buf_layout);
8389 + devm_kfree(dev, dpa_bp);
8390 +
8391 + /* Free FQ structures */
8392 + devm_kfree(dev, port_fqs.rx_defq);
8393 + devm_kfree(dev, port_fqs.rx_errq);
8394 + devm_kfree(dev, port_fqs.tx_defq);
8395 + devm_kfree(dev, port_fqs.tx_errq);
8396 +
8397 + for_each_port_device(i, mac_dev->port_dev) {
8398 + err = fm_port_enable(mac_dev->port_dev[i]);
8399 + if (err)
8400 + goto port_enable_fail;
8401 + }
8402 +
8403 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8404 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8405 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8406 +
8407 + return 0; /* Proxy interface initialization ended */
8408 +
8409 +port_enable_fail:
8410 + for_each_port_device(i, mac_dev->port_dev)
8411 + fm_port_disable(mac_dev->port_dev[i]);
8412 + dpa_eth_proxy_remove(_of_dev);
8413 +
8414 + return err;
8415 +}
8416 +
8417 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8418 + struct net_device *net_dev)
8419 +{
8420 + struct mac_device *mac_dev;
8421 + int _errno;
8422 +
8423 + mac_dev = proxy_dev->mac_dev;
8424 +
8425 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8426 + net_dev->dev_addr);
8427 + if (_errno < 0)
8428 + return _errno;
8429 +
8430 + return 0;
8431 +}
8432 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8433 +
8434 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8435 + struct net_device *net_dev)
8436 +{
8437 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8438 + int _errno;
8439 +
8440 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8441 + mac_dev->promisc = !mac_dev->promisc;
8442 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8443 + mac_dev->promisc);
8444 + if (unlikely(_errno < 0))
8445 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8446 + _errno);
8447 + }
8448 +
8449 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8450 + if (unlikely(_errno < 0))
8451 + return _errno;
8452 +
8453 + return 0;
8454 +}
8455 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8456 +
8457 +int dpa_proxy_start(struct net_device *net_dev)
8458 +{
8459 + struct mac_device *mac_dev;
8460 + const struct dpa_priv_s *priv;
8461 + struct proxy_device *proxy_dev;
8462 + int _errno;
8463 + int i;
8464 +
8465 + priv = netdev_priv(net_dev);
8466 + proxy_dev = (struct proxy_device *)priv->peer;
8467 + mac_dev = proxy_dev->mac_dev;
8468 +
8469 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8470 + if (_errno < 0) {
8471 + if (netif_msg_drv(priv))
8472 + netdev_err(net_dev, "init_phy() = %d\n",
8473 + _errno);
8474 + return _errno;
8475 + }
8476 +
8477 + for_each_port_device(i, mac_dev->port_dev) {
8478 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8479 + if (_errno)
8480 + goto port_enable_fail;
8481 + }
8482 +
8483 + _errno = mac_dev->start(mac_dev);
8484 + if (_errno < 0) {
8485 + if (netif_msg_drv(priv))
8486 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8487 + _errno);
8488 + goto port_enable_fail;
8489 + }
8490 +
8491 + return _errno;
8492 +
8493 +port_enable_fail:
8494 + for_each_port_device(i, mac_dev->port_dev)
8495 + fm_port_disable(mac_dev->port_dev[i]);
8496 +
8497 + return _errno;
8498 +}
8499 +EXPORT_SYMBOL(dpa_proxy_start);
8500 +
8501 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8502 +{
8503 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8504 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8505 + int _errno, i, err;
8506 +
8507 + _errno = mac_dev->stop(mac_dev);
8508 + if (_errno < 0) {
8509 + if (netif_msg_drv(priv))
8510 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8511 + _errno);
8512 + return _errno;
8513 + }
8514 +
8515 + for_each_port_device(i, mac_dev->port_dev) {
8516 + err = fm_port_disable(mac_dev->port_dev[i]);
8517 + _errno = err ? err : _errno;
8518 + }
8519 +
8520 + if (mac_dev->phy_dev)
8521 + phy_disconnect(mac_dev->phy_dev);
8522 + mac_dev->phy_dev = NULL;
8523 +
8524 + return _errno;
8525 +}
8526 +EXPORT_SYMBOL(dpa_proxy_stop);
8527 +
8528 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8529 +{
8530 + struct device *dev = &of_dev->dev;
8531 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8532 +
8533 + kfree(proxy_dev);
8534 +
8535 + dev_set_drvdata(dev, NULL);
8536 +
8537 + return 0;
8538 +}
8539 +
8540 +static const struct of_device_id dpa_proxy_match[] = {
8541 + {
8542 + .compatible = "fsl,dpa-ethernet-init"
8543 + },
8544 + {}
8545 +};
8546 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8547 +
8548 +static struct platform_driver dpa_proxy_driver = {
8549 + .driver = {
8550 + .name = KBUILD_MODNAME "-proxy",
8551 + .of_match_table = dpa_proxy_match,
8552 + .owner = THIS_MODULE,
8553 + .pm = PROXY_PM_OPS,
8554 + },
8555 + .probe = dpaa_eth_proxy_probe,
8556 + .remove = dpa_eth_proxy_remove
8557 +};
8558 +
8559 +static int __init __cold dpa_proxy_load(void)
8560 +{
8561 + int _errno;
8562 +
8563 + pr_info(DPA_DESCRIPTION "\n");
8564 +
8565 + /* Initialize dpaa_eth mirror values */
8566 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8567 + dpa_max_frm = fm_get_max_frm();
8568 +
8569 + _errno = platform_driver_register(&dpa_proxy_driver);
8570 + if (unlikely(_errno < 0)) {
8571 + pr_err(KBUILD_MODNAME
8572 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8573 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8574 + }
8575 +
8576 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8577 + KBUILD_BASENAME".c", __func__);
8578 +
8579 + return _errno;
8580 +}
8581 +module_init(dpa_proxy_load);
8582 +
8583 +static void __exit __cold dpa_proxy_unload(void)
8584 +{
8585 + platform_driver_unregister(&dpa_proxy_driver);
8586 +
8587 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8588 + KBUILD_BASENAME".c", __func__);
8589 +}
8590 +module_exit(dpa_proxy_unload);
8591 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8592 new file mode 100644
8593 index 00000000..11b47e8c
8594 --- /dev/null
8595 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8596 @@ -0,0 +1,1179 @@
8597 +/* Copyright 2012 Freescale Semiconductor Inc.
8598 + *
8599 + * Redistribution and use in source and binary forms, with or without
8600 + * modification, are permitted provided that the following conditions are met:
8601 + * * Redistributions of source code must retain the above copyright
8602 + * notice, this list of conditions and the following disclaimer.
8603 + * * Redistributions in binary form must reproduce the above copyright
8604 + * notice, this list of conditions and the following disclaimer in the
8605 + * documentation and/or other materials provided with the distribution.
8606 + * * Neither the name of Freescale Semiconductor nor the
8607 + * names of its contributors may be used to endorse or promote products
8608 + * derived from this software without specific prior written permission.
8609 + *
8610 + *
8611 + * ALTERNATIVELY, this software may be distributed under the terms of the
8612 + * GNU General Public License ("GPL") as published by the Free Software
8613 + * Foundation, either version 2 of that License or (at your option) any
8614 + * later version.
8615 + *
8616 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8617 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8618 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8619 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8620 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8621 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8622 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8623 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8624 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8625 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8626 + */
8627 +
8628 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8629 +#define pr_fmt(fmt) \
8630 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8631 + KBUILD_BASENAME".c", __LINE__, __func__
8632 +#else
8633 +#define pr_fmt(fmt) \
8634 + KBUILD_MODNAME ": " fmt
8635 +#endif
8636 +
8637 +#include <linux/init.h>
8638 +#include <linux/skbuff.h>
8639 +#include <linux/highmem.h>
8640 +#include <linux/fsl_bman.h>
8641 +#include <net/sock.h>
8642 +
8643 +#include "dpaa_eth.h"
8644 +#include "dpaa_eth_common.h"
8645 +#ifdef CONFIG_FSL_DPAA_1588
8646 +#include "dpaa_1588.h"
8647 +#endif
8648 +#ifdef CONFIG_FSL_DPAA_CEETM
8649 +#include "dpaa_eth_ceetm.h"
8650 +#endif
8651 +
8652 +/* DMA map and add a page frag back into the bpool.
8653 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8654 + * specifically for fitting into @dpa_bp.
8655 + */
8656 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8657 + int *count_ptr)
8658 +{
8659 + struct bm_buffer bmb;
8660 + dma_addr_t addr;
8661 +
8662 + bmb.opaque = 0;
8663 +
8664 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8665 + DMA_BIDIRECTIONAL);
8666 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8667 + dev_err(dpa_bp->dev, "DMA mapping failed");
8668 + return;
8669 + }
8670 +
8671 + bm_buffer_set64(&bmb, addr);
8672 +
8673 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8674 + cpu_relax();
8675 +
8676 + (*count_ptr)++;
8677 +}
8678 +
8679 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8680 +{
8681 + struct bm_buffer bmb[8];
8682 + void *new_buf;
8683 + dma_addr_t addr;
8684 + uint8_t i;
8685 + struct device *dev = dpa_bp->dev;
8686 + struct sk_buff *skb, **skbh;
8687 +
8688 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8689 +
8690 + for (i = 0; i < 8; i++) {
8691 + /* We'll prepend the skb back-pointer; can't use the DPA
8692 + * priv space, because FMan will overwrite it (from offset 0)
8693 + * if it ends up being the second, third, etc. fragment
8694 + * in a S/G frame.
8695 + *
8696 + * We only need enough space to store a pointer, but allocate
8697 + * an entire cacheline for performance reasons.
8698 + */
8699 +#ifndef CONFIG_PPC
8700 + if (unlikely(dpaa_errata_a010022)) {
8701 + struct page *new_page = alloc_page(GFP_ATOMIC);
8702 + if (unlikely(!new_page))
8703 + goto netdev_alloc_failed;
8704 + new_buf = page_address(new_page);
8705 + }
8706 + else
8707 +#endif
8708 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8709 +
8710 + if (unlikely(!new_buf))
8711 + goto netdev_alloc_failed;
8712 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8713 +
8714 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8715 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8716 + if (unlikely(!skb)) {
8717 + put_page(virt_to_head_page(new_buf));
8718 + goto build_skb_failed;
8719 + }
8720 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8721 +
8722 + addr = dma_map_single(dev, new_buf,
8723 + dpa_bp->size, DMA_BIDIRECTIONAL);
8724 + if (unlikely(dma_mapping_error(dev, addr)))
8725 + goto dma_map_failed;
8726 +
8727 + bm_buffer_set64(&bmb[i], addr);
8728 + }
8729 +
8730 +release_bufs:
8731 + /* Release the buffers. In case bman is busy, keep trying
8732 + * until successful. bman_release() is guaranteed to succeed
8733 + * in a reasonable amount of time
8734 + */
8735 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8736 + cpu_relax();
8737 + return i;
8738 +
8739 +dma_map_failed:
8740 + kfree_skb(skb);
8741 +
8742 +build_skb_failed:
8743 +netdev_alloc_failed:
8744 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8745 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8746 +
8747 + bm_buffer_set64(&bmb[i], 0);
8748 + /* Avoid releasing a completely null buffer; bman_release() requires
8749 + * at least one buffer.
8750 + */
8751 + if (likely(i))
8752 + goto release_bufs;
8753 +
8754 + return 0;
8755 +}
8756 +
8757 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8758 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8759 +{
8760 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8761 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8762 +}
8763 +
8764 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8765 +{
8766 + int i;
8767 +
8768 + /* Give each CPU an allotment of "config_count" buffers */
8769 + for_each_possible_cpu(i) {
8770 + int j;
8771 +
8772 + /* Although we access another CPU's counters here
8773 + * we do it at boot time so it is safe
8774 + */
8775 + for (j = 0; j < dpa_bp->config_count; j += 8)
8776 + dpa_bp_add_8_bufs(dpa_bp, i);
8777 + }
8778 + return 0;
8779 +}
8780 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8781 +
8782 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8783 + * REFILL_THRESHOLD.
8784 + */
8785 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8786 +{
8787 + int count = *countptr;
8788 + int new_bufs;
8789 +
8790 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8791 + do {
8792 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8793 + if (unlikely(!new_bufs)) {
8794 + /* Avoid looping forever if we've temporarily
8795 + * run out of memory. We'll try again at the
8796 + * next NAPI cycle.
8797 + */
8798 + break;
8799 + }
8800 + count += new_bufs;
8801 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8802 +
8803 + *countptr = count;
8804 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8805 + return -ENOMEM;
8806 + }
8807 +
8808 + return 0;
8809 +}
8810 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8811 +
8812 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8813 + * either contiguous frames or scatter/gather ones.
8814 + * Skb freeing is not handled here.
8815 + *
8816 + * This function may be called on error paths in the Tx function, so guard
8817 + * against cases when not all fd relevant fields were filled in.
8818 + *
8819 + * Return the skb backpointer, since for S/G frames the buffer containing it
8820 + * gets freed here.
8821 + */
8822 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8823 + const struct qm_fd *fd)
8824 +{
8825 + const struct qm_sg_entry *sgt;
8826 + int i;
8827 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8828 + dma_addr_t addr = qm_fd_addr(fd);
8829 + dma_addr_t sg_addr;
8830 + struct sk_buff **skbh;
8831 + struct sk_buff *skb = NULL;
8832 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8833 + int nr_frags;
8834 + int sg_len;
8835 +
8836 + /* retrieve skb back pointer */
8837 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8838 +
8839 + if (unlikely(fd->format == qm_fd_sg)) {
8840 + nr_frags = skb_shinfo(skb)->nr_frags;
8841 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8842 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8843 + dma_dir);
8844 +
8845 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8846 + * it's from lowmem.
8847 + */
8848 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8849 +#ifdef CONFIG_FSL_DPAA_1588
8850 + if (priv->tsu && priv->tsu->valid &&
8851 + priv->tsu->hwts_tx_en_ioctl)
8852 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8853 +#endif
8854 +#ifdef CONFIG_FSL_DPAA_TS
8855 + if (unlikely(priv->ts_tx_en &&
8856 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8857 + struct skb_shared_hwtstamps shhwtstamps;
8858 +
8859 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8860 + skb_tstamp_tx(skb, &shhwtstamps);
8861 + }
8862 +#endif /* CONFIG_FSL_DPAA_TS */
8863 +
8864 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8865 + sg_addr = qm_sg_addr(&sgt[0]);
8866 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8867 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8868 +
8869 + /* remaining pages were mapped with dma_map_page() */
8870 + for (i = 1; i <= nr_frags; i++) {
8871 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8872 + sg_addr = qm_sg_addr(&sgt[i]);
8873 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8874 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8875 + }
8876 +
8877 + /* Free the page frag that we allocated on Tx */
8878 + put_page(virt_to_head_page(sgt));
8879 + } else {
8880 + dma_unmap_single(dpa_bp->dev, addr,
8881 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8882 +#ifdef CONFIG_FSL_DPAA_TS
8883 + /* get the timestamp for non-SG frames */
8884 +#ifdef CONFIG_FSL_DPAA_1588
8885 + if (priv->tsu && priv->tsu->valid &&
8886 + priv->tsu->hwts_tx_en_ioctl)
8887 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8888 +#endif
8889 + if (unlikely(priv->ts_tx_en &&
8890 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8891 + struct skb_shared_hwtstamps shhwtstamps;
8892 +
8893 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8894 + skb_tstamp_tx(skb, &shhwtstamps);
8895 + }
8896 +#endif
8897 + }
8898 +
8899 + return skb;
8900 +}
8901 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8902 +
8903 +#ifndef CONFIG_FSL_DPAA_TS
8904 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
8905 +{
8906 +#ifndef CONFIG_PPC
8907 + /* Do no recycle skbs realigned by the errata workaround */
8908 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
8909 + return false;
8910 +#endif
8911 +
8912 + /* No recycling possible if skb buffer is kmalloc'ed */
8913 + if (skb->head_frag == 0)
8914 + return false;
8915 +
8916 + /* or if it's an userspace buffer */
8917 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
8918 + return false;
8919 +
8920 + /* or if it's cloned or shared */
8921 + if (skb_shared(skb) || skb_cloned(skb) ||
8922 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
8923 + return false;
8924 +
8925 + return true;
8926 +}
8927 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
8928 +
8929 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
8930 + uint32_t min_size,
8931 + uint16_t min_offset,
8932 + unsigned char **new_buf_start)
8933 +{
8934 + unsigned char *new;
8935 +
8936 + /* In order to recycle a buffer, the following conditions must be met:
8937 + * - buffer size no less than the buffer pool size
8938 + * - buffer size no higher than an upper limit (to avoid moving too much
8939 + * system memory to the buffer pools)
8940 + * - buffer address aligned to cacheline bytes
8941 + * - offset of data from start of buffer no lower than a minimum value
8942 + * - offset of data from start of buffer no higher than a maximum value
8943 + */
8944 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
8945 +
8946 + /* left align to the nearest cacheline */
8947 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
8948 +
8949 + if (likely(new >= skb->head &&
8950 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
8951 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
8952 + *new_buf_start = new;
8953 + return true;
8954 + }
8955 +
8956 + return false;
8957 +}
8958 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
8959 +#endif
8960 +
8961 +/* Build a linear skb around the received buffer.
8962 + * We are guaranteed there is enough room at the end of the data buffer to
8963 + * accommodate the shared info area of the skb.
8964 + */
8965 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
8966 + const struct qm_fd *fd, int *use_gro)
8967 +{
8968 + dma_addr_t addr = qm_fd_addr(fd);
8969 + ssize_t fd_off = dpa_fd_offset(fd);
8970 + void *vaddr;
8971 + const fm_prs_result_t *parse_results;
8972 + struct sk_buff *skb = NULL, **skbh;
8973 +
8974 + vaddr = phys_to_virt(addr);
8975 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8976 +
8977 + /* Retrieve the skb and adjust data and tail pointers, to make sure
8978 + * forwarded skbs will have enough space on Tx if extra headers
8979 + * are added.
8980 + */
8981 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
8982 +
8983 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
8984 + /* When using jumbo Rx buffers, we risk having frames dropped due to
8985 + * the socket backlog reaching its maximum allowed size.
8986 + * Use the frame length for the skb truesize instead of the buffer
8987 + * size, as this is the size of the data that actually gets copied to
8988 + * userspace.
8989 + * The stack may increase the payload. In this case, it will want to
8990 + * warn us that the frame length is larger than the truesize. We
8991 + * bypass the warning.
8992 + */
8993 +#ifndef CONFIG_PPC
8994 + /* We do not support Jumbo frames on LS1043 and thus we edit
8995 + * the skb truesize only when the 4k errata is not present.
8996 + */
8997 + if (likely(!dpaa_errata_a010022))
8998 +#endif
8999 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
9000 +#endif
9001 +
9002 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9003 + skb_reserve(skb, fd_off);
9004 + skb_put(skb, dpa_fd_length(fd));
9005 +
9006 + /* Peek at the parse results for csum validation */
9007 + parse_results = (const fm_prs_result_t *)(vaddr +
9008 + DPA_RX_PRIV_DATA_SIZE);
9009 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
9010 +
9011 +#ifdef CONFIG_FSL_DPAA_1588
9012 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
9013 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9014 +#endif
9015 +#ifdef CONFIG_FSL_DPAA_TS
9016 + if (priv->ts_rx_en)
9017 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9018 +#endif /* CONFIG_FSL_DPAA_TS */
9019 +
9020 + return skb;
9021 +}
9022 +
9023 +
9024 +/* Build an skb with the data of the first S/G entry in the linear portion and
9025 + * the rest of the frame as skb fragments.
9026 + *
9027 + * The page fragment holding the S/G Table is recycled here.
9028 + */
9029 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
9030 + const struct qm_fd *fd, int *use_gro,
9031 + int *count_ptr)
9032 +{
9033 + const struct qm_sg_entry *sgt;
9034 + dma_addr_t addr = qm_fd_addr(fd);
9035 + ssize_t fd_off = dpa_fd_offset(fd);
9036 + dma_addr_t sg_addr;
9037 + void *vaddr, *sg_vaddr;
9038 + struct dpa_bp *dpa_bp;
9039 + struct page *page, *head_page;
9040 + int frag_offset, frag_len;
9041 + int page_offset;
9042 + int i;
9043 + const fm_prs_result_t *parse_results;
9044 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
9045 +
9046 + vaddr = phys_to_virt(addr);
9047 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9048 +
9049 + dpa_bp = priv->dpa_bp;
9050 + /* Iterate through the SGT entries and add data buffers to the skb */
9051 + sgt = vaddr + fd_off;
9052 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9053 + /* Extension bit is not supported */
9054 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9055 +
9056 + /* We use a single global Rx pool */
9057 + DPA_BUG_ON(dpa_bp !=
9058 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9059 +
9060 + sg_addr = qm_sg_addr(&sgt[i]);
9061 + sg_vaddr = phys_to_virt(sg_addr);
9062 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9063 + SMP_CACHE_BYTES));
9064 +
9065 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9066 + DMA_BIDIRECTIONAL);
9067 + if (i == 0) {
9068 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9069 + DPA_BUG_ON(skb->head != sg_vaddr);
9070 +#ifdef CONFIG_FSL_DPAA_1588
9071 + if (priv->tsu && priv->tsu->valid &&
9072 + priv->tsu->hwts_rx_en_ioctl)
9073 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9074 +#endif
9075 +#ifdef CONFIG_FSL_DPAA_TS
9076 + if (priv->ts_rx_en)
9077 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9078 +#endif /* CONFIG_FSL_DPAA_TS */
9079 +
9080 + /* In the case of a SG frame, FMan stores the Internal
9081 + * Context in the buffer containing the sgt.
9082 + * Inspect the parse results before anything else.
9083 + */
9084 + parse_results = (const fm_prs_result_t *)(vaddr +
9085 + DPA_RX_PRIV_DATA_SIZE);
9086 + _dpa_process_parse_results(parse_results, fd, skb,
9087 + use_gro);
9088 +
9089 + /* Make sure forwarded skbs will have enough space
9090 + * on Tx, if extra headers are added.
9091 + */
9092 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9093 + skb_reserve(skb, fd_off);
9094 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9095 + } else {
9096 + /* Not the first S/G entry; all data from buffer will
9097 + * be added in an skb fragment; fragment index is offset
9098 + * by one since first S/G entry was incorporated in the
9099 + * linear part of the skb.
9100 + *
9101 + * Caution: 'page' may be a tail page.
9102 + */
9103 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9104 + page = virt_to_page(sg_vaddr);
9105 + head_page = virt_to_head_page(sg_vaddr);
9106 +
9107 + /* Free (only) the skbuff shell because its data buffer
9108 + * is already a frag in the main skb.
9109 + */
9110 + get_page(head_page);
9111 + dev_kfree_skb(skb_tmp);
9112 +
9113 + /* Compute offset in (possibly tail) page */
9114 + page_offset = ((unsigned long)sg_vaddr &
9115 + (PAGE_SIZE - 1)) +
9116 + (page_address(page) - page_address(head_page));
9117 + /* page_offset only refers to the beginning of sgt[i];
9118 + * but the buffer itself may have an internal offset.
9119 + */
9120 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9121 + page_offset;
9122 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9123 + /* skb_add_rx_frag() does no checking on the page; if
9124 + * we pass it a tail page, we'll end up with
9125 + * bad page accounting and eventually with segafults.
9126 + */
9127 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9128 + frag_len, dpa_bp->size);
9129 + }
9130 + /* Update the pool count for the current {cpu x bpool} */
9131 + (*count_ptr)--;
9132 +
9133 + if (qm_sg_entry_get_final(&sgt[i]))
9134 + break;
9135 + }
9136 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9137 +
9138 + /* recycle the SGT fragment */
9139 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9140 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9141 + return skb;
9142 +}
9143 +
9144 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9145 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9146 + struct sk_buff *skb)
9147 +{
9148 + if (unlikely(priv->loop_to < 0))
9149 + return 0; /* loop disabled by default */
9150 +
9151 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9152 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9153 +
9154 + return 1; /* Frame Tx on the selected interface */
9155 +}
9156 +#endif
9157 +
9158 +void __hot _dpa_rx(struct net_device *net_dev,
9159 + struct qman_portal *portal,
9160 + const struct dpa_priv_s *priv,
9161 + struct dpa_percpu_priv_s *percpu_priv,
9162 + const struct qm_fd *fd,
9163 + u32 fqid,
9164 + int *count_ptr)
9165 +{
9166 + struct dpa_bp *dpa_bp;
9167 + struct sk_buff *skb;
9168 + dma_addr_t addr = qm_fd_addr(fd);
9169 + u32 fd_status = fd->status;
9170 + unsigned int skb_len;
9171 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9172 + int use_gro = net_dev->features & NETIF_F_GRO;
9173 +
9174 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9175 + if (netif_msg_hw(priv) && net_ratelimit())
9176 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9177 + fd_status & FM_FD_STAT_RX_ERRORS);
9178 +
9179 + percpu_stats->rx_errors++;
9180 + goto _release_frame;
9181 + }
9182 +
9183 + dpa_bp = priv->dpa_bp;
9184 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9185 +
9186 + /* prefetch the first 64 bytes of the frame or the SGT start */
9187 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9188 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9189 +
9190 + /* The only FD types that we may receive are contig and S/G */
9191 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9192 +
9193 + if (likely(fd->format == qm_fd_contig)) {
9194 +#ifdef CONFIG_FSL_DPAA_HOOKS
9195 + /* Execute the Rx processing hook, if it exists. */
9196 + if (dpaa_eth_hooks.rx_default &&
9197 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9198 + fqid) == DPAA_ETH_STOLEN) {
9199 + /* won't count the rx bytes in */
9200 + return;
9201 + }
9202 +#endif
9203 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9204 + } else {
9205 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9206 + percpu_priv->rx_sg++;
9207 + }
9208 +
9209 + /* Account for either the contig buffer or the SGT buffer (depending on
9210 + * which case we were in) having been removed from the pool.
9211 + */
9212 + (*count_ptr)--;
9213 + skb->protocol = eth_type_trans(skb, net_dev);
9214 +
9215 + /* IP Reassembled frames are allowed to be larger than MTU */
9216 + if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) &&
9217 + !(fd_status & FM_FD_IPR))) {
9218 + percpu_stats->rx_dropped++;
9219 + goto drop_bad_frame;
9220 + }
9221 +
9222 + skb_len = skb->len;
9223 +
9224 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9225 + if (dpa_skb_loop(priv, skb)) {
9226 + percpu_stats->rx_packets++;
9227 + percpu_stats->rx_bytes += skb_len;
9228 + return;
9229 + }
9230 +#endif
9231 +
9232 + if (use_gro) {
9233 + gro_result_t gro_result;
9234 + const struct qman_portal_config *pc =
9235 + qman_p_get_portal_config(portal);
9236 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9237 +
9238 + np->p = portal;
9239 + gro_result = napi_gro_receive(&np->napi, skb);
9240 + /* If frame is dropped by the stack, rx_dropped counter is
9241 + * incremented automatically, so no need for us to update it
9242 + */
9243 + if (unlikely(gro_result == GRO_DROP))
9244 + goto packet_dropped;
9245 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9246 + goto packet_dropped;
9247 +
9248 + percpu_stats->rx_packets++;
9249 + percpu_stats->rx_bytes += skb_len;
9250 +
9251 +packet_dropped:
9252 + return;
9253 +
9254 +drop_bad_frame:
9255 + dev_kfree_skb(skb);
9256 + return;
9257 +
9258 +_release_frame:
9259 + dpa_fd_release(net_dev, fd);
9260 +}
9261 +
9262 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9263 + struct sk_buff *skb, struct qm_fd *fd,
9264 + int *count_ptr, int *offset)
9265 +{
9266 + struct sk_buff **skbh;
9267 + dma_addr_t addr;
9268 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9269 + struct net_device *net_dev = priv->net_dev;
9270 + int err;
9271 + enum dma_data_direction dma_dir;
9272 + unsigned char *buffer_start;
9273 + int dma_map_size;
9274 +
9275 +#ifndef CONFIG_FSL_DPAA_TS
9276 + /* Check recycling conditions; only if timestamp support is not
9277 + * enabled, otherwise we need the fd back on tx confirmation
9278 + */
9279 +
9280 + /* We can recycle the buffer if:
9281 + * - the pool is not full
9282 + * - the buffer meets the skb recycling conditions
9283 + * - the buffer meets our own (size, offset, align) conditions
9284 + */
9285 + if (likely((*count_ptr < dpa_bp->target_count) &&
9286 + dpa_skb_is_recyclable(skb) &&
9287 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9288 + priv->tx_headroom, &buffer_start))) {
9289 + /* Buffer is recyclable; use the new start address
9290 + * and set fd parameters and DMA mapping direction
9291 + */
9292 + fd->bpid = dpa_bp->bpid;
9293 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9294 + fd->offset = (uint16_t)(skb->data - buffer_start);
9295 + dma_dir = DMA_BIDIRECTIONAL;
9296 + dma_map_size = dpa_bp->size;
9297 +
9298 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9299 + *offset = skb_headroom(skb) - fd->offset;
9300 + } else
9301 +#endif
9302 + {
9303 + /* Not recyclable.
9304 + * We are guaranteed to have at least tx_headroom bytes
9305 + * available, so just use that for offset.
9306 + */
9307 + fd->bpid = 0xff;
9308 + buffer_start = skb->data - priv->tx_headroom;
9309 + fd->offset = priv->tx_headroom;
9310 + dma_dir = DMA_TO_DEVICE;
9311 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9312 +
9313 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9314 + * necessarily look at our Tx private data to retrieve the
9315 + * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.)
9316 + */
9317 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9318 + }
9319 +
9320 + /* Enable L3/L4 hardware checksum computation.
9321 + *
9322 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9323 + * need to write into the skb.
9324 + */
9325 + err = dpa_enable_tx_csum(priv, skb, fd,
9326 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9327 + if (unlikely(err < 0)) {
9328 + if (netif_msg_tx_err(priv) && net_ratelimit())
9329 + netdev_err(net_dev, "HW csum error: %d\n", err);
9330 + return err;
9331 + }
9332 +
9333 + /* Fill in the rest of the FD fields */
9334 + fd->format = qm_fd_contig;
9335 + fd->length20 = skb->len;
9336 + fd->cmd |= FM_FD_CMD_FCO;
9337 +
9338 + /* Map the entire buffer size that may be seen by FMan, but no more */
9339 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9340 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9341 + if (netif_msg_tx_err(priv) && net_ratelimit())
9342 + netdev_err(net_dev, "dma_map_single() failed\n");
9343 + return -EINVAL;
9344 + }
9345 + qm_fd_addr_set64(fd, addr);
9346 +
9347 + return 0;
9348 +}
9349 +EXPORT_SYMBOL(skb_to_contig_fd);
9350 +
9351 +#ifndef CONFIG_PPC
9352 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9353 + * 16 bytes and 4K memory address crossings.
9354 + */
9355 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9356 +{
9357 + int nr_frags, i = 0;
9358 + skb_frag_t *frag;
9359 +
9360 + /* Check if the headroom is aligned */
9361 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9362 + priv->buf_layout[TX].data_align != 0)
9363 + return true;
9364 +
9365 + /* Check if the headroom crosses a boundary */
9366 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9367 + return true;
9368 +
9369 + /* Check if the non-paged data crosses a boundary */
9370 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9371 + return true;
9372 +
9373 + /* Check if the entire linear skb crosses a boundary */
9374 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9375 + return true;
9376 +
9377 + nr_frags = skb_shinfo(skb)->nr_frags;
9378 +
9379 + while (i < nr_frags) {
9380 + frag = &skb_shinfo(skb)->frags[i];
9381 +
9382 + /* Check if a paged fragment crosses a boundary from its
9383 + * offset to its end.
9384 + */
9385 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9386 + return true;
9387 +
9388 + i++;
9389 + }
9390 +
9391 + return false;
9392 +}
9393 +
9394 +/* Realign the skb by copying its contents at the start of a newly allocated
9395 + * page. Build a new skb around the new buffer and release the old one.
9396 + * A performance drop should be expected.
9397 + */
9398 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9399 + struct dpa_priv_s *priv)
9400 +{
9401 + int trans_offset = skb_transport_offset(skb);
9402 + int net_offset = skb_network_offset(skb);
9403 + struct sk_buff *nskb = NULL;
9404 + int nsize, headroom;
9405 + struct page *npage;
9406 + void *npage_addr;
9407 +
9408 + /* Guarantee the minimum required headroom */
9409 + if (skb_headroom(skb) >= priv->tx_headroom)
9410 + headroom = skb_headroom(skb);
9411 + else
9412 + headroom = priv->tx_headroom;
9413 +
9414 + npage = alloc_page(GFP_ATOMIC);
9415 + if (unlikely(!npage)) {
9416 + WARN_ONCE(1, "Memory allocation failure\n");
9417 + return NULL;
9418 + }
9419 + npage_addr = page_address(npage);
9420 +
9421 + /* For the new skb we only need the old one's data (both non-paged and
9422 + * paged) and a headroom large enough to fit our private info. We can
9423 + * skip the old tailroom.
9424 + *
9425 + * Make sure the new linearized buffer will not exceed a page's size.
9426 + */
9427 + nsize = headroom + skb->len +
9428 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9429 + if (unlikely(nsize > 4096))
9430 + goto err;
9431 +
9432 + nskb = build_skb(npage_addr, nsize);
9433 + if (unlikely(!nskb))
9434 + goto err;
9435 +
9436 + /* Reserve only the needed headroom in order to guarantee the data's
9437 + * alignment.
9438 + * Code borrowed and adapted from skb_copy().
9439 + */
9440 + skb_reserve(nskb, priv->tx_headroom);
9441 + skb_put(nskb, skb->len);
9442 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9443 + WARN_ONCE(1, "skb parsing failure\n");
9444 + goto err;
9445 + }
9446 + copy_skb_header(nskb, skb);
9447 +
9448 +#ifdef CONFIG_FSL_DPAA_TS
9449 + /* Copy relevant timestamp info from the old skb to the new */
9450 + if (priv->ts_tx_en) {
9451 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9452 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9453 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9454 + if (skb->sk)
9455 + skb_set_owner_w(nskb, skb->sk);
9456 + }
9457 +#endif
9458 + /* We move the headroom when we align it so we have to reset the
9459 + * network and transport header offsets relative to the new data
9460 + * pointer. The checksum offload relies on these offsets.
9461 + */
9462 + skb_set_network_header(nskb, net_offset);
9463 + skb_set_transport_header(nskb, trans_offset);
9464 +
9465 + /* We don't want the buffer to be recycled so we mark it accordingly */
9466 + nskb->mark = NONREC_MARK;
9467 +
9468 + dev_kfree_skb(skb);
9469 + return nskb;
9470 +
9471 +err:
9472 + if (nskb)
9473 + dev_kfree_skb(nskb);
9474 + put_page(npage);
9475 + return NULL;
9476 +}
9477 +#endif
9478 +
9479 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9480 + struct sk_buff *skb, struct qm_fd *fd)
9481 +{
9482 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9483 + dma_addr_t addr;
9484 + dma_addr_t sg_addr;
9485 + struct sk_buff **skbh;
9486 + struct net_device *net_dev = priv->net_dev;
9487 + int sg_len, sgt_size;
9488 + int err;
9489 +
9490 + struct qm_sg_entry *sgt;
9491 + void *sgt_buf;
9492 + skb_frag_t *frag;
9493 + int i = 0, j = 0;
9494 + int nr_frags;
9495 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9496 +
9497 + nr_frags = skb_shinfo(skb)->nr_frags;
9498 + fd->format = qm_fd_sg;
9499 +
9500 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9501 +
9502 + /* Get a page frag to store the SGTable, or a full page if the errata
9503 + * is in place and we need to avoid crossing a 4k boundary.
9504 + */
9505 +#ifndef CONFIG_PPC
9506 + if (unlikely(dpaa_errata_a010022))
9507 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9508 + else
9509 +#endif
9510 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9511 + if (unlikely(!sgt_buf)) {
9512 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9513 + return -ENOMEM;
9514 + }
9515 +
9516 + /* it seems that the memory allocator does not zero the allocated mem */
9517 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9518 +
9519 + /* Enable L3/L4 hardware checksum computation.
9520 + *
9521 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9522 + * need to write into the skb.
9523 + */
9524 + err = dpa_enable_tx_csum(priv, skb, fd,
9525 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9526 + if (unlikely(err < 0)) {
9527 + if (netif_msg_tx_err(priv) && net_ratelimit())
9528 + netdev_err(net_dev, "HW csum error: %d\n", err);
9529 + goto csum_failed;
9530 + }
9531 +
9532 + /* Assign the data from skb->data to the first SG list entry */
9533 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9534 + sg_len = skb_headlen(skb);
9535 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9536 + qm_sg_entry_set_offset(&sgt[0], 0);
9537 + qm_sg_entry_set_len(&sgt[0], sg_len);
9538 + qm_sg_entry_set_ext(&sgt[0], 0);
9539 + qm_sg_entry_set_final(&sgt[0], 0);
9540 +
9541 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9542 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9543 + dev_err(dpa_bp->dev, "DMA mapping failed");
9544 + err = -EINVAL;
9545 + goto sg0_map_failed;
9546 + }
9547 +
9548 + qm_sg_entry_set64(&sgt[0], addr);
9549 +
9550 + /* populate the rest of SGT entries */
9551 + for (i = 1; i <= nr_frags; i++) {
9552 + frag = &skb_shinfo(skb)->frags[i - 1];
9553 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9554 + qm_sg_entry_set_offset(&sgt[i], 0);
9555 + qm_sg_entry_set_len(&sgt[i], frag->size);
9556 + qm_sg_entry_set_ext(&sgt[i], 0);
9557 +
9558 + if (i == nr_frags)
9559 + qm_sg_entry_set_final(&sgt[i], 1);
9560 + else
9561 + qm_sg_entry_set_final(&sgt[i], 0);
9562 +
9563 + DPA_BUG_ON(!skb_frag_page(frag));
9564 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9565 + dma_dir);
9566 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9567 + dev_err(dpa_bp->dev, "DMA mapping failed");
9568 + err = -EINVAL;
9569 + goto sg_map_failed;
9570 + }
9571 +
9572 + /* keep the offset in the address */
9573 + qm_sg_entry_set64(&sgt[i], addr);
9574 + }
9575 +
9576 + fd->length20 = skb->len;
9577 + fd->offset = priv->tx_headroom;
9578 +
9579 + /* DMA map the SGT page */
9580 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9581 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9582 + priv->tx_headroom + sgt_size,
9583 + dma_dir);
9584 +
9585 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9586 + dev_err(dpa_bp->dev, "DMA mapping failed");
9587 + err = -EINVAL;
9588 + goto sgt_map_failed;
9589 + }
9590 +
9591 + qm_fd_addr_set64(fd, addr);
9592 + fd->bpid = 0xff;
9593 + fd->cmd |= FM_FD_CMD_FCO;
9594 +
9595 + return 0;
9596 +
9597 +sgt_map_failed:
9598 +sg_map_failed:
9599 + for (j = 0; j < i; j++) {
9600 + sg_addr = qm_sg_addr(&sgt[j]);
9601 + dma_unmap_page(dpa_bp->dev, sg_addr,
9602 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9603 + }
9604 +sg0_map_failed:
9605 +csum_failed:
9606 + put_page(virt_to_head_page(sgt_buf));
9607 +
9608 + return err;
9609 +}
9610 +EXPORT_SYMBOL(skb_to_sg_fd);
9611 +
9612 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9613 +{
9614 + struct dpa_priv_s *priv;
9615 + const int queue_mapping = dpa_get_queue_mapping(skb);
9616 + struct qman_fq *egress_fq, *conf_fq;
9617 +
9618 +#ifdef CONFIG_FSL_DPAA_HOOKS
9619 + /* If there is a Tx hook, run it. */
9620 + if (dpaa_eth_hooks.tx &&
9621 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9622 + /* won't update any Tx stats */
9623 + return NETDEV_TX_OK;
9624 +#endif
9625 +
9626 + priv = netdev_priv(net_dev);
9627 +
9628 +#ifdef CONFIG_FSL_DPAA_CEETM
9629 + if (priv->ceetm_en)
9630 + return ceetm_tx(skb, net_dev);
9631 +#endif
9632 +
9633 + egress_fq = priv->egress_fqs[queue_mapping];
9634 + conf_fq = priv->conf_fqs[queue_mapping];
9635 +
9636 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9637 +}
9638 +
9639 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9640 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9641 +{
9642 + struct dpa_priv_s *priv;
9643 + struct qm_fd fd;
9644 + struct dpa_percpu_priv_s *percpu_priv;
9645 + struct rtnl_link_stats64 *percpu_stats;
9646 + int err = 0;
9647 + bool nonlinear;
9648 + int *countptr, offset = 0;
9649 +
9650 + priv = netdev_priv(net_dev);
9651 + /* Non-migratable context, safe to use raw_cpu_ptr */
9652 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9653 + percpu_stats = &percpu_priv->stats;
9654 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9655 +
9656 + clear_fd(&fd);
9657 +
9658 +#ifndef CONFIG_PPC
9659 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9660 + skb = a010022_realign_skb(skb, priv);
9661 + if (!skb)
9662 + goto skb_to_fd_failed;
9663 + }
9664 +#endif
9665 +
9666 + nonlinear = skb_is_nonlinear(skb);
9667 +
9668 +#ifdef CONFIG_FSL_DPAA_1588
9669 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9670 + fd.cmd |= FM_FD_CMD_UPD;
9671 +#endif
9672 +#ifdef CONFIG_FSL_DPAA_TS
9673 + if (unlikely(priv->ts_tx_en &&
9674 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9675 + fd.cmd |= FM_FD_CMD_UPD;
9676 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9677 +#endif /* CONFIG_FSL_DPAA_TS */
9678 +
9679 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9680 + * we don't feed FMan with more fragments than it supports.
9681 + * Btw, we're using the first sgt entry to store the linear part of
9682 + * the skb, so we're one extra frag short.
9683 + */
9684 + if (nonlinear &&
9685 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9686 + /* Just create a S/G fd based on the skb */
9687 + err = skb_to_sg_fd(priv, skb, &fd);
9688 + percpu_priv->tx_frag_skbuffs++;
9689 + } else {
9690 + /* Make sure we have enough headroom to accommodate private
9691 + * data, parse results, etc. Normally this shouldn't happen if
9692 + * we're here via the standard kernel stack.
9693 + */
9694 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9695 + struct sk_buff *skb_new;
9696 +
9697 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9698 + if (unlikely(!skb_new)) {
9699 + dev_kfree_skb(skb);
9700 + percpu_stats->tx_errors++;
9701 + return NETDEV_TX_OK;
9702 + }
9703 + dev_kfree_skb(skb);
9704 + skb = skb_new;
9705 + }
9706 +
9707 + /* We're going to store the skb backpointer at the beginning
9708 + * of the data buffer, so we need a privately owned skb
9709 + */
9710 +
9711 + /* Code borrowed from skb_unshare(). */
9712 + if (skb_cloned(skb)) {
9713 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9714 + kfree_skb(skb);
9715 + skb = nskb;
9716 +#ifndef CONFIG_PPC
9717 + if (unlikely(dpaa_errata_a010022) &&
9718 + a010022_check_skb(skb, priv)) {
9719 + skb = a010022_realign_skb(skb, priv);
9720 + if (!skb)
9721 + goto skb_to_fd_failed;
9722 + }
9723 +#endif
9724 + /* skb_copy() has now linearized the skbuff. */
9725 + } else if (unlikely(nonlinear)) {
9726 + /* We are here because the egress skb contains
9727 + * more fragments than we support. In this case,
9728 + * we have no choice but to linearize it ourselves.
9729 + */
9730 + err = __skb_linearize(skb);
9731 + }
9732 + if (unlikely(!skb || err < 0))
9733 + /* Common out-of-memory error path */
9734 + goto enomem;
9735 +
9736 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9737 + }
9738 + if (unlikely(err < 0))
9739 + goto skb_to_fd_failed;
9740 +
9741 + if (fd.bpid != 0xff) {
9742 + skb_recycle(skb);
9743 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9744 + * but we need the skb to look as if returned by build_skb().
9745 + * We need to manually adjust the tailptr as well.
9746 + */
9747 + skb->data = skb->head + offset;
9748 + skb_reset_tail_pointer(skb);
9749 +
9750 + (*countptr)++;
9751 + percpu_priv->tx_returned++;
9752 + }
9753 +
9754 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9755 + goto xmit_failed;
9756 +
9757 + netif_trans_update(net_dev);
9758 + return NETDEV_TX_OK;
9759 +
9760 +xmit_failed:
9761 + if (fd.bpid != 0xff) {
9762 + (*countptr)--;
9763 + percpu_priv->tx_returned--;
9764 + dpa_fd_release(net_dev, &fd);
9765 + percpu_stats->tx_errors++;
9766 + return NETDEV_TX_OK;
9767 + }
9768 + _dpa_cleanup_tx_fd(priv, &fd);
9769 +skb_to_fd_failed:
9770 +enomem:
9771 + percpu_stats->tx_errors++;
9772 + dev_kfree_skb(skb);
9773 + return NETDEV_TX_OK;
9774 +}
9775 +EXPORT_SYMBOL(dpa_tx_extended);
9776 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9777 new file mode 100644
9778 index 00000000..3542d0b2
9779 --- /dev/null
9780 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9781 @@ -0,0 +1,278 @@
9782 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9783 + *
9784 + * Redistribution and use in source and binary forms, with or without
9785 + * modification, are permitted provided that the following conditions are met:
9786 + * * Redistributions of source code must retain the above copyright
9787 + * notice, this list of conditions and the following disclaimer.
9788 + * * Redistributions in binary form must reproduce the above copyright
9789 + * notice, this list of conditions and the following disclaimer in the
9790 + * documentation and/or other materials provided with the distribution.
9791 + * * Neither the name of Freescale Semiconductor nor the
9792 + * names of its contributors may be used to endorse or promote products
9793 + * derived from this software without specific prior written permission.
9794 + *
9795 + *
9796 + * ALTERNATIVELY, this software may be distributed under the terms of the
9797 + * GNU General Public License ("GPL") as published by the Free Software
9798 + * Foundation, either version 2 of that License or (at your option) any
9799 + * later version.
9800 + *
9801 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9802 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9803 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9804 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9805 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9806 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9807 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9808 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9809 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9810 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9811 + */
9812 +
9813 +#include <linux/init.h>
9814 +#include <linux/module.h>
9815 +#include <linux/kthread.h>
9816 +#include <linux/io.h>
9817 +#include <linux/of_net.h>
9818 +#include "dpaa_eth.h"
9819 +#include "mac.h" /* struct mac_device */
9820 +#ifdef CONFIG_FSL_DPAA_1588
9821 +#include "dpaa_1588.h"
9822 +#endif
9823 +
9824 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9825 + struct device_attribute *attr, char *buf)
9826 +{
9827 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9828 + struct mac_device *mac_dev = priv->mac_dev;
9829 +
9830 + if (mac_dev)
9831 + return sprintf(buf, "%llx",
9832 + (unsigned long long)mac_dev->res->start);
9833 + else
9834 + return sprintf(buf, "none");
9835 +}
9836 +
9837 +static ssize_t dpaa_eth_show_type(struct device *dev,
9838 + struct device_attribute *attr, char *buf)
9839 +{
9840 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9841 + ssize_t res = 0;
9842 +
9843 + if (priv)
9844 + res = sprintf(buf, "%s", priv->if_type);
9845 +
9846 + return res;
9847 +}
9848 +
9849 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9850 + struct device_attribute *attr, char *buf)
9851 +{
9852 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9853 + ssize_t bytes = 0;
9854 + int i = 0;
9855 + char *str;
9856 + struct dpa_fq *fq;
9857 + struct dpa_fq *tmp;
9858 + struct dpa_fq *prev = NULL;
9859 + u32 first_fqid = 0;
9860 + u32 last_fqid = 0;
9861 + char *prevstr = NULL;
9862 +
9863 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9864 + switch (fq->fq_type) {
9865 + case FQ_TYPE_RX_DEFAULT:
9866 + str = "Rx default";
9867 + break;
9868 + case FQ_TYPE_RX_ERROR:
9869 + str = "Rx error";
9870 + break;
9871 + case FQ_TYPE_RX_PCD:
9872 + str = "Rx PCD";
9873 + break;
9874 + case FQ_TYPE_TX_CONFIRM:
9875 + str = "Tx default confirmation";
9876 + break;
9877 + case FQ_TYPE_TX_CONF_MQ:
9878 + str = "Tx confirmation (mq)";
9879 + break;
9880 + case FQ_TYPE_TX_ERROR:
9881 + str = "Tx error";
9882 + break;
9883 + case FQ_TYPE_TX:
9884 + str = "Tx";
9885 + break;
9886 + case FQ_TYPE_RX_PCD_HI_PRIO:
9887 + str ="Rx PCD High Priority";
9888 + break;
9889 + default:
9890 + str = "Unknown";
9891 + }
9892 +
9893 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9894 + str != prevstr)) {
9895 + if (last_fqid == first_fqid)
9896 + bytes += sprintf(buf + bytes,
9897 + "%s: %d\n", prevstr, prev->fqid);
9898 + else
9899 + bytes += sprintf(buf + bytes,
9900 + "%s: %d - %d\n", prevstr,
9901 + first_fqid, last_fqid);
9902 + }
9903 +
9904 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
9905 + last_fqid = fq->fqid;
9906 + else
9907 + first_fqid = last_fqid = fq->fqid;
9908 +
9909 + prev = fq;
9910 + prevstr = str;
9911 + i++;
9912 + }
9913 +
9914 + if (prev) {
9915 + if (last_fqid == first_fqid)
9916 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
9917 + prev->fqid);
9918 + else
9919 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
9920 + first_fqid, last_fqid);
9921 + }
9922 +
9923 + return bytes;
9924 +}
9925 +
9926 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
9927 + struct device_attribute *attr, char *buf)
9928 +{
9929 + ssize_t bytes = 0;
9930 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9931 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9932 + int i = 0;
9933 +
9934 + for (i = 0; i < priv->bp_count; i++)
9935 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
9936 + dpa_bp[i].bpid);
9937 +
9938 + return bytes;
9939 +}
9940 +
9941 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
9942 + struct device_attribute *attr, char *buf)
9943 +{
9944 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9945 + struct mac_device *mac_dev = priv->mac_dev;
9946 + int n = 0;
9947 +
9948 + if (mac_dev)
9949 + n = fm_mac_dump_regs(mac_dev, buf, n);
9950 + else
9951 + return sprintf(buf, "no mac registers\n");
9952 +
9953 + return n;
9954 +}
9955 +
9956 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
9957 + struct device_attribute *attr, char *buf)
9958 +{
9959 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9960 + struct mac_device *mac_dev = priv->mac_dev;
9961 + int n = 0;
9962 +
9963 + if (mac_dev)
9964 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
9965 + else
9966 + return sprintf(buf, "no mac rx stats\n");
9967 +
9968 + return n;
9969 +}
9970 +
9971 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
9972 + struct device_attribute *attr, char *buf)
9973 +{
9974 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9975 + struct mac_device *mac_dev = priv->mac_dev;
9976 + int n = 0;
9977 +
9978 + if (mac_dev)
9979 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
9980 + else
9981 + return sprintf(buf, "no mac tx stats\n");
9982 +
9983 + return n;
9984 +}
9985 +
9986 +#ifdef CONFIG_FSL_DPAA_1588
9987 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
9988 + struct device_attribute *attr, char *buf)
9989 +{
9990 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9991 +
9992 + if (priv->tsu && priv->tsu->valid)
9993 + return sprintf(buf, "1\n");
9994 + else
9995 + return sprintf(buf, "0\n");
9996 +}
9997 +
9998 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
9999 + struct device_attribute *attr,
10000 + const char *buf, size_t count)
10001 +{
10002 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10003 + unsigned int num;
10004 + unsigned long flags;
10005 +
10006 + if (kstrtouint(buf, 0, &num) < 0)
10007 + return -EINVAL;
10008 +
10009 + local_irq_save(flags);
10010 +
10011 + if (num) {
10012 + if (priv->tsu)
10013 + priv->tsu->valid = TRUE;
10014 + } else {
10015 + if (priv->tsu)
10016 + priv->tsu->valid = FALSE;
10017 + }
10018 +
10019 + local_irq_restore(flags);
10020 +
10021 + return count;
10022 +}
10023 +#endif
10024 +
10025 +static struct device_attribute dpaa_eth_attrs[] = {
10026 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
10027 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
10028 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
10029 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
10030 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
10031 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
10032 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
10033 +#ifdef CONFIG_FSL_DPAA_1588
10034 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
10035 + dpaa_eth_set_ptp_1588),
10036 +#endif
10037 +};
10038 +
10039 +void dpaa_eth_sysfs_init(struct device *dev)
10040 +{
10041 + int i;
10042 +
10043 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10044 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
10045 + dev_err(dev, "Error creating sysfs file\n");
10046 + while (i > 0)
10047 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
10048 + return;
10049 + }
10050 +}
10051 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
10052 +
10053 +void dpaa_eth_sysfs_remove(struct device *dev)
10054 +{
10055 + int i;
10056 +
10057 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10058 + device_remove_file(dev, &dpaa_eth_attrs[i]);
10059 +}
10060 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10061 new file mode 100644
10062 index 00000000..30069ef9
10063 --- /dev/null
10064 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10065 @@ -0,0 +1,144 @@
10066 +/* Copyright 2013 Freescale Semiconductor Inc.
10067 + *
10068 + * Redistribution and use in source and binary forms, with or without
10069 + * modification, are permitted provided that the following conditions are met:
10070 + * * Redistributions of source code must retain the above copyright
10071 + * notice, this list of conditions and the following disclaimer.
10072 + * * Redistributions in binary form must reproduce the above copyright
10073 + * notice, this list of conditions and the following disclaimer in the
10074 + * documentation and/or other materials provided with the distribution.
10075 + * * Neither the name of Freescale Semiconductor nor the
10076 + * names of its contributors may be used to endorse or promote products
10077 + * derived from this software without specific prior written permission.
10078 + *
10079 + *
10080 + * ALTERNATIVELY, this software may be distributed under the terms of the
10081 + * GNU General Public License ("GPL") as published by the Free Software
10082 + * Foundation, either version 2 of that License or (at your option) any
10083 + * later version.
10084 + *
10085 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10086 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10087 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10088 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10089 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10090 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10091 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10092 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10093 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10094 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10095 + */
10096 +
10097 +#undef TRACE_SYSTEM
10098 +#define TRACE_SYSTEM dpaa_eth
10099 +
10100 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10101 +#define _DPAA_ETH_TRACE_H
10102 +
10103 +#include <linux/skbuff.h>
10104 +#include <linux/netdevice.h>
10105 +#include "dpaa_eth.h"
10106 +#include <linux/tracepoint.h>
10107 +
10108 +#define fd_format_name(format) { qm_fd_##format, #format }
10109 +#define fd_format_list \
10110 + fd_format_name(contig), \
10111 + fd_format_name(sg)
10112 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10113 + " status=0x%08x"
10114 +
10115 +/* This is used to declare a class of events.
10116 + * individual events of this type will be defined below.
10117 + */
10118 +
10119 +/* Store details about a frame descriptor and the FQ on which it was
10120 + * transmitted/received.
10121 + */
10122 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10123 + /* Trace function prototype */
10124 + TP_PROTO(struct net_device *netdev,
10125 + struct qman_fq *fq,
10126 + const struct qm_fd *fd),
10127 +
10128 + /* Repeat argument list here */
10129 + TP_ARGS(netdev, fq, fd),
10130 +
10131 + /* A structure containing the relevant information we want to record.
10132 + * Declare name and type for each normal element, name, type and size
10133 + * for arrays. Use __string for variable length strings.
10134 + */
10135 + TP_STRUCT__entry(
10136 + __field(u32, fqid)
10137 + __field(u64, fd_addr)
10138 + __field(u8, fd_format)
10139 + __field(u16, fd_offset)
10140 + __field(u32, fd_length)
10141 + __field(u32, fd_status)
10142 + __string(name, netdev->name)
10143 + ),
10144 +
10145 + /* The function that assigns values to the above declared fields */
10146 + TP_fast_assign(
10147 + __entry->fqid = fq->fqid;
10148 + __entry->fd_addr = qm_fd_addr_get64(fd);
10149 + __entry->fd_format = fd->format;
10150 + __entry->fd_offset = dpa_fd_offset(fd);
10151 + __entry->fd_length = dpa_fd_length(fd);
10152 + __entry->fd_status = fd->status;
10153 + __assign_str(name, netdev->name);
10154 + ),
10155 +
10156 + /* This is what gets printed when the trace event is triggered */
10157 + /* TODO: print the status using __print_flags() */
10158 + TP_printk(TR_FMT,
10159 + __get_str(name), __entry->fqid, __entry->fd_addr,
10160 + __print_symbolic(__entry->fd_format, fd_format_list),
10161 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10162 +);
10163 +
10164 +/* Now declare events of the above type. Format is:
10165 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10166 + */
10167 +
10168 +/* Tx (egress) fd */
10169 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10170 +
10171 + TP_PROTO(struct net_device *netdev,
10172 + struct qman_fq *fq,
10173 + const struct qm_fd *fd),
10174 +
10175 + TP_ARGS(netdev, fq, fd)
10176 +);
10177 +
10178 +/* Rx fd */
10179 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10180 +
10181 + TP_PROTO(struct net_device *netdev,
10182 + struct qman_fq *fq,
10183 + const struct qm_fd *fd),
10184 +
10185 + TP_ARGS(netdev, fq, fd)
10186 +);
10187 +
10188 +/* Tx confirmation fd */
10189 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10190 +
10191 + TP_PROTO(struct net_device *netdev,
10192 + struct qman_fq *fq,
10193 + const struct qm_fd *fd),
10194 +
10195 + TP_ARGS(netdev, fq, fd)
10196 +);
10197 +
10198 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10199 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10200 + */
10201 +
10202 +#endif /* _DPAA_ETH_TRACE_H */
10203 +
10204 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10205 +#undef TRACE_INCLUDE_PATH
10206 +#define TRACE_INCLUDE_PATH .
10207 +#undef TRACE_INCLUDE_FILE
10208 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10209 +#include <trace/define_trace.h>
10210 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10211 new file mode 100644
10212 index 00000000..4b784662
10213 --- /dev/null
10214 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10215 @@ -0,0 +1,544 @@
10216 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10217 + *
10218 + * Redistribution and use in source and binary forms, with or without
10219 + * modification, are permitted provided that the following conditions are met:
10220 + * * Redistributions of source code must retain the above copyright
10221 + * notice, this list of conditions and the following disclaimer.
10222 + * * Redistributions in binary form must reproduce the above copyright
10223 + * notice, this list of conditions and the following disclaimer in the
10224 + * documentation and/or other materials provided with the distribution.
10225 + * * Neither the name of Freescale Semiconductor nor the
10226 + * names of its contributors may be used to endorse or promote products
10227 + * derived from this software without specific prior written permission.
10228 + *
10229 + *
10230 + * ALTERNATIVELY, this software may be distributed under the terms of the
10231 + * GNU General Public License ("GPL") as published by the Free Software
10232 + * Foundation, either version 2 of that License or (at your option) any
10233 + * later version.
10234 + *
10235 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10236 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10237 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10238 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10239 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10240 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10241 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10242 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10243 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10244 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10245 + */
10246 +
10247 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10248 +#define pr_fmt(fmt) \
10249 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10250 + KBUILD_BASENAME".c", __LINE__, __func__
10251 +#else
10252 +#define pr_fmt(fmt) \
10253 + KBUILD_MODNAME ": " fmt
10254 +#endif
10255 +
10256 +#include <linux/string.h>
10257 +
10258 +#include "dpaa_eth.h"
10259 +#include "mac.h" /* struct mac_device */
10260 +#include "dpaa_eth_common.h"
10261 +
10262 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10263 + "interrupts",
10264 + "rx packets",
10265 + "tx packets",
10266 + "tx recycled",
10267 + "tx confirm",
10268 + "tx S/G",
10269 + "rx S/G",
10270 + "tx error",
10271 + "rx error",
10272 + "bp count"
10273 +};
10274 +
10275 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10276 + /* dpa rx errors */
10277 + "rx dma error",
10278 + "rx frame physical error",
10279 + "rx frame size error",
10280 + "rx header error",
10281 + "rx csum error",
10282 +
10283 + /* demultiplexing errors */
10284 + "qman cg_tdrop",
10285 + "qman wred",
10286 + "qman error cond",
10287 + "qman early window",
10288 + "qman late window",
10289 + "qman fq tdrop",
10290 + "qman fq retired",
10291 + "qman orp disabled",
10292 +
10293 + /* congestion related stats */
10294 + "congestion time (ms)",
10295 + "entered congestion",
10296 + "congested (0/1)"
10297 +};
10298 +
10299 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10300 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10301 +
10302 +static int __cold dpa_get_settings(struct net_device *net_dev,
10303 + struct ethtool_cmd *et_cmd)
10304 +{
10305 + int _errno;
10306 + struct dpa_priv_s *priv;
10307 +
10308 + priv = netdev_priv(net_dev);
10309 +
10310 + if (priv->mac_dev == NULL) {
10311 + netdev_info(net_dev, "This is a MAC-less interface\n");
10312 + return -ENODEV;
10313 + }
10314 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10315 + netdev_dbg(net_dev, "phy device not initialized\n");
10316 + return 0;
10317 + }
10318 +
10319 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10320 + if (unlikely(_errno < 0))
10321 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10322 +
10323 + return _errno;
10324 +}
10325 +
10326 +static int __cold dpa_set_settings(struct net_device *net_dev,
10327 + struct ethtool_cmd *et_cmd)
10328 +{
10329 + int _errno;
10330 + struct dpa_priv_s *priv;
10331 +
10332 + priv = netdev_priv(net_dev);
10333 +
10334 + if (priv->mac_dev == NULL) {
10335 + netdev_info(net_dev, "This is a MAC-less interface\n");
10336 + return -ENODEV;
10337 + }
10338 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10339 + netdev_err(net_dev, "phy device not initialized\n");
10340 + return -ENODEV;
10341 + }
10342 +
10343 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10344 + if (unlikely(_errno < 0))
10345 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10346 +
10347 + return _errno;
10348 +}
10349 +
10350 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10351 + struct ethtool_drvinfo *drvinfo)
10352 +{
10353 + int _errno;
10354 +
10355 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10356 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10357 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10358 + "%X", 0);
10359 +
10360 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10361 + /* Truncated output */
10362 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10363 + } else if (unlikely(_errno < 0)) {
10364 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10365 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10366 + }
10367 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10368 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10369 +}
10370 +
10371 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10372 +{
10373 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10374 +}
10375 +
10376 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10377 + uint32_t msg_enable)
10378 +{
10379 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10380 +}
10381 +
10382 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10383 +{
10384 + int _errno;
10385 + struct dpa_priv_s *priv;
10386 +
10387 + priv = netdev_priv(net_dev);
10388 +
10389 + if (priv->mac_dev == NULL) {
10390 + netdev_info(net_dev, "This is a MAC-less interface\n");
10391 + return -ENODEV;
10392 + }
10393 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10394 + netdev_err(net_dev, "phy device not initialized\n");
10395 + return -ENODEV;
10396 + }
10397 +
10398 + _errno = 0;
10399 + if (priv->mac_dev->phy_dev->autoneg) {
10400 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10401 + if (unlikely(_errno < 0))
10402 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10403 + _errno);
10404 + }
10405 +
10406 + return _errno;
10407 +}
10408 +
10409 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10410 + struct ethtool_pauseparam *epause)
10411 +{
10412 + struct dpa_priv_s *priv;
10413 + struct mac_device *mac_dev;
10414 + struct phy_device *phy_dev;
10415 +
10416 + priv = netdev_priv(net_dev);
10417 + mac_dev = priv->mac_dev;
10418 +
10419 + if (mac_dev == NULL) {
10420 + netdev_info(net_dev, "This is a MAC-less interface\n");
10421 + return;
10422 + }
10423 +
10424 + phy_dev = mac_dev->phy_dev;
10425 + if (unlikely(phy_dev == NULL)) {
10426 + netdev_err(net_dev, "phy device not initialized\n");
10427 + return;
10428 + }
10429 +
10430 + epause->autoneg = mac_dev->autoneg_pause;
10431 + epause->rx_pause = mac_dev->rx_pause_active;
10432 + epause->tx_pause = mac_dev->tx_pause_active;
10433 +}
10434 +
10435 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10436 + struct ethtool_pauseparam *epause)
10437 +{
10438 + struct dpa_priv_s *priv;
10439 + struct mac_device *mac_dev;
10440 + struct phy_device *phy_dev;
10441 + int _errno;
10442 + u32 newadv, oldadv;
10443 + bool rx_pause, tx_pause;
10444 +
10445 + priv = netdev_priv(net_dev);
10446 + mac_dev = priv->mac_dev;
10447 +
10448 + if (mac_dev == NULL) {
10449 + netdev_info(net_dev, "This is a MAC-less interface\n");
10450 + return -ENODEV;
10451 + }
10452 +
10453 + phy_dev = mac_dev->phy_dev;
10454 + if (unlikely(phy_dev == NULL)) {
10455 + netdev_err(net_dev, "phy device not initialized\n");
10456 + return -ENODEV;
10457 + }
10458 +
10459 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10460 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10461 + (epause->rx_pause != epause->tx_pause)))
10462 + return -EINVAL;
10463 +
10464 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10465 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10466 + * settings.
10467 + */
10468 + mac_dev->autoneg_pause = !!epause->autoneg;
10469 + mac_dev->rx_pause_req = !!epause->rx_pause;
10470 + mac_dev->tx_pause_req = !!epause->tx_pause;
10471 +
10472 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10473 + * rx/tx pause settings.
10474 + */
10475 + newadv = 0;
10476 + if (epause->rx_pause)
10477 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10478 + if (epause->tx_pause)
10479 + newadv |= ADVERTISED_Asym_Pause;
10480 +
10481 + oldadv = phy_dev->advertising &
10482 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10483 +
10484 + /* If there are differences between the old and the new advertised
10485 + * values, restart PHY autonegotiation and advertise the new values.
10486 + */
10487 + if (oldadv != newadv) {
10488 + phy_dev->advertising &= ~(ADVERTISED_Pause
10489 + | ADVERTISED_Asym_Pause);
10490 + phy_dev->advertising |= newadv;
10491 + if (phy_dev->autoneg) {
10492 + _errno = phy_start_aneg(phy_dev);
10493 + if (unlikely(_errno < 0))
10494 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10495 + _errno);
10496 + }
10497 + }
10498 +
10499 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10500 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10501 + if (unlikely(_errno < 0))
10502 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10503 +
10504 + return _errno;
10505 +}
10506 +
10507 +#ifdef CONFIG_PM
10508 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10509 +{
10510 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10511 +
10512 + wol->supported = 0;
10513 + wol->wolopts = 0;
10514 +
10515 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10516 + return;
10517 +
10518 + if (priv->wol & DPAA_WOL_MAGIC) {
10519 + wol->supported = WAKE_MAGIC;
10520 + wol->wolopts = WAKE_MAGIC;
10521 + }
10522 +}
10523 +
10524 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10525 +{
10526 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10527 +
10528 + if (priv->mac_dev == NULL) {
10529 + netdev_info(net_dev, "This is a MAC-less interface\n");
10530 + return -ENODEV;
10531 + }
10532 +
10533 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10534 + netdev_dbg(net_dev, "phy device not initialized\n");
10535 + return -ENODEV;
10536 + }
10537 +
10538 + if (!device_can_wakeup(net_dev->dev.parent) ||
10539 + (wol->wolopts & ~WAKE_MAGIC))
10540 + return -EOPNOTSUPP;
10541 +
10542 + priv->wol = 0;
10543 +
10544 + if (wol->wolopts & WAKE_MAGIC) {
10545 + priv->wol = DPAA_WOL_MAGIC;
10546 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10547 + } else {
10548 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10549 + }
10550 +
10551 + return 0;
10552 +}
10553 +#endif
10554 +
10555 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10556 +{
10557 + struct dpa_priv_s *priv;
10558 +
10559 + priv = netdev_priv(net_dev);
10560 + if (priv->mac_dev == NULL) {
10561 + netdev_info(net_dev, "This is a MAC-less interface\n");
10562 + return -ENODEV;
10563 + }
10564 +
10565 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10566 + netdev_err(net_dev, "phy device not initialized\n");
10567 + return -ENODEV;
10568 + }
10569 +
10570 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10571 +}
10572 +
10573 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10574 +{
10575 + struct dpa_priv_s *priv;
10576 +
10577 + priv = netdev_priv(net_dev);
10578 + if (priv->mac_dev == NULL) {
10579 + netdev_info(net_dev, "This is a MAC-less interface\n");
10580 + return -ENODEV;
10581 + }
10582 +
10583 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10584 + netdev_err(net_dev, "phy device not initialized\n");
10585 + return -ENODEV;
10586 + }
10587 +
10588 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10589 +}
10590 +
10591 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10592 +{
10593 + unsigned int total_stats, num_stats;
10594 +
10595 + num_stats = num_online_cpus() + 1;
10596 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10597 +
10598 + switch (type) {
10599 + case ETH_SS_STATS:
10600 + return total_stats;
10601 + default:
10602 + return -EOPNOTSUPP;
10603 + }
10604 +}
10605 +
10606 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10607 + int crr_cpu, u64 bp_count, u64 *data)
10608 +{
10609 + int num_stat_values = num_cpus + 1;
10610 + int crr_stat = 0;
10611 +
10612 + /* update current CPU's stats and also add them to the total values */
10613 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10614 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10615 +
10616 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10617 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10618 +
10619 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10620 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10621 +
10622 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10623 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10624 +
10625 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10626 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10627 +
10628 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10629 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10630 +
10631 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10632 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10633 +
10634 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10635 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10636 +
10637 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10638 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10639 +
10640 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10641 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10642 +}
10643 +
10644 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10645 + struct ethtool_stats *stats, u64 *data)
10646 +{
10647 + u64 bp_count, cg_time, cg_num, cg_status;
10648 + struct dpa_percpu_priv_s *percpu_priv;
10649 + struct qm_mcr_querycgr query_cgr;
10650 + struct dpa_rx_errors rx_errors;
10651 + struct dpa_ern_cnt ern_cnt;
10652 + struct dpa_priv_s *priv;
10653 + unsigned int num_cpus, offset;
10654 + struct dpa_bp *dpa_bp;
10655 + int total_stats, i;
10656 +
10657 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10658 + priv = netdev_priv(net_dev);
10659 + dpa_bp = priv->dpa_bp;
10660 + num_cpus = num_online_cpus();
10661 + bp_count = 0;
10662 +
10663 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10664 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10665 + memset(data, 0, total_stats * sizeof(u64));
10666 +
10667 + for_each_online_cpu(i) {
10668 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10669 +
10670 + if (dpa_bp->percpu_count)
10671 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10672 +
10673 + rx_errors.dme += percpu_priv->rx_errors.dme;
10674 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10675 + rx_errors.fse += percpu_priv->rx_errors.fse;
10676 + rx_errors.phe += percpu_priv->rx_errors.phe;
10677 + rx_errors.cse += percpu_priv->rx_errors.cse;
10678 +
10679 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10680 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10681 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10682 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10683 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10684 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10685 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10686 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10687 +
10688 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10689 + }
10690 +
10691 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10692 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10693 +
10694 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10695 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10696 +
10697 + /* gather congestion related counters */
10698 + cg_num = 0;
10699 + cg_status = 0;
10700 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10701 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10702 + cg_num = priv->cgr_data.cgr_congested_count;
10703 + cg_status = query_cgr.cgr.cs;
10704 +
10705 + /* reset congestion stats (like QMan API does */
10706 + priv->cgr_data.congested_jiffies = 0;
10707 + priv->cgr_data.cgr_congested_count = 0;
10708 + }
10709 +
10710 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10711 + data[offset++] = cg_time;
10712 + data[offset++] = cg_num;
10713 + data[offset++] = cg_status;
10714 +}
10715 +
10716 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10717 +{
10718 + unsigned int i, j, num_cpus, size;
10719 + char stat_string_cpu[ETH_GSTRING_LEN];
10720 + u8 *strings;
10721 +
10722 + strings = data;
10723 + num_cpus = num_online_cpus();
10724 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10725 +
10726 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10727 + for (j = 0; j < num_cpus; j++) {
10728 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10729 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10730 + strings += ETH_GSTRING_LEN;
10731 + }
10732 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10733 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10734 + strings += ETH_GSTRING_LEN;
10735 + }
10736 + memcpy(strings, dpa_stats_global, size);
10737 +}
10738 +
10739 +const struct ethtool_ops dpa_ethtool_ops = {
10740 + .get_settings = dpa_get_settings,
10741 + .set_settings = dpa_set_settings,
10742 + .get_drvinfo = dpa_get_drvinfo,
10743 + .get_msglevel = dpa_get_msglevel,
10744 + .set_msglevel = dpa_set_msglevel,
10745 + .nway_reset = dpa_nway_reset,
10746 + .get_pauseparam = dpa_get_pauseparam,
10747 + .set_pauseparam = dpa_set_pauseparam,
10748 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10749 + .get_link = ethtool_op_get_link,
10750 + .get_eee = dpa_get_eee,
10751 + .set_eee = dpa_set_eee,
10752 + .get_sset_count = dpa_get_sset_count,
10753 + .get_ethtool_stats = dpa_get_ethtool_stats,
10754 + .get_strings = dpa_get_strings,
10755 +#ifdef CONFIG_PM
10756 + .get_wol = dpa_get_wol,
10757 + .set_wol = dpa_set_wol,
10758 +#endif
10759 +};
10760 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10761 new file mode 100644
10762 index 00000000..f54a3d67
10763 --- /dev/null
10764 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10765 @@ -0,0 +1,291 @@
10766 +/*
10767 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10768 + *
10769 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10770 + *
10771 + * Copyright 2014 Freescale Semiconductor, Inc.
10772 + *
10773 + * This program is free software; you can redistribute it and/or modify it
10774 + * under the terms of the GNU General Public License as published by the
10775 + * Free Software Foundation; either version 2 of the License, or (at your
10776 + * option) any later version.
10777 +*/
10778 +
10779 +#include <linux/device.h>
10780 +#include <linux/hrtimer.h>
10781 +#include <linux/init.h>
10782 +#include <linux/interrupt.h>
10783 +#include <linux/kernel.h>
10784 +#include <linux/module.h>
10785 +#include <linux/of.h>
10786 +#include <linux/of_platform.h>
10787 +#include <linux/timex.h>
10788 +#include <linux/io.h>
10789 +
10790 +#include <linux/ptp_clock_kernel.h>
10791 +
10792 +#include "dpaa_eth.h"
10793 +#include "mac.h"
10794 +
10795 +static struct mac_device *mac_dev;
10796 +static u32 freqCompensation;
10797 +
10798 +/* Bit definitions for the TMR_CTRL register */
10799 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10800 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10801 +#define FS (1<<28) /* FIPER start indication */
10802 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10803 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10804 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10805 +#define TCLK_PERIOD_MASK (0x3ff)
10806 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10807 +#define FRD (1<<14) /* FIPER Realignment Disable */
10808 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10809 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10810 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10811 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10812 +#define COPH (1<<7) /* Generated clock output phase. */
10813 +#define CIPH (1<<6) /* External oscillator input clock phase */
10814 +#define TMSR (1<<5) /* Timer soft reset. */
10815 +#define BYP (1<<3) /* Bypass drift compensated clock */
10816 +#define TE (1<<2) /* 1588 timer enable. */
10817 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10818 +#define CKSEL_MASK (0x3)
10819 +
10820 +/* Bit definitions for the TMR_TEVENT register */
10821 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10822 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10823 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10824 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10825 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10826 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10827 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10828 +
10829 +/* Bit definitions for the TMR_TEMASK register */
10830 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10831 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10832 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10833 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10834 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10835 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10836 +
10837 +/* Bit definitions for the TMR_PEVENT register */
10838 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10839 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10840 +#define RXP (1<<0) /* PTP frame has been received */
10841 +
10842 +/* Bit definitions for the TMR_PEMASK register */
10843 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10844 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10845 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10846 +
10847 +/* Bit definitions for the TMR_STAT register */
10848 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10849 +#define STAT_VEC_MASK (0x3f)
10850 +
10851 +/* Bit definitions for the TMR_PRSC register */
10852 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10853 +#define PRSC_OCK_MASK (0xffff)
10854 +
10855 +
10856 +#define N_EXT_TS 2
10857 +
10858 +static void set_alarm(void)
10859 +{
10860 + u64 ns;
10861 +
10862 + if (mac_dev->fm_rtc_get_cnt)
10863 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10864 + ns += 1500000000ULL;
10865 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10866 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10867 + if (mac_dev->fm_rtc_set_alarm)
10868 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10869 +}
10870 +
10871 +static void set_fipers(void)
10872 +{
10873 + u64 fiper;
10874 +
10875 + if (mac_dev->fm_rtc_disable)
10876 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10877 +
10878 + set_alarm();
10879 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10880 + if (mac_dev->fm_rtc_set_fiper)
10881 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10882 +
10883 + if (mac_dev->fm_rtc_enable)
10884 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10885 +}
10886 +
10887 +/* PTP clock operations */
10888 +
10889 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10890 +{
10891 + u64 adj;
10892 + u32 diff, tmr_add;
10893 + int neg_adj = 0;
10894 +
10895 + if (ppb < 0) {
10896 + neg_adj = 1;
10897 + ppb = -ppb;
10898 + }
10899 +
10900 + tmr_add = freqCompensation;
10901 + adj = tmr_add;
10902 + adj *= ppb;
10903 + diff = div_u64(adj, 1000000000ULL);
10904 +
10905 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
10906 +
10907 + if (mac_dev->fm_rtc_set_drift)
10908 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
10909 +
10910 + return 0;
10911 +}
10912 +
10913 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
10914 +{
10915 + s64 now;
10916 +
10917 + if (mac_dev->fm_rtc_get_cnt)
10918 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
10919 +
10920 + now += delta;
10921 +
10922 + if (mac_dev->fm_rtc_set_cnt)
10923 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
10924 + set_fipers();
10925 +
10926 + return 0;
10927 +}
10928 +
10929 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
10930 +{
10931 + u64 ns;
10932 + u32 remainder;
10933 +
10934 + if (mac_dev->fm_rtc_get_cnt)
10935 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10936 +
10937 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
10938 + ts->tv_nsec = remainder;
10939 + return 0;
10940 +}
10941 +
10942 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
10943 + const struct timespec64 *ts)
10944 +{
10945 + u64 ns;
10946 +
10947 + ns = ts->tv_sec * 1000000000ULL;
10948 + ns += ts->tv_nsec;
10949 +
10950 + if (mac_dev->fm_rtc_set_cnt)
10951 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
10952 + set_fipers();
10953 + return 0;
10954 +}
10955 +
10956 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
10957 + struct ptp_clock_request *rq, int on)
10958 +{
10959 + u32 bit;
10960 +
10961 + switch (rq->type) {
10962 + case PTP_CLK_REQ_EXTTS:
10963 + switch (rq->extts.index) {
10964 + case 0:
10965 + bit = ETS1EN;
10966 + break;
10967 + case 1:
10968 + bit = ETS2EN;
10969 + break;
10970 + default:
10971 + return -EINVAL;
10972 + }
10973 + if (on) {
10974 + if (mac_dev->fm_rtc_enable_interrupt)
10975 + mac_dev->fm_rtc_enable_interrupt(
10976 + mac_dev->fm_dev, bit);
10977 + } else {
10978 + if (mac_dev->fm_rtc_disable_interrupt)
10979 + mac_dev->fm_rtc_disable_interrupt(
10980 + mac_dev->fm_dev, bit);
10981 + }
10982 + return 0;
10983 +
10984 + case PTP_CLK_REQ_PPS:
10985 + if (on) {
10986 + if (mac_dev->fm_rtc_enable_interrupt)
10987 + mac_dev->fm_rtc_enable_interrupt(
10988 + mac_dev->fm_dev, PP1EN);
10989 + } else {
10990 + if (mac_dev->fm_rtc_disable_interrupt)
10991 + mac_dev->fm_rtc_disable_interrupt(
10992 + mac_dev->fm_dev, PP1EN);
10993 + }
10994 + return 0;
10995 +
10996 + default:
10997 + break;
10998 + }
10999 +
11000 + return -EOPNOTSUPP;
11001 +}
11002 +
11003 +static struct ptp_clock_info ptp_dpa_caps = {
11004 + .owner = THIS_MODULE,
11005 + .name = "dpaa clock",
11006 + .max_adj = 512000,
11007 + .n_alarm = 0,
11008 + .n_ext_ts = N_EXT_TS,
11009 + .n_per_out = 0,
11010 + .pps = 1,
11011 + .adjfreq = ptp_dpa_adjfreq,
11012 + .adjtime = ptp_dpa_adjtime,
11013 + .gettime64 = ptp_dpa_gettime,
11014 + .settime64 = ptp_dpa_settime,
11015 + .enable = ptp_dpa_enable,
11016 +};
11017 +
11018 +static int __init __cold dpa_ptp_load(void)
11019 +{
11020 + struct device *ptp_dev;
11021 + struct timespec64 now;
11022 + struct ptp_clock *clock = ptp_priv.clock;
11023 + int dpa_phc_index;
11024 + int err;
11025 +
11026 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
11027 + return -ENODEV;
11028 +
11029 + ptp_dev = &ptp_priv.of_dev->dev;
11030 + mac_dev = ptp_priv.mac_dev;
11031 +
11032 + if (mac_dev->fm_rtc_get_drift)
11033 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
11034 +
11035 + getnstimeofday64(&now);
11036 + ptp_dpa_settime(&ptp_dpa_caps, &now);
11037 +
11038 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
11039 + if (IS_ERR(clock)) {
11040 + err = PTR_ERR(clock);
11041 + return err;
11042 + }
11043 + dpa_phc_index = ptp_clock_index(clock);
11044 + return 0;
11045 +}
11046 +module_init(dpa_ptp_load);
11047 +
11048 +static void __exit __cold dpa_ptp_unload(void)
11049 +{
11050 + struct ptp_clock *clock = ptp_priv.clock;
11051 +
11052 + if (mac_dev->fm_rtc_disable_interrupt)
11053 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
11054 + ptp_clock_unregister(clock);
11055 +}
11056 +module_exit(dpa_ptp_unload);
11057 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11058 new file mode 100644
11059 index 00000000..2c5652d9
11060 --- /dev/null
11061 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11062 @@ -0,0 +1,907 @@
11063 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11064 + *
11065 + * Redistribution and use in source and binary forms, with or without
11066 + * modification, are permitted provided that the following conditions are met:
11067 + * * Redistributions of source code must retain the above copyright
11068 + * notice, this list of conditions and the following disclaimer.
11069 + * * Redistributions in binary form must reproduce the above copyright
11070 + * notice, this list of conditions and the following disclaimer in the
11071 + * documentation and/or other materials provided with the distribution.
11072 + * * Neither the name of Freescale Semiconductor nor the
11073 + * names of its contributors may be used to endorse or promote products
11074 + * derived from this software without specific prior written permission.
11075 + *
11076 + *
11077 + * ALTERNATIVELY, this software may be distributed under the terms of the
11078 + * GNU General Public License ("GPL") as published by the Free Software
11079 + * Foundation, either version 2 of that License or (at your option) any
11080 + * later version.
11081 + *
11082 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11083 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11084 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11085 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11086 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11087 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11088 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11089 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11090 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11091 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11092 + */
11093 +
11094 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11095 +#define pr_fmt(fmt) \
11096 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11097 + KBUILD_BASENAME".c", __LINE__, __func__
11098 +#else
11099 +#define pr_fmt(fmt) \
11100 + KBUILD_MODNAME ": " fmt
11101 +#endif
11102 +
11103 +#include <linux/init.h>
11104 +#include <linux/module.h>
11105 +#include <linux/io.h>
11106 +#include <linux/of_platform.h>
11107 +#include <linux/of_mdio.h>
11108 +#include <linux/phy.h>
11109 +#include <linux/netdevice.h>
11110 +
11111 +#include "dpaa_eth.h"
11112 +#include "mac.h"
11113 +#include "lnxwrp_fsl_fman.h"
11114 +
11115 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11116 +
11117 +#include "fsl_fman_dtsec.h"
11118 +#include "fsl_fman_tgec.h"
11119 +#include "fsl_fman_memac.h"
11120 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11121 +
11122 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11123 +
11124 +MODULE_LICENSE("Dual BSD/GPL");
11125 +
11126 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11127 +
11128 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11129 +
11130 +struct mac_priv_s {
11131 + struct fm_mac_dev *fm_mac;
11132 +};
11133 +
11134 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11135 +const size_t mac_sizeof_priv[] = {
11136 + [DTSEC] = sizeof(struct mac_priv_s),
11137 + [XGMAC] = sizeof(struct mac_priv_s),
11138 + [MEMAC] = sizeof(struct mac_priv_s)
11139 +};
11140 +
11141 +static const enet_mode_t _100[] = {
11142 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11143 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11144 +};
11145 +
11146 +static const enet_mode_t _1000[] = {
11147 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11148 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11149 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11150 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11151 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11152 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11153 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11154 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11155 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11156 +};
11157 +
11158 +static enet_mode_t __cold __attribute__((nonnull))
11159 +macdev2enetinterface(const struct mac_device *mac_dev)
11160 +{
11161 + switch (mac_dev->max_speed) {
11162 + case SPEED_100:
11163 + return _100[mac_dev->phy_if];
11164 + case SPEED_1000:
11165 + return _1000[mac_dev->phy_if];
11166 + case SPEED_2500:
11167 + return e_ENET_MODE_SGMII_2500;
11168 + case SPEED_10000:
11169 + return e_ENET_MODE_XGMII_10000;
11170 + default:
11171 + return e_ENET_MODE_MII_100;
11172 + }
11173 +}
11174 +
11175 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11176 +{
11177 + struct mac_device *mac_dev;
11178 +
11179 + mac_dev = (struct mac_device *)_mac_dev;
11180 +
11181 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11182 + /* don't flag RX FIFO after the first */
11183 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11184 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11185 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11186 + exception);
11187 + }
11188 +
11189 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11190 + exception);
11191 +}
11192 +
11193 +static int __cold init(struct mac_device *mac_dev)
11194 +{
11195 + int _errno;
11196 + struct mac_priv_s *priv;
11197 + t_FmMacParams param;
11198 + uint32_t version;
11199 +
11200 + priv = macdev_priv(mac_dev);
11201 +
11202 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11203 + mac_dev->dev, mac_dev->res->start, 0x2000);
11204 + param.enetMode = macdev2enetinterface(mac_dev);
11205 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11206 + sizeof(mac_dev->addr)));
11207 + param.macId = mac_dev->cell_index;
11208 + param.h_Fm = (handle_t)mac_dev->fm;
11209 + param.mdioIrq = NO_IRQ;
11210 + param.f_Exception = mac_exception;
11211 + param.f_Event = mac_exception;
11212 + param.h_App = mac_dev;
11213 +
11214 + priv->fm_mac = fm_mac_config(&param);
11215 + if (unlikely(priv->fm_mac == NULL)) {
11216 + _errno = -EINVAL;
11217 + goto _return;
11218 + }
11219 +
11220 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11221 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11222 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11223 +
11224 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11225 + fm_get_max_frm());
11226 + if (unlikely(_errno < 0))
11227 + goto _return_fm_mac_free;
11228 +
11229 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11230 + /* 10G always works with pad and CRC */
11231 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11232 + if (unlikely(_errno < 0))
11233 + goto _return_fm_mac_free;
11234 +
11235 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11236 + mac_dev->half_duplex);
11237 + if (unlikely(_errno < 0))
11238 + goto _return_fm_mac_free;
11239 + } else {
11240 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11241 + if (unlikely(_errno < 0))
11242 + goto _return_fm_mac_free;
11243 + }
11244 +
11245 + _errno = fm_mac_init(priv->fm_mac);
11246 + if (unlikely(_errno < 0))
11247 + goto _return_fm_mac_free;
11248 +
11249 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11250 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11251 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11252 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11253 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11254 + if (unlikely(_errno < 0))
11255 + goto _return_fm_mac_free;
11256 + }
11257 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11258 +
11259 + /* For 10G MAC, disable Tx ECC exception */
11260 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11261 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11262 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11263 + if (unlikely(_errno < 0))
11264 + goto _return_fm_mac_free;
11265 + }
11266 +
11267 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11268 + if (unlikely(_errno < 0))
11269 + goto _return_fm_mac_free;
11270 +
11271 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11272 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11273 + "dTSEC" : "XGEC"), version);
11274 +
11275 + goto _return;
11276 +
11277 +
11278 +_return_fm_mac_free:
11279 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11280 +
11281 +_return:
11282 + return _errno;
11283 +}
11284 +
11285 +static int __cold memac_init(struct mac_device *mac_dev)
11286 +{
11287 + int _errno;
11288 + struct mac_priv_s *priv;
11289 + t_FmMacParams param;
11290 +
11291 + priv = macdev_priv(mac_dev);
11292 +
11293 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11294 + mac_dev->dev, mac_dev->res->start, 0x2000);
11295 + param.enetMode = macdev2enetinterface(mac_dev);
11296 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11297 + param.macId = mac_dev->cell_index;
11298 + param.h_Fm = (handle_t)mac_dev->fm;
11299 + param.mdioIrq = NO_IRQ;
11300 + param.f_Exception = mac_exception;
11301 + param.f_Event = mac_exception;
11302 + param.h_App = mac_dev;
11303 +
11304 + priv->fm_mac = fm_mac_config(&param);
11305 + if (unlikely(priv->fm_mac == NULL)) {
11306 + _errno = -EINVAL;
11307 + goto _return;
11308 + }
11309 +
11310 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11311 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11312 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11313 +
11314 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11315 + if (unlikely(_errno < 0))
11316 + goto _return_fm_mac_free;
11317 +
11318 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11319 + if (unlikely(_errno < 0))
11320 + goto _return_fm_mac_free;
11321 +
11322 + _errno = fm_mac_init(priv->fm_mac);
11323 + if (unlikely(_errno < 0))
11324 + goto _return_fm_mac_free;
11325 +
11326 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11327 +
11328 + goto _return;
11329 +
11330 +_return_fm_mac_free:
11331 + fm_mac_free(priv->fm_mac);
11332 +
11333 +_return:
11334 + return _errno;
11335 +}
11336 +
11337 +static int __cold start(struct mac_device *mac_dev)
11338 +{
11339 + int _errno;
11340 + struct phy_device *phy_dev = mac_dev->phy_dev;
11341 +
11342 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11343 +
11344 + if (!_errno && phy_dev)
11345 + phy_start(phy_dev);
11346 +
11347 + return _errno;
11348 +}
11349 +
11350 +static int __cold stop(struct mac_device *mac_dev)
11351 +{
11352 + if (mac_dev->phy_dev)
11353 + phy_stop(mac_dev->phy_dev);
11354 +
11355 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11356 +}
11357 +
11358 +static int __cold set_multi(struct net_device *net_dev,
11359 + struct mac_device *mac_dev)
11360 +{
11361 + struct mac_priv_s *mac_priv;
11362 + struct mac_address *old_addr, *tmp;
11363 + struct netdev_hw_addr *ha;
11364 + int _errno;
11365 +
11366 + mac_priv = macdev_priv(mac_dev);
11367 +
11368 + /* Clear previous address list */
11369 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11370 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11371 + (t_EnetAddr *)old_addr->addr);
11372 + if (_errno < 0)
11373 + return _errno;
11374 +
11375 + list_del(&old_addr->list);
11376 + kfree(old_addr);
11377 + }
11378 +
11379 + /* Add all the addresses from the new list */
11380 + netdev_for_each_mc_addr(ha, net_dev) {
11381 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11382 + (t_EnetAddr *)ha->addr);
11383 + if (_errno < 0)
11384 + return _errno;
11385 +
11386 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11387 + if (!tmp) {
11388 + dev_err(mac_dev->dev, "Out of memory\n");
11389 + return -ENOMEM;
11390 + }
11391 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11392 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11393 + }
11394 + return 0;
11395 +}
11396 +
11397 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11398 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11399 + * in FMan.
11400 + */
11401 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11402 +{
11403 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11404 + int _errno = 0;
11405 +
11406 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11407 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11408 + if (likely(_errno == 0))
11409 + mac_dev->rx_pause_active = rx;
11410 + }
11411 +
11412 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11413 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11414 + if (likely(_errno == 0))
11415 + mac_dev->tx_pause_active = tx;
11416 + }
11417 +
11418 + return _errno;
11419 +}
11420 +EXPORT_SYMBOL(set_mac_active_pause);
11421 +
11422 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11423 + * autonegotiation or values set by eththool.
11424 + */
11425 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11426 +{
11427 + struct phy_device *phy_dev = mac_dev->phy_dev;
11428 + u16 lcl_adv, rmt_adv;
11429 + u8 flowctrl;
11430 +
11431 + *rx_pause = *tx_pause = false;
11432 +
11433 + if (!phy_dev->duplex)
11434 + return;
11435 +
11436 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11437 + * are those set by ethtool.
11438 + */
11439 + if (!mac_dev->autoneg_pause) {
11440 + *rx_pause = mac_dev->rx_pause_req;
11441 + *tx_pause = mac_dev->tx_pause_req;
11442 + return;
11443 + }
11444 +
11445 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11446 + * settings depend on the result of the link negotiation.
11447 + */
11448 +
11449 + /* get local capabilities */
11450 + lcl_adv = 0;
11451 + if (phy_dev->advertising & ADVERTISED_Pause)
11452 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11453 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11454 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11455 +
11456 + /* get link partner capabilities */
11457 + rmt_adv = 0;
11458 + if (phy_dev->pause)
11459 + rmt_adv |= LPA_PAUSE_CAP;
11460 + if (phy_dev->asym_pause)
11461 + rmt_adv |= LPA_PAUSE_ASYM;
11462 +
11463 + /* Calculate TX/RX settings based on local and peer advertised
11464 + * symmetric/asymmetric PAUSE capabilities.
11465 + */
11466 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11467 + if (flowctrl & FLOW_CTRL_RX)
11468 + *rx_pause = true;
11469 + if (flowctrl & FLOW_CTRL_TX)
11470 + *tx_pause = true;
11471 +}
11472 +EXPORT_SYMBOL(get_pause_cfg);
11473 +
11474 +static void adjust_link_void(struct net_device *net_dev)
11475 +{
11476 +}
11477 +
11478 +static void adjust_link(struct net_device *net_dev)
11479 +{
11480 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11481 + struct mac_device *mac_dev = priv->mac_dev;
11482 + struct phy_device *phy_dev = mac_dev->phy_dev;
11483 + struct fm_mac_dev *fm_mac_dev;
11484 + bool rx_pause, tx_pause;
11485 + int _errno;
11486 +
11487 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11488 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11489 + phy_dev->duplex);
11490 +
11491 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11492 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11493 + if (unlikely(_errno < 0))
11494 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11495 +}
11496 +
11497 +/* Initializes driver's PHY state, and attaches to the PHY.
11498 + * Returns 0 on success.
11499 + */
11500 +static int dtsec_init_phy(struct net_device *net_dev,
11501 + struct mac_device *mac_dev)
11502 +{
11503 + struct phy_device *phy_dev;
11504 +
11505 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11506 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11507 + 0, mac_dev->phy_if);
11508 + else
11509 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11510 + &adjust_link, 0, mac_dev->phy_if);
11511 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11512 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11513 + mac_dev->phy_node ?
11514 + mac_dev->phy_node->full_name :
11515 + mac_dev->fixed_bus_id);
11516 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11517 + }
11518 +
11519 + /* Remove any features not supported by the controller */
11520 + phy_dev->supported &= mac_dev->if_support;
11521 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11522 + * as most of the PHY drivers do not enable them by default.
11523 + */
11524 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11525 + phy_dev->advertising = phy_dev->supported;
11526 +
11527 + mac_dev->phy_dev = phy_dev;
11528 +
11529 + return 0;
11530 +}
11531 +
11532 +static int xgmac_init_phy(struct net_device *net_dev,
11533 + struct mac_device *mac_dev)
11534 +{
11535 + struct phy_device *phy_dev;
11536 +
11537 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11538 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11539 + 0, mac_dev->phy_if);
11540 + else
11541 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11542 + &adjust_link_void, 0, mac_dev->phy_if);
11543 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11544 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11545 + mac_dev->phy_node ?
11546 + mac_dev->phy_node->full_name :
11547 + mac_dev->fixed_bus_id);
11548 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11549 + }
11550 +
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 memac_init_phy(struct net_device *net_dev,
11564 + struct mac_device *mac_dev)
11565 +{
11566 + struct phy_device *phy_dev;
11567 +
11568 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11569 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) ||
11570 + of_phy_is_fixed_link(mac_dev->phy_node)) {
11571 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11572 + &adjust_link_void, 0,
11573 + mac_dev->phy_if);
11574 + } else {
11575 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11576 + &adjust_link, 0, mac_dev->phy_if);
11577 + }
11578 +
11579 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11580 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11581 + mac_dev->phy_node ?
11582 + mac_dev->phy_node->full_name :
11583 + mac_dev->fixed_bus_id);
11584 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11585 + }
11586 +
11587 + /* Remove any features not supported by the controller */
11588 + phy_dev->supported &= mac_dev->if_support;
11589 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11590 + * as most of the PHY drivers do not enable them by default.
11591 + */
11592 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11593 + phy_dev->advertising = phy_dev->supported;
11594 +
11595 + mac_dev->phy_dev = phy_dev;
11596 +
11597 + return 0;
11598 +}
11599 +
11600 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11601 +{
11602 + int _errno, __errno;
11603 +
11604 + _errno = fm_mac_disable(fm_mac_dev);
11605 + __errno = fm_mac_free(fm_mac_dev);
11606 +
11607 + if (unlikely(__errno < 0))
11608 + _errno = __errno;
11609 +
11610 + return _errno;
11611 +}
11612 +
11613 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11614 +{
11615 + const struct mac_priv_s *priv;
11616 + priv = macdev_priv(mac_dev);
11617 + return priv->fm_mac;
11618 +}
11619 +
11620 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11621 +{
11622 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11623 + int i = 0, n = nn;
11624 +
11625 + FM_DMP_SUBTITLE(buf, n, "\n");
11626 +
11627 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11628 +
11629 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11630 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11631 + FM_DMP_V32(buf, n, p_mm, ievent);
11632 + FM_DMP_V32(buf, n, p_mm, imask);
11633 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11634 + FM_DMP_V32(buf, n, p_mm, ptv);
11635 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11636 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11637 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11638 + FM_DMP_V32(buf, n, p_mm, tctrl);
11639 + FM_DMP_V32(buf, n, p_mm, rctrl);
11640 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11641 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11642 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11643 + FM_DMP_V32(buf, n, p_mm, hafdup);
11644 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11645 +
11646 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11647 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11648 +
11649 + for (i = 0; i < 7; ++i) {
11650 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11651 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11652 + }
11653 +
11654 + FM_DMP_V32(buf, n, p_mm, car1);
11655 + FM_DMP_V32(buf, n, p_mm, car2);
11656 +
11657 + return n;
11658 +}
11659 +
11660 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11661 +{
11662 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11663 + int n = nn;
11664 +
11665 + FM_DMP_SUBTITLE(buf, n, "\n");
11666 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11667 +
11668 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11669 + FM_DMP_V32(buf, n, p_mm, command_config);
11670 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11671 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11672 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11673 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11674 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11675 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11676 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11677 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11678 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11679 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11680 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11681 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11682 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11683 + FM_DMP_V32(buf, n, p_mm, status);
11684 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11685 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11686 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11687 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11688 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11689 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11690 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11691 + FM_DMP_V32(buf, n, p_mm, imask);
11692 + FM_DMP_V32(buf, n, p_mm, ievent);
11693 +
11694 + return n;
11695 +}
11696 +
11697 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11698 +{
11699 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11700 + int i = 0, n = nn;
11701 +
11702 + FM_DMP_SUBTITLE(buf, n, "\n");
11703 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11704 +
11705 + FM_DMP_V32(buf, n, p_mm, command_config);
11706 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11707 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11708 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11709 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11710 + FM_DMP_V32(buf, n, p_mm, ievent);
11711 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11712 + FM_DMP_V32(buf, n, p_mm, imask);
11713 +
11714 + for (i = 0; i < 4; ++i)
11715 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11716 +
11717 + for (i = 0; i < 4; ++i)
11718 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11719 +
11720 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11721 +
11722 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11723 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11724 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11725 + }
11726 +
11727 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11728 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11729 + FM_DMP_V32(buf, n, p_mm, statn_config);
11730 + FM_DMP_V32(buf, n, p_mm, if_mode);
11731 + FM_DMP_V32(buf, n, p_mm, if_status);
11732 + FM_DMP_V32(buf, n, p_mm, hg_config);
11733 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11734 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11735 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11736 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11737 + FM_DMP_V32(buf, n, p_mm, rhm);
11738 + FM_DMP_V32(buf, n, p_mm, thm);
11739 +
11740 + return n;
11741 +}
11742 +
11743 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11744 +{
11745 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11746 + int n = nn;
11747 +
11748 + FM_DMP_SUBTITLE(buf, n, "\n");
11749 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11750 +
11751 + /* Rx Statistics Counter */
11752 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11753 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11754 + FM_DMP_V32(buf, n, p_mm, roct_l);
11755 + FM_DMP_V32(buf, n, p_mm, roct_u);
11756 + FM_DMP_V32(buf, n, p_mm, raln_l);
11757 + FM_DMP_V32(buf, n, p_mm, raln_u);
11758 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11759 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11760 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11761 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11762 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11763 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11764 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11765 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11766 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11767 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11768 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11769 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11770 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11771 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11772 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11773 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11774 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11775 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11776 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11777 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11778 + FM_DMP_V32(buf, n, p_mm, rund_l);
11779 + FM_DMP_V32(buf, n, p_mm, rund_u);
11780 + FM_DMP_V32(buf, n, p_mm, r64_l);
11781 + FM_DMP_V32(buf, n, p_mm, r64_u);
11782 + FM_DMP_V32(buf, n, p_mm, r127_l);
11783 + FM_DMP_V32(buf, n, p_mm, r127_u);
11784 + FM_DMP_V32(buf, n, p_mm, r255_l);
11785 + FM_DMP_V32(buf, n, p_mm, r255_u);
11786 + FM_DMP_V32(buf, n, p_mm, r511_l);
11787 + FM_DMP_V32(buf, n, p_mm, r511_u);
11788 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11789 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11790 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11791 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11792 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11793 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11794 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11795 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11796 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11797 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11798 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11799 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11800 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11801 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11802 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11803 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11804 +
11805 + return n;
11806 +}
11807 +
11808 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11809 +{
11810 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11811 + int n = nn;
11812 +
11813 + FM_DMP_SUBTITLE(buf, n, "\n");
11814 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11815 +
11816 +
11817 + /* Tx Statistics Counter */
11818 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11819 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11820 + FM_DMP_V32(buf, n, p_mm, toct_l);
11821 + FM_DMP_V32(buf, n, p_mm, toct_u);
11822 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11823 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11824 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11825 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11826 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11827 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11828 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11829 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11830 + FM_DMP_V32(buf, n, p_mm, terr_l);
11831 + FM_DMP_V32(buf, n, p_mm, terr_u);
11832 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11833 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11834 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11835 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11836 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11837 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11838 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11839 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11840 + FM_DMP_V32(buf, n, p_mm, tund_l);
11841 + FM_DMP_V32(buf, n, p_mm, tund_u);
11842 + FM_DMP_V32(buf, n, p_mm, t64_l);
11843 + FM_DMP_V32(buf, n, p_mm, t64_u);
11844 + FM_DMP_V32(buf, n, p_mm, t127_l);
11845 + FM_DMP_V32(buf, n, p_mm, t127_u);
11846 + FM_DMP_V32(buf, n, p_mm, t255_l);
11847 + FM_DMP_V32(buf, n, p_mm, t255_u);
11848 + FM_DMP_V32(buf, n, p_mm, t511_l);
11849 + FM_DMP_V32(buf, n, p_mm, t511_u);
11850 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11851 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11852 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11853 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11854 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11855 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11856 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11857 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11858 +
11859 + return n;
11860 +}
11861 +
11862 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11863 +{
11864 + int n = nn;
11865 +
11866 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11867 +
11868 + return n;
11869 +}
11870 +EXPORT_SYMBOL(fm_mac_dump_regs);
11871 +
11872 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11873 +{
11874 + int n = nn;
11875 +
11876 + if(h_mac->dump_mac_rx_stats)
11877 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11878 +
11879 + return n;
11880 +}
11881 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11882 +
11883 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
11884 +{
11885 + int n = nn;
11886 +
11887 + if(h_mac->dump_mac_tx_stats)
11888 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
11889 +
11890 + return n;
11891 +}
11892 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
11893 +
11894 +static void __cold setup_dtsec(struct mac_device *mac_dev)
11895 +{
11896 + mac_dev->init_phy = dtsec_init_phy;
11897 + mac_dev->init = init;
11898 + mac_dev->start = start;
11899 + mac_dev->stop = stop;
11900 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11901 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11902 + mac_dev->set_multi = set_multi;
11903 + mac_dev->uninit = uninit;
11904 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
11905 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
11906 + mac_dev->get_mac_handle = get_mac_handle;
11907 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11908 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11909 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11910 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11911 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11912 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11913 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11914 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11915 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11916 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11917 + mac_dev->set_wol = fm_mac_set_wol;
11918 + mac_dev->dump_mac_regs = dtsec_dump_regs;
11919 +}
11920 +
11921 +static void __cold setup_xgmac(struct mac_device *mac_dev)
11922 +{
11923 + mac_dev->init_phy = xgmac_init_phy;
11924 + mac_dev->init = init;
11925 + mac_dev->start = start;
11926 + mac_dev->stop = stop;
11927 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11928 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11929 + mac_dev->set_multi = set_multi;
11930 + mac_dev->uninit = uninit;
11931 + mac_dev->get_mac_handle = get_mac_handle;
11932 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11933 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11934 + mac_dev->set_wol = fm_mac_set_wol;
11935 + mac_dev->dump_mac_regs = xgmac_dump_regs;
11936 +}
11937 +
11938 +static void __cold setup_memac(struct mac_device *mac_dev)
11939 +{
11940 + mac_dev->init_phy = memac_init_phy;
11941 + mac_dev->init = memac_init;
11942 + mac_dev->start = start;
11943 + mac_dev->stop = stop;
11944 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11945 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11946 + mac_dev->set_multi = set_multi;
11947 + mac_dev->uninit = uninit;
11948 + mac_dev->get_mac_handle = get_mac_handle;
11949 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11950 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11951 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11952 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11953 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11954 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11955 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11956 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11957 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11958 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11959 + mac_dev->set_wol = fm_mac_set_wol;
11960 + mac_dev->dump_mac_regs = memac_dump_regs;
11961 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
11962 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
11963 +}
11964 +
11965 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
11966 + [DTSEC] = setup_dtsec,
11967 + [XGMAC] = setup_xgmac,
11968 + [MEMAC] = setup_memac
11969 +};
11970 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11971 new file mode 100644
11972 index 00000000..60133b02
11973 --- /dev/null
11974 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11975 @@ -0,0 +1,489 @@
11976 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11977 + *
11978 + * Redistribution and use in source and binary forms, with or without
11979 + * modification, are permitted provided that the following conditions are met:
11980 + * * Redistributions of source code must retain the above copyright
11981 + * notice, this list of conditions and the following disclaimer.
11982 + * * Redistributions in binary form must reproduce the above copyright
11983 + * notice, this list of conditions and the following disclaimer in the
11984 + * documentation and/or other materials provided with the distribution.
11985 + * * Neither the name of Freescale Semiconductor nor the
11986 + * names of its contributors may be used to endorse or promote products
11987 + * derived from this software without specific prior written permission.
11988 + *
11989 + *
11990 + * ALTERNATIVELY, this software may be distributed under the terms of the
11991 + * GNU General Public License ("GPL") as published by the Free Software
11992 + * Foundation, either version 2 of that License or (at your option) any
11993 + * later version.
11994 + *
11995 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11996 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11997 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11998 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11999 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12000 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12001 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12002 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12003 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12004 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12005 + */
12006 +
12007 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12008 +#define pr_fmt(fmt) \
12009 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12010 + KBUILD_BASENAME".c", __LINE__, __func__
12011 +#else
12012 +#define pr_fmt(fmt) \
12013 + KBUILD_MODNAME ": " fmt
12014 +#endif
12015 +
12016 +#include <linux/init.h>
12017 +#include <linux/module.h>
12018 +#include <linux/of_address.h>
12019 +#include <linux/of_platform.h>
12020 +#include <linux/of_net.h>
12021 +#include <linux/of_mdio.h>
12022 +#include <linux/phy_fixed.h>
12023 +#include <linux/device.h>
12024 +#include <linux/phy.h>
12025 +#include <linux/io.h>
12026 +
12027 +#include "lnxwrp_fm_ext.h"
12028 +
12029 +#include "mac.h"
12030 +
12031 +#define DTSEC_SUPPORTED \
12032 + (SUPPORTED_10baseT_Half \
12033 + | SUPPORTED_10baseT_Full \
12034 + | SUPPORTED_100baseT_Half \
12035 + | SUPPORTED_100baseT_Full \
12036 + | SUPPORTED_Autoneg \
12037 + | SUPPORTED_Pause \
12038 + | SUPPORTED_Asym_Pause \
12039 + | SUPPORTED_MII)
12040 +
12041 +static const char phy_str[][11] = {
12042 + [PHY_INTERFACE_MODE_MII] = "mii",
12043 + [PHY_INTERFACE_MODE_GMII] = "gmii",
12044 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
12045 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
12046 + [PHY_INTERFACE_MODE_TBI] = "tbi",
12047 + [PHY_INTERFACE_MODE_RMII] = "rmii",
12048 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
12049 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
12050 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
12051 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
12052 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
12053 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
12054 + [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
12055 +};
12056 +
12057 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
12058 +{
12059 + int i;
12060 +
12061 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
12062 + if (strcmp(str, phy_str[i]) == 0)
12063 + return (phy_interface_t)i;
12064 +
12065 + return PHY_INTERFACE_MODE_MII;
12066 +}
12067 +
12068 +static const uint16_t phy2speed[] = {
12069 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
12070 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
12071 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
12072 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
12073 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
12074 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
12075 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
12076 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
12077 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
12078 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12079 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12080 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12081 + [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500,
12082 +};
12083 +
12084 +static struct mac_device * __cold
12085 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12086 + void (*setup)(struct mac_device *mac_dev))
12087 +{
12088 + struct mac_device *mac_dev;
12089 +
12090 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12091 + if (unlikely(mac_dev == NULL))
12092 + mac_dev = ERR_PTR(-ENOMEM);
12093 + else {
12094 + mac_dev->dev = dev;
12095 + dev_set_drvdata(dev, mac_dev);
12096 + setup(mac_dev);
12097 + }
12098 +
12099 + return mac_dev;
12100 +}
12101 +
12102 +static int __cold free_macdev(struct mac_device *mac_dev)
12103 +{
12104 + dev_set_drvdata(mac_dev->dev, NULL);
12105 +
12106 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12107 +}
12108 +
12109 +static const struct of_device_id mac_match[] = {
12110 + [DTSEC] = {
12111 + .compatible = "fsl,fman-1g-mac"
12112 + },
12113 + [XGMAC] = {
12114 + .compatible = "fsl,fman-10g-mac"
12115 + },
12116 + [MEMAC] = {
12117 + .compatible = "fsl,fman-memac"
12118 + },
12119 + {}
12120 +};
12121 +MODULE_DEVICE_TABLE(of, mac_match);
12122 +
12123 +static int __cold mac_probe(struct platform_device *_of_dev)
12124 +{
12125 + int _errno, i;
12126 + struct device *dev;
12127 + struct device_node *mac_node, *dev_node;
12128 + struct mac_device *mac_dev;
12129 + struct platform_device *of_dev;
12130 + struct resource res;
12131 + const uint8_t *mac_addr;
12132 + const char *char_prop;
12133 + int nph;
12134 + u32 cell_index;
12135 + const struct of_device_id *match;
12136 +
12137 + dev = &_of_dev->dev;
12138 + mac_node = dev->of_node;
12139 +
12140 + match = of_match_device(mac_match, dev);
12141 + if (!match)
12142 + return -EINVAL;
12143 +
12144 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12145 + i++)
12146 + ;
12147 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12148 +
12149 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12150 + if (IS_ERR(mac_dev)) {
12151 + _errno = PTR_ERR(mac_dev);
12152 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12153 + goto _return;
12154 + }
12155 +
12156 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12157 +
12158 + /* Get the FM node */
12159 + dev_node = of_get_parent(mac_node);
12160 + if (unlikely(dev_node == NULL)) {
12161 + dev_err(dev, "of_get_parent(%s) failed\n",
12162 + mac_node->full_name);
12163 + _errno = -EINVAL;
12164 + goto _return_dev_set_drvdata;
12165 + }
12166 +
12167 + of_dev = of_find_device_by_node(dev_node);
12168 + if (unlikely(of_dev == NULL)) {
12169 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12170 + dev_node->full_name);
12171 + _errno = -EINVAL;
12172 + goto _return_of_node_put;
12173 + }
12174 +
12175 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12176 + if (unlikely(mac_dev->fm_dev == NULL)) {
12177 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12178 + _errno = -ENODEV;
12179 + goto _return_of_node_put;
12180 + }
12181 +
12182 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12183 + of_node_put(dev_node);
12184 +
12185 + /* Get the address of the memory mapped registers */
12186 + _errno = of_address_to_resource(mac_node, 0, &res);
12187 + if (unlikely(_errno < 0)) {
12188 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12189 + mac_node->full_name, _errno);
12190 + goto _return_dev_set_drvdata;
12191 + }
12192 +
12193 + mac_dev->res = __devm_request_region(
12194 + dev,
12195 + fm_get_mem_region(mac_dev->fm_dev),
12196 + res.start, res.end + 1 - res.start, "mac");
12197 + if (unlikely(mac_dev->res == NULL)) {
12198 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12199 + _errno = -EBUSY;
12200 + goto _return_dev_set_drvdata;
12201 + }
12202 +
12203 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12204 + mac_dev->res->end + 1
12205 + - mac_dev->res->start);
12206 + if (unlikely(mac_dev->vaddr == NULL)) {
12207 + dev_err(dev, "devm_ioremap() failed\n");
12208 + _errno = -EIO;
12209 + goto _return_dev_set_drvdata;
12210 + }
12211 +
12212 +#define TBIPA_OFFSET 0x1c
12213 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12214 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12215 + if (mac_dev->tbi_node) {
12216 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12217 + const __be32 *tbi_reg;
12218 + void __iomem *addr;
12219 +
12220 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12221 + if (tbi_reg)
12222 + tbiaddr = be32_to_cpup(tbi_reg);
12223 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12224 + /* TODO: out_be32 does not exist on ARM */
12225 + out_be32(addr, tbiaddr);
12226 + }
12227 +
12228 + if (!of_device_is_available(mac_node)) {
12229 + devm_iounmap(dev, mac_dev->vaddr);
12230 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12231 + res.start, res.end + 1 - res.start);
12232 + fm_unbind(mac_dev->fm_dev);
12233 + devm_kfree(dev, mac_dev);
12234 + dev_set_drvdata(dev, NULL);
12235 + return -ENODEV;
12236 + }
12237 +
12238 + /* Get the cell-index */
12239 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12240 + if (unlikely(_errno)) {
12241 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12242 + mac_node->full_name);
12243 + goto _return_dev_set_drvdata;
12244 + }
12245 + mac_dev->cell_index = (uint8_t)cell_index;
12246 + if (mac_dev->cell_index >= 8)
12247 + mac_dev->cell_index -= 8;
12248 +
12249 + /* Get the MAC address */
12250 + mac_addr = of_get_mac_address(mac_node);
12251 + if (unlikely(mac_addr == NULL)) {
12252 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12253 + mac_node->full_name);
12254 + _errno = -EINVAL;
12255 + goto _return_dev_set_drvdata;
12256 + }
12257 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12258 +
12259 + /* Verify the number of port handles */
12260 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12261 + if (unlikely(nph < 0)) {
12262 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12263 + mac_node->full_name);
12264 + _errno = nph;
12265 + goto _return_dev_set_drvdata;
12266 + }
12267 +
12268 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12269 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12270 + mac_node->full_name);
12271 + _errno = -EINVAL;
12272 + goto _return_dev_set_drvdata;
12273 + }
12274 +
12275 + for_each_port_device(i, mac_dev->port_dev) {
12276 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12277 + if (unlikely(dev_node == NULL)) {
12278 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12279 + mac_node->full_name);
12280 + _errno = -EINVAL;
12281 + goto _return_of_node_put;
12282 + }
12283 +
12284 + of_dev = of_find_device_by_node(dev_node);
12285 + if (unlikely(of_dev == NULL)) {
12286 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12287 + dev_node->full_name);
12288 + _errno = -EINVAL;
12289 + goto _return_of_node_put;
12290 + }
12291 +
12292 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12293 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12294 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12295 + dev_node->full_name);
12296 + _errno = -EINVAL;
12297 + goto _return_of_node_put;
12298 + }
12299 + of_node_put(dev_node);
12300 + }
12301 +
12302 + /* Get the PHY connection type */
12303 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12304 + &char_prop);
12305 + if (unlikely(_errno)) {
12306 + dev_warn(dev,
12307 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12308 + mac_node->full_name);
12309 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12310 + } else
12311 + mac_dev->phy_if = str2phy(char_prop);
12312 +
12313 + mac_dev->link = false;
12314 + mac_dev->half_duplex = false;
12315 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12316 + mac_dev->max_speed = mac_dev->speed;
12317 + mac_dev->if_support = DTSEC_SUPPORTED;
12318 + /* We don't support half-duplex in SGMII mode */
12319 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12320 + strstr(char_prop, "sgmii-2500"))
12321 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12322 + SUPPORTED_100baseT_Half);
12323 +
12324 + /* Gigabit support (no half-duplex) */
12325 + if (mac_dev->max_speed == SPEED_1000 ||
12326 + mac_dev->max_speed == SPEED_2500)
12327 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12328 +
12329 + /* The 10G interface only supports one mode */
12330 + if (strstr(char_prop, "xgmii"))
12331 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12332 +
12333 + /* Get the rest of the PHY information */
12334 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12335 + if (!mac_dev->phy_node) {
12336 + struct phy_device *phy;
12337 +
12338 + if (!of_phy_is_fixed_link(mac_node)) {
12339 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12340 + mac_node->full_name);
12341 + goto _return_dev_set_drvdata;
12342 + }
12343 +
12344 + _errno = of_phy_register_fixed_link(mac_node);
12345 + if (_errno)
12346 + goto _return_dev_set_drvdata;
12347 +
12348 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12349 + sizeof(*mac_dev->fixed_link),
12350 + GFP_KERNEL);
12351 + if (!mac_dev->fixed_link)
12352 + goto _return_dev_set_drvdata;
12353 +
12354 + mac_dev->phy_node = of_node_get(mac_node);
12355 + phy = of_phy_find_device(mac_dev->phy_node);
12356 + if (!phy)
12357 + goto _return_dev_set_drvdata;
12358 +
12359 + mac_dev->fixed_link->link = phy->link;
12360 + mac_dev->fixed_link->speed = phy->speed;
12361 + mac_dev->fixed_link->duplex = phy->duplex;
12362 + mac_dev->fixed_link->pause = phy->pause;
12363 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12364 + }
12365 +
12366 + _errno = mac_dev->init(mac_dev);
12367 + if (unlikely(_errno < 0)) {
12368 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12369 + goto _return_dev_set_drvdata;
12370 + }
12371 +
12372 + /* pause frame autonegotiation enabled*/
12373 + mac_dev->autoneg_pause = true;
12374 +
12375 + /* by intializing the values to false, force FMD to enable PAUSE frames
12376 + * on RX and TX
12377 + */
12378 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12379 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12380 + _errno = set_mac_active_pause(mac_dev, true, true);
12381 + if (unlikely(_errno < 0))
12382 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12383 +
12384 + dev_info(dev,
12385 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12386 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12387 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12388 +
12389 + goto _return;
12390 +
12391 +_return_of_node_put:
12392 + of_node_put(dev_node);
12393 +_return_dev_set_drvdata:
12394 + dev_set_drvdata(dev, NULL);
12395 +_return:
12396 + return _errno;
12397 +}
12398 +
12399 +static int __cold mac_remove(struct platform_device *of_dev)
12400 +{
12401 + int i, _errno;
12402 + struct device *dev;
12403 + struct mac_device *mac_dev;
12404 +
12405 + dev = &of_dev->dev;
12406 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12407 +
12408 + for_each_port_device(i, mac_dev->port_dev)
12409 + fm_port_unbind(mac_dev->port_dev[i]);
12410 +
12411 + fm_unbind(mac_dev->fm_dev);
12412 +
12413 + _errno = free_macdev(mac_dev);
12414 +
12415 + return _errno;
12416 +}
12417 +
12418 +static struct platform_driver mac_driver = {
12419 + .driver = {
12420 + .name = KBUILD_MODNAME,
12421 + .of_match_table = mac_match,
12422 + .owner = THIS_MODULE,
12423 + },
12424 + .probe = mac_probe,
12425 + .remove = mac_remove
12426 +};
12427 +
12428 +static int __init __cold mac_load(void)
12429 +{
12430 + int _errno;
12431 +
12432 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12433 + KBUILD_BASENAME".c", __func__);
12434 +
12435 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12436 +
12437 + _errno = platform_driver_register(&mac_driver);
12438 + if (unlikely(_errno < 0)) {
12439 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12440 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12441 + goto _return;
12442 + }
12443 +
12444 + goto _return;
12445 +
12446 +_return:
12447 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12448 + KBUILD_BASENAME".c", __func__);
12449 +
12450 + return _errno;
12451 +}
12452 +module_init(mac_load);
12453 +
12454 +static void __exit __cold mac_unload(void)
12455 +{
12456 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12457 + KBUILD_BASENAME".c", __func__);
12458 +
12459 + platform_driver_unregister(&mac_driver);
12460 +
12461 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12462 + KBUILD_BASENAME".c", __func__);
12463 +}
12464 +module_exit(mac_unload);
12465 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac.h b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12466 new file mode 100644
12467 index 00000000..b5288f2a
12468 --- /dev/null
12469 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12470 @@ -0,0 +1,135 @@
12471 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12472 + *
12473 + * Redistribution and use in source and binary forms, with or without
12474 + * modification, are permitted provided that the following conditions are met:
12475 + * * Redistributions of source code must retain the above copyright
12476 + * notice, this list of conditions and the following disclaimer.
12477 + * * Redistributions in binary form must reproduce the above copyright
12478 + * notice, this list of conditions and the following disclaimer in the
12479 + * documentation and/or other materials provided with the distribution.
12480 + * * Neither the name of Freescale Semiconductor nor the
12481 + * names of its contributors may be used to endorse or promote products
12482 + * derived from this software without specific prior written permission.
12483 + *
12484 + *
12485 + * ALTERNATIVELY, this software may be distributed under the terms of the
12486 + * GNU General Public License ("GPL") as published by the Free Software
12487 + * Foundation, either version 2 of that License or (at your option) any
12488 + * later version.
12489 + *
12490 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12491 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12492 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12493 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12494 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12495 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12496 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12497 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12498 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12499 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12500 + */
12501 +
12502 +#ifndef __MAC_H
12503 +#define __MAC_H
12504 +
12505 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12506 +#include <linux/if_ether.h> /* ETH_ALEN */
12507 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12508 +#include <linux/list.h>
12509 +
12510 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12511 +
12512 +enum {DTSEC, XGMAC, MEMAC};
12513 +
12514 +struct mac_device {
12515 + struct device *dev;
12516 + void *priv;
12517 + uint8_t cell_index;
12518 + struct resource *res;
12519 + void __iomem *vaddr;
12520 + uint8_t addr[ETH_ALEN];
12521 + bool promisc;
12522 +
12523 + struct fm *fm_dev;
12524 + struct fm_port *port_dev[2];
12525 +
12526 + phy_interface_t phy_if;
12527 + u32 if_support;
12528 + bool link;
12529 + bool half_duplex;
12530 + uint16_t speed;
12531 + uint16_t max_speed;
12532 + struct device_node *phy_node;
12533 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12534 + struct device_node *tbi_node;
12535 + struct phy_device *phy_dev;
12536 + void *fm;
12537 + /* List of multicast addresses */
12538 + struct list_head mc_addr_list;
12539 + struct fixed_phy_status *fixed_link;
12540 +
12541 + bool autoneg_pause;
12542 + bool rx_pause_req;
12543 + bool tx_pause_req;
12544 + bool rx_pause_active;
12545 + bool tx_pause_active;
12546 +
12547 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12548 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12549 + int (*init)(struct mac_device *mac_dev);
12550 + int (*start)(struct mac_device *mac_dev);
12551 + int (*stop)(struct mac_device *mac_dev);
12552 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12553 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12554 + int (*set_multi)(struct net_device *net_dev,
12555 + struct mac_device *mac_dev);
12556 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12557 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12558 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12559 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12560 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12561 + int (*fm_rtc_enable)(struct fm *fm_dev);
12562 + int (*fm_rtc_disable)(struct fm *fm_dev);
12563 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12564 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12565 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12566 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12567 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12568 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12569 + uint64_t fiper);
12570 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12571 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12572 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12573 +#endif
12574 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12575 + bool en);
12576 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12577 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12578 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12579 +};
12580 +
12581 +struct mac_address {
12582 + uint8_t addr[ETH_ALEN];
12583 + struct list_head list;
12584 +};
12585 +
12586 +#define get_fm_handle(net_dev) \
12587 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12588 +
12589 +#define for_each_port_device(i, port_dev) \
12590 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12591 +
12592 +static inline __attribute((nonnull)) void *macdev_priv(
12593 + const struct mac_device *mac_dev)
12594 +{
12595 + return (void *)mac_dev + sizeof(*mac_dev);
12596 +}
12597 +
12598 +extern const char *mac_driver_description;
12599 +extern const size_t mac_sizeof_priv[];
12600 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12601 +
12602 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12603 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12604 +
12605 +#endif /* __MAC_H */
12606 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12607 new file mode 100644
12608 index 00000000..fb084af5
12609 --- /dev/null
12610 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12611 @@ -0,0 +1,848 @@
12612 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12613 + *
12614 + * Redistribution and use in source and binary forms, with or without
12615 + * modification, are permitted provided that the following conditions are met:
12616 + * * Redistributions of source code must retain the above copyright
12617 + * notice, this list of conditions and the following disclaimer.
12618 + * * Redistributions in binary form must reproduce the above copyright
12619 + * notice, this list of conditions and the following disclaimer in the
12620 + * documentation and/or other materials provided with the distribution.
12621 + * * Neither the name of Freescale Semiconductor nor the
12622 + * names of its contributors may be used to endorse or promote products
12623 + * derived from this software without specific prior written permission.
12624 + *
12625 + *
12626 + * ALTERNATIVELY, this software may be distributed under the terms of the
12627 + * GNU General Public License ("GPL") as published by the Free Software
12628 + * Foundation, either version 2 of that License or (at your option) any
12629 + * later version.
12630 + *
12631 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12632 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12633 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12634 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12635 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12636 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12637 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12638 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12639 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12640 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12641 + */
12642 +
12643 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12644 + * Validates device-tree configuration and sets up the offline ports.
12645 + */
12646 +
12647 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12648 +#define pr_fmt(fmt) \
12649 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12650 + KBUILD_BASENAME".c", __LINE__, __func__
12651 +#else
12652 +#define pr_fmt(fmt) \
12653 + KBUILD_MODNAME ": " fmt
12654 +#endif
12655 +
12656 +
12657 +#include <linux/init.h>
12658 +#include <linux/module.h>
12659 +#include <linux/of_platform.h>
12660 +#include <linux/fsl_qman.h>
12661 +
12662 +#include "offline_port.h"
12663 +#include "dpaa_eth.h"
12664 +#include "dpaa_eth_common.h"
12665 +
12666 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12667 +/* Manip extra space and data alignment for fragmentation */
12668 +#define FRAG_MANIP_SPACE 128
12669 +#define FRAG_DATA_ALIGN 64
12670 +
12671 +
12672 +MODULE_LICENSE("Dual BSD/GPL");
12673 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12674 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12675 +
12676 +
12677 +static const struct of_device_id oh_port_match_table[] = {
12678 + {
12679 + .compatible = "fsl,dpa-oh"
12680 + },
12681 + {
12682 + .compatible = "fsl,dpa-oh-shared"
12683 + },
12684 + {}
12685 +};
12686 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12687 +
12688 +#ifdef CONFIG_PM
12689 +
12690 +static int oh_suspend(struct device *dev)
12691 +{
12692 + struct dpa_oh_config_s *oh_config;
12693 +
12694 + oh_config = dev_get_drvdata(dev);
12695 + return fm_port_suspend(oh_config->oh_port);
12696 +}
12697 +
12698 +static int oh_resume(struct device *dev)
12699 +{
12700 + struct dpa_oh_config_s *oh_config;
12701 +
12702 + oh_config = dev_get_drvdata(dev);
12703 + return fm_port_resume(oh_config->oh_port);
12704 +}
12705 +
12706 +static const struct dev_pm_ops oh_pm_ops = {
12707 + .suspend = oh_suspend,
12708 + .resume = oh_resume,
12709 +};
12710 +
12711 +#define OH_PM_OPS (&oh_pm_ops)
12712 +
12713 +#else /* CONFIG_PM */
12714 +
12715 +#define OH_PM_OPS NULL
12716 +
12717 +#endif /* CONFIG_PM */
12718 +
12719 +/* Creates Frame Queues */
12720 +static uint32_t oh_fq_create(struct qman_fq *fq,
12721 + uint32_t fq_id, uint16_t channel,
12722 + uint16_t wq_id)
12723 +{
12724 + struct qm_mcc_initfq fq_opts;
12725 + uint32_t create_flags, init_flags;
12726 + uint32_t ret = 0;
12727 +
12728 + if (fq == NULL)
12729 + return 1;
12730 +
12731 + /* Set flags for FQ create */
12732 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12733 +
12734 + /* Create frame queue */
12735 + ret = qman_create_fq(fq_id, create_flags, fq);
12736 + if (ret != 0)
12737 + return 1;
12738 +
12739 + /* Set flags for FQ init */
12740 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12741 +
12742 + /* Set FQ init options. Specify destination WQ ID and channel */
12743 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12744 + fq_opts.fqd.dest.wq = wq_id;
12745 + fq_opts.fqd.dest.channel = channel;
12746 +
12747 + /* Initialize frame queue */
12748 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12749 + if (ret != 0) {
12750 + qman_destroy_fq(fq, 0);
12751 + return 1;
12752 + }
12753 +
12754 + return 0;
12755 +}
12756 +
12757 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12758 +{
12759 + if (channel) {
12760 + /* display fqs with a valid (!= 0) destination channel */
12761 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12762 + }
12763 +}
12764 +
12765 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12766 + int fqs_count, uint16_t channel_id)
12767 +{
12768 + int i;
12769 + for (i = 0; i < fqs_count; i++)
12770 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12771 +}
12772 +
12773 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12774 +{
12775 + struct list_head *fq_list;
12776 + struct fq_duple *fqd;
12777 + int i;
12778 +
12779 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12780 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12781 +
12782 + /* TX queues (old initialization) */
12783 + dev_info(dev, "Initialized queues:");
12784 + for (i = 0; i < conf->egress_cnt; i++)
12785 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12786 + conf->channel);
12787 +
12788 + /* initialized ingress queues */
12789 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12790 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12791 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12792 + }
12793 +
12794 + /* initialized egress queues */
12795 + list_for_each(fq_list, &conf->fqs_egress_list) {
12796 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12797 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12798 + }
12799 +}
12800 +
12801 +/* Destroys Frame Queues */
12802 +static void oh_fq_destroy(struct qman_fq *fq)
12803 +{
12804 + int _errno = 0;
12805 +
12806 + _errno = qman_retire_fq(fq, NULL);
12807 + if (unlikely(_errno < 0))
12808 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12809 + KBUILD_BASENAME".c", __LINE__, __func__,
12810 + qman_fq_fqid(fq), _errno);
12811 +
12812 + _errno = qman_oos_fq(fq);
12813 + if (unlikely(_errno < 0)) {
12814 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12815 + KBUILD_BASENAME".c", __LINE__, __func__,
12816 + qman_fq_fqid(fq), _errno);
12817 + }
12818 +
12819 + qman_destroy_fq(fq, 0);
12820 +}
12821 +
12822 +/* Allocation code for the OH port's PCD frame queues */
12823 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12824 + uint32_t num,
12825 + uint8_t alignment,
12826 + uint32_t *base_fqid)
12827 +{
12828 + dev_crit(dev, "callback not implemented!\n");
12829 + BUG();
12830 +
12831 + return 0;
12832 +}
12833 +
12834 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12835 +{
12836 + dev_crit(dev, "callback not implemented!\n");
12837 + BUG();
12838 +
12839 + return 0;
12840 +}
12841 +
12842 +static void oh_set_buffer_layout(struct fm_port *port,
12843 + struct dpa_buffer_layout_s *layout)
12844 +{
12845 + struct fm_port_params params;
12846 +
12847 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12848 + layout->parse_results = true;
12849 + layout->hash_results = true;
12850 + layout->time_stamp = false;
12851 +
12852 + fm_port_get_buff_layout_ext_params(port, &params);
12853 + layout->manip_extra_space = params.manip_extra_space;
12854 + layout->data_align = params.data_align;
12855 +}
12856 +
12857 +static int
12858 +oh_port_probe(struct platform_device *_of_dev)
12859 +{
12860 + struct device *dpa_oh_dev;
12861 + struct device_node *dpa_oh_node;
12862 + int lenp, _errno = 0, fq_idx, duple_idx;
12863 + int n_size, i, j, ret, duples_count;
12864 + struct platform_device *oh_of_dev;
12865 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12866 + struct device *oh_dev;
12867 + struct dpa_oh_config_s *oh_config = NULL;
12868 + const __be32 *oh_all_queues;
12869 + const __be32 *channel_ids;
12870 + const __be32 *oh_tx_queues;
12871 + uint32_t queues_count;
12872 + uint32_t crt_fqid_base;
12873 + uint32_t crt_fq_count;
12874 + bool frag_enabled = false;
12875 + struct fm_port_params oh_port_tx_params;
12876 + struct fm_port_pcd_param oh_port_pcd_params;
12877 + struct dpa_buffer_layout_s buf_layout;
12878 +
12879 + /* True if the current partition owns the OH port. */
12880 + bool init_oh_port;
12881 +
12882 + const struct of_device_id *match;
12883 + int crt_ext_pools_count;
12884 + u32 ext_pool_size;
12885 + u32 port_id;
12886 + u32 channel_id;
12887 +
12888 + int channel_ids_count;
12889 + int channel_idx;
12890 + struct fq_duple *fqd;
12891 + struct list_head *fq_list, *fq_list_tmp;
12892 +
12893 + const __be32 *bpool_cfg;
12894 + uint32_t bpid;
12895 +
12896 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
12897 + dpa_oh_dev = &_of_dev->dev;
12898 + dpa_oh_node = dpa_oh_dev->of_node;
12899 + BUG_ON(dpa_oh_node == NULL);
12900 +
12901 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
12902 + if (!match)
12903 + return -EINVAL;
12904 +
12905 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
12906 +
12907 + /* Find the referenced OH node */
12908 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
12909 + if (oh_node == NULL) {
12910 + dev_err(dpa_oh_dev,
12911 + "Can't find OH node referenced from node %s\n",
12912 + dpa_oh_node->full_name);
12913 + return -EINVAL;
12914 + }
12915 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
12916 + match->compatible);
12917 +
12918 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
12919 + if (_errno) {
12920 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
12921 + dpa_oh_node->full_name);
12922 + goto return_kfree;
12923 + }
12924 +
12925 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
12926 + &channel_id);
12927 + if (_errno) {
12928 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
12929 + dpa_oh_node->full_name);
12930 + goto return_kfree;
12931 + }
12932 +
12933 + oh_of_dev = of_find_device_by_node(oh_node);
12934 + BUG_ON(oh_of_dev == NULL);
12935 + oh_dev = &oh_of_dev->dev;
12936 +
12937 + /* The OH port must be initialized exactly once.
12938 + * The following scenarios are of interest:
12939 + * - the node is Linux-private (will always initialize it);
12940 + * - the node is shared between two Linux partitions
12941 + * (only one of them will initialize it);
12942 + * - the node is shared between a Linux and a LWE partition
12943 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
12944 + */
12945 +
12946 + /* Check if the current partition owns the OH port
12947 + * and ought to initialize it. It may be the case that we leave this
12948 + * to another (also Linux) partition.
12949 + */
12950 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
12951 +
12952 + /* If we aren't the "owner" of the OH node, we're done here. */
12953 + if (!init_oh_port) {
12954 + dev_dbg(dpa_oh_dev,
12955 + "Not owning the shared OH port %s, will not initialize it.\n",
12956 + oh_node->full_name);
12957 + of_node_put(oh_node);
12958 + return 0;
12959 + }
12960 +
12961 + /* Allocate OH dev private data */
12962 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
12963 + if (oh_config == NULL) {
12964 + dev_err(dpa_oh_dev,
12965 + "Can't allocate private data for OH node %s referenced from node %s!\n",
12966 + oh_node->full_name, dpa_oh_node->full_name);
12967 + _errno = -ENOMEM;
12968 + goto return_kfree;
12969 + }
12970 +
12971 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
12972 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
12973 +
12974 + /* FQs that enter OH port */
12975 + lenp = 0;
12976 + oh_all_queues = of_get_property(dpa_oh_node,
12977 + "fsl,qman-frame-queues-ingress", &lenp);
12978 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12979 + dev_warn(dpa_oh_dev,
12980 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
12981 + oh_node->full_name, dpa_oh_node->full_name);
12982 + /* just ignore the last unpaired value */
12983 + }
12984 +
12985 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12986 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
12987 + duples_count);
12988 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12989 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12990 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12991 +
12992 + fqd = devm_kzalloc(dpa_oh_dev,
12993 + sizeof(struct fq_duple), GFP_KERNEL);
12994 + if (!fqd) {
12995 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12996 + oh_node->full_name,
12997 + dpa_oh_node->full_name);
12998 + _errno = -ENOMEM;
12999 + goto return_kfree;
13000 + }
13001 +
13002 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13003 + crt_fq_count * sizeof(struct qman_fq),
13004 + GFP_KERNEL);
13005 + if (!fqd->fqs) {
13006 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
13007 + oh_node->full_name,
13008 + dpa_oh_node->full_name);
13009 + _errno = -ENOMEM;
13010 + goto return_kfree;
13011 + }
13012 +
13013 + for (j = 0; j < crt_fq_count; j++)
13014 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13015 + fqd->fqs_count = crt_fq_count;
13016 + fqd->channel_id = (uint16_t)channel_id;
13017 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
13018 + }
13019 +
13020 + /* create the ingress queues */
13021 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
13022 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13023 +
13024 + for (j = 0; j < fqd->fqs_count; j++) {
13025 + ret = oh_fq_create(fqd->fqs + j,
13026 + (fqd->fqs + j)->fqid,
13027 + fqd->channel_id, 3);
13028 + if (ret != 0) {
13029 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
13030 + (fqd->fqs + j)->fqid,
13031 + oh_node->full_name,
13032 + dpa_oh_node->full_name);
13033 + _errno = -EINVAL;
13034 + goto return_kfree;
13035 + }
13036 + }
13037 + }
13038 +
13039 + /* FQs that exit OH port */
13040 + lenp = 0;
13041 + oh_all_queues = of_get_property(dpa_oh_node,
13042 + "fsl,qman-frame-queues-egress", &lenp);
13043 + if (lenp % (2 * sizeof(*oh_all_queues))) {
13044 + dev_warn(dpa_oh_dev,
13045 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
13046 + oh_node->full_name, dpa_oh_node->full_name);
13047 + /* just ignore the last unpaired value */
13048 + }
13049 +
13050 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
13051 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
13052 + duples_count);
13053 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
13054 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
13055 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
13056 +
13057 + fqd = devm_kzalloc(dpa_oh_dev,
13058 + sizeof(struct fq_duple), GFP_KERNEL);
13059 + if (!fqd) {
13060 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13061 + oh_node->full_name,
13062 + dpa_oh_node->full_name);
13063 + _errno = -ENOMEM;
13064 + goto return_kfree;
13065 + }
13066 +
13067 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13068 + crt_fq_count * sizeof(struct qman_fq),
13069 + GFP_KERNEL);
13070 + if (!fqd->fqs) {
13071 + dev_err(dpa_oh_dev,
13072 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13073 + oh_node->full_name,
13074 + dpa_oh_node->full_name);
13075 + _errno = -ENOMEM;
13076 + goto return_kfree;
13077 + }
13078 +
13079 + for (j = 0; j < crt_fq_count; j++)
13080 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13081 + fqd->fqs_count = crt_fq_count;
13082 + /* channel ID is specified in another attribute */
13083 + fqd->channel_id = 0;
13084 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13085 +
13086 + /* allocate the queue */
13087 +
13088 + }
13089 +
13090 + /* channel_ids for FQs that exit OH port */
13091 + lenp = 0;
13092 + channel_ids = of_get_property(dpa_oh_node,
13093 + "fsl,qman-channel-ids-egress", &lenp);
13094 +
13095 + channel_ids_count = lenp / (sizeof(*channel_ids));
13096 + if (channel_ids_count != duples_count) {
13097 + dev_warn(dpa_oh_dev,
13098 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13099 + oh_node->full_name, dpa_oh_node->full_name);
13100 + /* just ignore the queues that do not have a Channel ID */
13101 + }
13102 +
13103 + channel_idx = 0;
13104 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13105 + if (channel_idx + 1 > channel_ids_count)
13106 + break;
13107 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13108 + fqd->channel_id =
13109 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13110 + }
13111 +
13112 + /* create egress queues */
13113 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13114 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13115 +
13116 + if (fqd->channel_id == 0) {
13117 + /* missing channel id in dts */
13118 + continue;
13119 + }
13120 +
13121 + for (j = 0; j < fqd->fqs_count; j++) {
13122 + ret = oh_fq_create(fqd->fqs + j,
13123 + (fqd->fqs + j)->fqid,
13124 + fqd->channel_id, 3);
13125 + if (ret != 0) {
13126 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13127 + (fqd->fqs + j)->fqid,
13128 + oh_node->full_name,
13129 + dpa_oh_node->full_name);
13130 + _errno = -EINVAL;
13131 + goto return_kfree;
13132 + }
13133 + }
13134 + }
13135 +
13136 + /* Read FQ ids/nums for the DPA OH node */
13137 + oh_all_queues = of_get_property(dpa_oh_node,
13138 + "fsl,qman-frame-queues-oh", &lenp);
13139 + if (oh_all_queues == NULL) {
13140 + dev_err(dpa_oh_dev,
13141 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13142 + oh_node->full_name, dpa_oh_node->full_name);
13143 + _errno = -EINVAL;
13144 + goto return_kfree;
13145 + }
13146 +
13147 + /* Check that the OH error and default FQs are there */
13148 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13149 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13150 + if (queues_count != 2) {
13151 + dev_err(dpa_oh_dev,
13152 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13153 + oh_node->full_name, dpa_oh_node->full_name);
13154 + _errno = -EINVAL;
13155 + goto return_kfree;
13156 + }
13157 +
13158 + /* Read the FQIDs defined for this OH port */
13159 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13160 + fq_idx = 0;
13161 +
13162 + /* Error FQID - must be present */
13163 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13164 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13165 + if (crt_fq_count != 1) {
13166 + dev_err(dpa_oh_dev,
13167 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13168 + oh_node->full_name, dpa_oh_node->full_name,
13169 + crt_fq_count);
13170 + _errno = -EINVAL;
13171 + goto return_kfree;
13172 + }
13173 + oh_config->error_fqid = crt_fqid_base;
13174 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13175 + oh_config->error_fqid, oh_node->full_name);
13176 +
13177 + /* Default FQID - must be present */
13178 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13179 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13180 + if (crt_fq_count != 1) {
13181 + dev_err(dpa_oh_dev,
13182 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13183 + oh_node->full_name, dpa_oh_node->full_name,
13184 + crt_fq_count);
13185 + _errno = -EINVAL;
13186 + goto return_kfree;
13187 + }
13188 + oh_config->default_fqid = crt_fqid_base;
13189 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13190 + oh_config->default_fqid, oh_node->full_name);
13191 +
13192 + /* TX FQID - presence is optional */
13193 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13194 + &lenp);
13195 + if (oh_tx_queues == NULL) {
13196 + dev_dbg(dpa_oh_dev,
13197 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13198 + oh_node->full_name, dpa_oh_node->full_name);
13199 + goto config_port;
13200 + }
13201 +
13202 + /* Check that queues-tx has only a base and a count defined */
13203 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13204 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13205 + if (queues_count != 1) {
13206 + dev_err(dpa_oh_dev,
13207 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13208 + oh_node->full_name, dpa_oh_node->full_name);
13209 + _errno = -EINVAL;
13210 + goto return_kfree;
13211 + }
13212 +
13213 + fq_idx = 0;
13214 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13215 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13216 + oh_config->egress_cnt = crt_fq_count;
13217 +
13218 + /* Allocate TX queues */
13219 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13220 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13221 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13222 + if (oh_config->egress_fqs == NULL) {
13223 + dev_err(dpa_oh_dev,
13224 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13225 + oh_node->full_name, dpa_oh_node->full_name);
13226 + _errno = -ENOMEM;
13227 + goto return_kfree;
13228 + }
13229 +
13230 + /* Create TX queues */
13231 + for (i = 0; i < crt_fq_count; i++) {
13232 + ret = oh_fq_create(oh_config->egress_fqs + i,
13233 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13234 + if (ret != 0) {
13235 + dev_err(dpa_oh_dev,
13236 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13237 + crt_fqid_base + i, oh_node->full_name,
13238 + dpa_oh_node->full_name);
13239 + _errno = -EINVAL;
13240 + goto return_kfree;
13241 + }
13242 + }
13243 +
13244 +config_port:
13245 + /* Get a handle to the fm_port so we can set
13246 + * its configuration params
13247 + */
13248 + oh_config->oh_port = fm_port_bind(oh_dev);
13249 + if (oh_config->oh_port == NULL) {
13250 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13251 + oh_node->full_name);
13252 + _errno = -EINVAL;
13253 + goto return_kfree;
13254 + }
13255 +
13256 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13257 +
13258 + /* read the pool handlers */
13259 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13260 + "fsl,bman-buffer-pools", NULL);
13261 + if (crt_ext_pools_count <= 0) {
13262 + dev_info(dpa_oh_dev,
13263 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13264 + oh_node->full_name);
13265 + goto init_port;
13266 + }
13267 +
13268 + /* used for reading ext_pool_size*/
13269 + root_node = of_find_node_by_path("/");
13270 + if (root_node == NULL) {
13271 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13272 + _errno = -EINVAL;
13273 + goto return_kfree;
13274 + }
13275 +
13276 + n_size = of_n_size_cells(root_node);
13277 + of_node_put(root_node);
13278 +
13279 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13280 + crt_ext_pools_count);
13281 +
13282 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13283 +
13284 + for (i = 0; i < crt_ext_pools_count; i++) {
13285 + bpool_node = of_parse_phandle(dpa_oh_node,
13286 + "fsl,bman-buffer-pools", i);
13287 + if (bpool_node == NULL) {
13288 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13289 + _errno = -EINVAL;
13290 + goto return_kfree;
13291 + }
13292 +
13293 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13294 + if (_errno) {
13295 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13296 + _errno = -EINVAL;
13297 + goto return_kfree;
13298 + }
13299 +
13300 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13301 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13302 +
13303 + bpool_cfg = of_get_property(bpool_node,
13304 + "fsl,bpool-ethernet-cfg", &lenp);
13305 + if (bpool_cfg == NULL) {
13306 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13307 + _errno = -EINVAL;
13308 + goto return_kfree;
13309 + }
13310 +
13311 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13312 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13313 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13314 + ext_pool_size);
13315 + of_node_put(bpool_node);
13316 +
13317 + }
13318 +
13319 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13320 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13321 + goto init_port;
13322 +
13323 + frag_enabled = true;
13324 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13325 + port_id);
13326 +
13327 +init_port:
13328 + of_node_put(oh_node);
13329 + /* Set Tx params */
13330 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13331 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13332 + frag_enabled);
13333 + /* Set PCD params */
13334 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13335 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13336 + oh_port_pcd_params.dev = dpa_oh_dev;
13337 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13338 +
13339 + dev_set_drvdata(dpa_oh_dev, oh_config);
13340 +
13341 + /* Enable the OH port */
13342 + _errno = fm_port_enable(oh_config->oh_port);
13343 + if (_errno)
13344 + goto return_kfree;
13345 +
13346 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13347 +
13348 + /* print of all referenced & created queues */
13349 + dump_oh_config(dpa_oh_dev, oh_config);
13350 +
13351 + return 0;
13352 +
13353 +return_kfree:
13354 + if (bpool_node)
13355 + of_node_put(bpool_node);
13356 + if (oh_node)
13357 + of_node_put(oh_node);
13358 + if (oh_config && oh_config->egress_fqs)
13359 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13360 +
13361 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13362 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13363 + list_del(fq_list);
13364 + devm_kfree(dpa_oh_dev, fqd->fqs);
13365 + devm_kfree(dpa_oh_dev, fqd);
13366 + }
13367 +
13368 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13369 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13370 + list_del(fq_list);
13371 + devm_kfree(dpa_oh_dev, fqd->fqs);
13372 + devm_kfree(dpa_oh_dev, fqd);
13373 + }
13374 +
13375 + devm_kfree(dpa_oh_dev, oh_config);
13376 + return _errno;
13377 +}
13378 +
13379 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13380 +{
13381 + int _errno = 0, i;
13382 + struct dpa_oh_config_s *oh_config;
13383 +
13384 + pr_info("Removing OH port...\n");
13385 +
13386 + oh_config = dev_get_drvdata(&_of_dev->dev);
13387 + if (oh_config == NULL) {
13388 + pr_err(KBUILD_MODNAME
13389 + ": %s:%hu:%s(): No OH config in device private data!\n",
13390 + KBUILD_BASENAME".c", __LINE__, __func__);
13391 + _errno = -ENODEV;
13392 + goto return_error;
13393 + }
13394 +
13395 + if (oh_config->egress_fqs)
13396 + for (i = 0; i < oh_config->egress_cnt; i++)
13397 + oh_fq_destroy(oh_config->egress_fqs + i);
13398 +
13399 + if (oh_config->oh_port == NULL) {
13400 + pr_err(KBUILD_MODNAME
13401 + ": %s:%hu:%s(): No fm port in device private data!\n",
13402 + KBUILD_BASENAME".c", __LINE__, __func__);
13403 + _errno = -EINVAL;
13404 + goto free_egress_fqs;
13405 + }
13406 +
13407 + _errno = fm_port_disable(oh_config->oh_port);
13408 +
13409 +free_egress_fqs:
13410 + if (oh_config->egress_fqs)
13411 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13412 + devm_kfree(&_of_dev->dev, oh_config);
13413 + dev_set_drvdata(&_of_dev->dev, NULL);
13414 +
13415 +return_error:
13416 + return _errno;
13417 +}
13418 +
13419 +static struct platform_driver oh_port_driver = {
13420 + .driver = {
13421 + .name = KBUILD_MODNAME,
13422 + .of_match_table = oh_port_match_table,
13423 + .owner = THIS_MODULE,
13424 + .pm = OH_PM_OPS,
13425 + },
13426 + .probe = oh_port_probe,
13427 + .remove = oh_port_remove
13428 +};
13429 +
13430 +static int __init __cold oh_port_load(void)
13431 +{
13432 + int _errno;
13433 +
13434 + pr_info(OH_MOD_DESCRIPTION "\n");
13435 +
13436 + _errno = platform_driver_register(&oh_port_driver);
13437 + if (_errno < 0) {
13438 + pr_err(KBUILD_MODNAME
13439 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13440 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13441 + }
13442 +
13443 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13444 + KBUILD_BASENAME".c", __func__);
13445 + return _errno;
13446 +}
13447 +module_init(oh_port_load);
13448 +
13449 +static void __exit __cold oh_port_unload(void)
13450 +{
13451 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13452 + KBUILD_BASENAME".c", __func__);
13453 +
13454 + platform_driver_unregister(&oh_port_driver);
13455 +
13456 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13457 + KBUILD_BASENAME".c", __func__);
13458 +}
13459 +module_exit(oh_port_unload);
13460 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13461 new file mode 100644
13462 index 00000000..432ee88d
13463 --- /dev/null
13464 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13465 @@ -0,0 +1,59 @@
13466 +/* Copyright 2011 Freescale Semiconductor Inc.
13467 + *
13468 + * Redistribution and use in source and binary forms, with or without
13469 + * modification, are permitted provided that the following conditions are met:
13470 + * * Redistributions of source code must retain the above copyright
13471 + * notice, this list of conditions and the following disclaimer.
13472 + * * Redistributions in binary form must reproduce the above copyright
13473 + * notice, this list of conditions and the following disclaimer in the
13474 + * documentation and/or other materials provided with the distribution.
13475 + * * Neither the name of Freescale Semiconductor nor the
13476 + * names of its contributors may be used to endorse or promote products
13477 + * derived from this software without specific prior written permission.
13478 + *
13479 + *
13480 + * ALTERNATIVELY, this software may be distributed under the terms of the
13481 + * GNU General Public License ("GPL") as published by the Free Software
13482 + * Foundation, either version 2 of that License or (at your option) any
13483 + * later version.
13484 + *
13485 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13486 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13487 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13488 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13489 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13490 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13491 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13492 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13493 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13494 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13495 + */
13496 +
13497 +#ifndef __OFFLINE_PORT_H
13498 +#define __OFFLINE_PORT_H
13499 +
13500 +struct fm_port;
13501 +struct qman_fq;
13502 +
13503 +/* fqs are defined in duples (base_fq, fq_count) */
13504 +struct fq_duple {
13505 + struct qman_fq *fqs;
13506 + int fqs_count;
13507 + uint16_t channel_id;
13508 + struct list_head fq_list;
13509 +};
13510 +
13511 +/* OH port configuration */
13512 +struct dpa_oh_config_s {
13513 + uint32_t error_fqid;
13514 + uint32_t default_fqid;
13515 + struct fm_port *oh_port;
13516 + uint32_t egress_cnt;
13517 + struct qman_fq *egress_fqs;
13518 + uint16_t channel;
13519 +
13520 + struct list_head fqs_ingress_list;
13521 + struct list_head fqs_egress_list;
13522 +};
13523 +
13524 +#endif /* __OFFLINE_PORT_H */
13525 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Kconfig b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13526 new file mode 100644
13527 index 00000000..d98c0989
13528 --- /dev/null
13529 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13530 @@ -0,0 +1,153 @@
13531 +menu "Frame Manager support"
13532 +
13533 +menuconfig FSL_SDK_FMAN
13534 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13535 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13536 + default y
13537 + ---help---
13538 + If unsure, say Y.
13539 +
13540 +if FSL_SDK_FMAN
13541 +
13542 +config FSL_SDK_FMAN_TEST
13543 + bool "FMan test module"
13544 + default n
13545 + select FSL_DPAA_HOOKS
13546 + ---help---
13547 + This option compiles test code for FMan.
13548 +
13549 +menu "FMAN Processor support"
13550 +choice
13551 + depends on FSL_SDK_FMAN
13552 + prompt "Processor Type"
13553 +
13554 +config FMAN_ARM
13555 + bool "LS1043"
13556 + depends on ARM64 || ARM
13557 + ---help---
13558 + Choose "LS1043" for the ARM platforms:
13559 + LS1043
13560 +
13561 +config FMAN_P3040_P4080_P5020
13562 + bool "P3040 P4080 5020"
13563 +
13564 +config FMAN_P1023
13565 + bool "P1023"
13566 +
13567 +config FMAN_V3H
13568 + bool "FmanV3H"
13569 + ---help---
13570 + Choose "FmanV3H" for Fman rev3H:
13571 + B4860, T4240, T4160, etc
13572 +
13573 +config FMAN_V3L
13574 + bool "FmanV3L"
13575 + ---help---
13576 + Choose "FmanV3L" for Fman rev3L:
13577 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13578 +
13579 +endchoice
13580 +endmenu
13581 +
13582 +config FMAN_MIB_CNT_OVF_IRQ_EN
13583 + bool "Enable the dTSEC MIB counters overflow interrupt"
13584 + default n
13585 + ---help---
13586 + Enable the dTSEC MIB counters overflow interrupt to get
13587 + accurate MIB counters values. Enabled it compensates
13588 + for the counters overflow but reduces performance and
13589 + triggers error messages in HV setups.
13590 +
13591 +config FSL_FM_MAX_FRAME_SIZE
13592 + int "Maximum L2 frame size"
13593 + depends on FSL_SDK_FMAN
13594 + range 64 9600
13595 + default "1522"
13596 + help
13597 + Configure this in relation to the maximum possible MTU of your
13598 + network configuration. In particular, one would need to
13599 + increase this value in order to use jumbo frames.
13600 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13601 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13602 + excess of the desired L3 MTU.
13603 +
13604 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13605 + than the actual MTU) may lead to buffer exhaustion, especially
13606 + in the case of badly fragmented datagrams on the Rx path.
13607 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13608 + MTU will lead to frames being dropped.
13609 +
13610 + This can be overridden by specifying "fsl_fm_max_frm" in
13611 + the kernel bootargs:
13612 + * in Hypervisor-based scenarios, by adding a "chosen" node
13613 + with the "bootargs" property specifying
13614 + "fsl_fm_max_frm=<YourValue>";
13615 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13616 + modifying the "bootargs" env variable.
13617 +
13618 +config FSL_FM_RX_EXTRA_HEADROOM
13619 + int "Add extra headroom at beginning of data buffers"
13620 + depends on FSL_SDK_FMAN
13621 + range 16 384
13622 + default "64"
13623 + help
13624 + Configure this to tell the Frame Manager to reserve some extra
13625 + space at the beginning of a data buffer on the receive path,
13626 + before Internal Context fields are copied. This is in addition
13627 + to the private data area already reserved for driver internal
13628 + use. The provided value must be a multiple of 16.
13629 +
13630 + This setting can be overridden by specifying
13631 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13632 + * in Hypervisor-based scenarios, by adding a "chosen" node
13633 + with the "bootargs" property specifying
13634 + "fsl_fm_rx_extra_headroom=<YourValue>";
13635 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13636 + modifying the "bootargs" env variable.
13637 +
13638 +config FMAN_PFC
13639 + bool "FMan PFC support (EXPERIMENTAL)"
13640 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13641 + default n
13642 + help
13643 + This option enables PFC support on FMan v3 ports.
13644 + Data Center Bridging defines Classes of Service that are
13645 + flow-controlled using PFC pause frames.
13646 +
13647 +if FMAN_PFC
13648 +config FMAN_PFC_COS_COUNT
13649 + int "Number of PFC Classes of Service"
13650 + depends on FMAN_PFC && FSL_SDK_FMAN
13651 + range 1 4
13652 + default "3"
13653 + help
13654 + The number of Classes of Service controlled by PFC.
13655 +
13656 +config FMAN_PFC_QUANTA_0
13657 + int "The pause quanta for PFC CoS 0"
13658 + depends on FMAN_PFC && FSL_SDK_FMAN
13659 + range 0 65535
13660 + default "65535"
13661 +
13662 +config FMAN_PFC_QUANTA_1
13663 + int "The pause quanta for PFC CoS 1"
13664 + depends on FMAN_PFC && FSL_SDK_FMAN
13665 + range 0 65535
13666 + default "65535"
13667 +
13668 +config FMAN_PFC_QUANTA_2
13669 + int "The pause quanta for PFC CoS 2"
13670 + depends on FMAN_PFC && FSL_SDK_FMAN
13671 + range 0 65535
13672 + default "65535"
13673 +
13674 +config FMAN_PFC_QUANTA_3
13675 + int "The pause quanta for PFC CoS 3"
13676 + depends on FMAN_PFC && FSL_SDK_FMAN
13677 + range 0 65535
13678 + default "65535"
13679 +endif
13680 +
13681 +endif # FSL_SDK_FMAN
13682 +
13683 +endmenu
13684 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13685 new file mode 100644
13686 index 00000000..25ce7e6a
13687 --- /dev/null
13688 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13689 @@ -0,0 +1,11 @@
13690 +#
13691 +# Makefile for the Freescale Ethernet controllers
13692 +#
13693 +ccflags-y += -DVERSION=\"\"
13694 +#
13695 +#Include netcomm SW specific definitions
13696 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13697 +#
13698 +obj-y += etc/
13699 +obj-y += Peripherals/FM/
13700 +obj-y += src/
13701 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13702 new file mode 100644
13703 index 00000000..d0e76727
13704 --- /dev/null
13705 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13706 @@ -0,0 +1,15 @@
13707 +#
13708 +# Makefile for the Freescale Ethernet controllers
13709 +#
13710 +ccflags-y += -DVERSION=\"\"
13711 +#
13712 +#Include netcomm SW specific definitions
13713 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13714 +
13715 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13716 +
13717 +ccflags-y += -I$(NCSW_FM_INC)
13718 +
13719 +obj-y += fsl-ncsw-Hc.o
13720 +
13721 +fsl-ncsw-Hc-objs := hc.o
13722 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13723 new file mode 100644
13724 index 00000000..363c8f95
13725 --- /dev/null
13726 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13727 @@ -0,0 +1,1232 @@
13728 +/*
13729 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13730 + *
13731 + * Redistribution and use in source and binary forms, with or without
13732 + * modification, are permitted provided that the following conditions are met:
13733 + * * Redistributions of source code must retain the above copyright
13734 + * notice, this list of conditions and the following disclaimer.
13735 + * * Redistributions in binary form must reproduce the above copyright
13736 + * notice, this list of conditions and the following disclaimer in the
13737 + * documentation and/or other materials provided with the distribution.
13738 + * * Neither the name of Freescale Semiconductor nor the
13739 + * names of its contributors may be used to endorse or promote products
13740 + * derived from this software without specific prior written permission.
13741 + *
13742 + *
13743 + * ALTERNATIVELY, this software may be distributed under the terms of the
13744 + * GNU General Public License ("GPL") as published by the Free Software
13745 + * Foundation, either version 2 of that License or (at your option) any
13746 + * later version.
13747 + *
13748 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13749 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13750 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13751 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13752 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13753 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13754 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13755 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13756 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13757 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13758 + */
13759 +
13760 +
13761 +#include "std_ext.h"
13762 +#include "error_ext.h"
13763 +#include "sprint_ext.h"
13764 +#include "string_ext.h"
13765 +
13766 +#include "fm_common.h"
13767 +#include "fm_hc.h"
13768 +
13769 +
13770 +/**************************************************************************//**
13771 + @Description defaults
13772 +*//***************************************************************************/
13773 +#define DEFAULT_dataMemId 0
13774 +
13775 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13776 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13777 +#define HC_HCOR_OPCODE_SYNC 0x2
13778 +#define HC_HCOR_OPCODE_CC 0x3
13779 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13780 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13781 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13782 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13783 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13784 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13785 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13786 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13787 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13788 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13789 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13790 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13791 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13792 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13793 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13794 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13795 +
13796 +#define HC_HCOR_GBL 0x20000000
13797 +
13798 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13799 +
13800 +#if (DPAA_VERSION == 10)
13801 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13802 +#else
13803 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13804 +#endif /* (DPAA_VERSION == 10) */
13805 +
13806 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13807 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13808 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13809 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13810 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13811 +
13812 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13813 +
13814 +#define BUILD_FD(len) \
13815 +do { \
13816 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13817 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13818 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13819 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13820 +} while (0)
13821 +
13822 +
13823 +#if defined(__MWERKS__) && !defined(__GNUC__)
13824 +#pragma pack(push,1)
13825 +#endif /* defined(__MWERKS__) && ... */
13826 +
13827 +typedef struct t_FmPcdKgPortRegs {
13828 + volatile uint32_t spReg;
13829 + volatile uint32_t cppReg;
13830 +} t_FmPcdKgPortRegs;
13831 +
13832 +typedef struct t_HcFrame {
13833 + volatile uint32_t opcode;
13834 + volatile uint32_t actionReg;
13835 + volatile uint32_t extraReg;
13836 + volatile uint32_t commandSequence;
13837 + union {
13838 + struct fman_kg_scheme_regs schemeRegs;
13839 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13840 + t_FmPcdPlcrProfileRegs profileRegs;
13841 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13842 + t_FmPcdKgPortRegs portRegsForRead;
13843 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13844 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13845 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13846 + } hcSpecificData;
13847 +} t_HcFrame;
13848 +
13849 +#if defined(__MWERKS__) && !defined(__GNUC__)
13850 +#pragma pack(pop)
13851 +#endif /* defined(__MWERKS__) && ... */
13852 +
13853 +
13854 +typedef struct t_FmHc {
13855 + t_Handle h_FmPcd;
13856 + t_Handle h_HcPortDev;
13857 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13858 + t_Handle h_QmArg; /**< A handle to the QM module */
13859 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13860 +
13861 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13862 + taking buffer */
13863 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13864 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13865 + and not confirmed yet */
13866 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13867 +} t_FmHc;
13868 +
13869 +
13870 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13871 +{
13872 + uint32_t i;
13873 +
13874 + ASSERT_COND(p_FmHc);
13875 +
13876 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13877 + {
13878 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13879 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13880 + p_FmHc->dataMemId,
13881 + 16);
13882 +#else
13883 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13884 + p_FmHc->dataMemId,
13885 + 16);
13886 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13887 + if (!p_FmHc->p_Frm[i])
13888 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13889 + }
13890 +
13891 + /* Initialize FIFO of seqNum to use during GetBuf */
13892 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13893 + {
13894 + p_FmHc->seqNum[i] = i;
13895 + }
13896 + p_FmHc->nextSeqNumLocation = 0;
13897 +
13898 + return E_OK;
13899 +}
13900 +
13901 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13902 +{
13903 + uint32_t intFlags;
13904 +
13905 + ASSERT_COND(p_FmHc);
13906 +
13907 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13908 +
13909 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
13910 + {
13911 + /* No more buffers */
13912 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13913 + return NULL;
13914 + }
13915 +
13916 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
13917 + p_FmHc->nextSeqNumLocation++;
13918 +
13919 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13920 + return p_FmHc->p_Frm[*p_SeqNum];
13921 +}
13922 +
13923 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
13924 +{
13925 + uint32_t intFlags;
13926 +
13927 + UNUSED(p_Buf);
13928 +
13929 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13930 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
13931 + p_FmHc->nextSeqNumLocation--;
13932 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
13933 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13934 +}
13935 +
13936 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
13937 +{
13938 + t_Error err = E_OK;
13939 + uint32_t intFlags;
13940 + uint32_t timeout=100;
13941 +
13942 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13943 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
13944 + p_FmHc->enqueued[seqNum] = TRUE;
13945 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13946 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
13947 + seqNum,
13948 + DPAA_FD_GET_ADDR(p_FmFd),
13949 + DPAA_FD_GET_OFFSET(p_FmFd)));
13950 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
13951 + if (err)
13952 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
13953 +
13954 + while (p_FmHc->enqueued[seqNum] && --timeout)
13955 + XX_UDelay(100);
13956 +
13957 + if (!timeout)
13958 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
13959 +
13960 + return err;
13961 +}
13962 +
13963 +
13964 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
13965 +{
13966 + t_FmHc *p_FmHc;
13967 + t_FmPortParams fmPortParam;
13968 + t_Error err;
13969 +
13970 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
13971 + if (!p_FmHc)
13972 + {
13973 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
13974 + return NULL;
13975 + }
13976 + memset(p_FmHc,0,sizeof(t_FmHc));
13977 +
13978 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
13979 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
13980 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
13981 + p_FmHc->dataMemId = DEFAULT_dataMemId;
13982 +
13983 + err = FillBufPool(p_FmHc);
13984 + if (err != E_OK)
13985 + {
13986 + REPORT_ERROR(MAJOR, err, NO_MSG);
13987 + FmHcFree(p_FmHc);
13988 + return NULL;
13989 + }
13990 +
13991 + if (!FmIsMaster(p_FmHcParams->h_Fm))
13992 + return (t_Handle)p_FmHc;
13993 +
13994 + memset(&fmPortParam, 0, sizeof(fmPortParam));
13995 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
13996 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
13997 + fmPortParam.portId = p_FmHcParams->params.portId;
13998 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
13999 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
14000 +
14001 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
14002 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
14003 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
14004 +
14005 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
14006 + if (!p_FmHc->h_HcPortDev)
14007 + {
14008 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
14009 + XX_Free(p_FmHc);
14010 + return NULL;
14011 + }
14012 +
14013 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
14014 + (uint16_t)sizeof(t_HcFrame));
14015 +
14016 + if (err != E_OK)
14017 + {
14018 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14019 + FmHcFree(p_FmHc);
14020 + return NULL;
14021 + }
14022 +
14023 + /* final init */
14024 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
14025 + if (err != E_OK)
14026 + {
14027 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14028 + FmHcFree(p_FmHc);
14029 + return NULL;
14030 + }
14031 +
14032 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
14033 + if (err != E_OK)
14034 + {
14035 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
14036 + FmHcFree(p_FmHc);
14037 + return NULL;
14038 + }
14039 +
14040 + return (t_Handle)p_FmHc;
14041 +}
14042 +
14043 +void FmHcFree(t_Handle h_FmHc)
14044 +{
14045 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14046 + int i;
14047 +
14048 + if (!p_FmHc)
14049 + return;
14050 +
14051 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14052 + if (p_FmHc->p_Frm[i])
14053 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14054 + else
14055 + break;
14056 +
14057 + if (p_FmHc->h_HcPortDev)
14058 + FM_PORT_Free(p_FmHc->h_HcPortDev);
14059 +
14060 + XX_Free(p_FmHc);
14061 +}
14062 +
14063 +/*****************************************************************************/
14064 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
14065 + uint8_t memId)
14066 +{
14067 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14068 + int i;
14069 +
14070 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14071 +
14072 + p_FmHc->dataMemId = memId;
14073 +
14074 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14075 + if (p_FmHc->p_Frm[i])
14076 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14077 +
14078 + return FillBufPool(p_FmHc);
14079 +}
14080 +
14081 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
14082 +{
14083 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14084 + t_HcFrame *p_HcFrame;
14085 + uint32_t intFlags;
14086 +
14087 + ASSERT_COND(p_FmHc);
14088 +
14089 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14090 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
14091 +
14092 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
14093 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
14094 +
14095 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
14096 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
14097 + else
14098 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
14099 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14100 +}
14101 +
14102 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14103 + t_Handle h_Scheme,
14104 + struct fman_kg_scheme_regs *p_SchemeRegs,
14105 + bool updateCounter)
14106 +{
14107 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14108 + t_Error err = E_OK;
14109 + t_HcFrame *p_HcFrame;
14110 + t_DpaaFD fmFd;
14111 + uint8_t physicalSchemeId;
14112 + uint32_t seqNum;
14113 +
14114 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14115 + if (!p_HcFrame)
14116 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14117 +
14118 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14119 +
14120 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14121 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14122 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
14123 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14124 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14125 + if (!updateCounter)
14126 + {
14127 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14128 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14129 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14130 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14131 + }
14132 + p_HcFrame->commandSequence = seqNum;
14133 +
14134 + BUILD_FD(sizeof(t_HcFrame));
14135 +
14136 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14137 +
14138 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14139 +
14140 + if (err != E_OK)
14141 + RETURN_ERROR(MINOR, err, NO_MSG);
14142 +
14143 + return E_OK;
14144 +}
14145 +
14146 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14147 +{
14148 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14149 + t_Error err = E_OK;
14150 + t_HcFrame *p_HcFrame;
14151 + t_DpaaFD fmFd;
14152 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14153 + uint32_t seqNum;
14154 +
14155 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14156 + if (!p_HcFrame)
14157 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14158 +
14159 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14160 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14161 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14162 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14163 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14164 + p_HcFrame->commandSequence = seqNum;
14165 +
14166 + BUILD_FD(sizeof(t_HcFrame));
14167 +
14168 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14169 +
14170 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14171 +
14172 + if (err != E_OK)
14173 + RETURN_ERROR(MINOR, err, NO_MSG);
14174 +
14175 + return E_OK;
14176 +}
14177 +
14178 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14179 +{
14180 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14181 + t_Error err = E_OK;
14182 + t_HcFrame *p_HcFrame;
14183 + t_DpaaFD fmFd;
14184 + uint8_t relativeSchemeId;
14185 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14186 + uint32_t tmpReg32 = 0;
14187 + uint32_t seqNum;
14188 +
14189 + /* Scheme is locked by calling routine */
14190 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14191 + * "kgse_mode" or "kgse_om" without locking scheme !
14192 + */
14193 +
14194 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14195 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14196 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14197 +
14198 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14199 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14200 + {
14201 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14202 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14203 + {
14204 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14205 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14206 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14207 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14208 + if (err)
14209 + RETURN_ERROR(MAJOR, err, NO_MSG);
14210 + }
14211 + else /* From here we deal with KG-Schemes only */
14212 + {
14213 + /* Pre change general code */
14214 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14215 + if (!p_HcFrame)
14216 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14217 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14218 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14219 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14220 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14221 + p_HcFrame->commandSequence = seqNum;
14222 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14223 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14224 + {
14225 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14226 + RETURN_ERROR(MINOR, err, NO_MSG);
14227 + }
14228 +
14229 + /* specific change */
14230 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14231 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14232 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14233 + {
14234 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14235 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14236 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14237 + }
14238 +
14239 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14240 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14241 + {
14242 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14243 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14244 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14245 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14246 + }
14247 +
14248 + if (requiredAction & UPDATE_KG_OPT_MODE)
14249 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14250 +
14251 + if (requiredAction & UPDATE_KG_NIA)
14252 + {
14253 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14254 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14255 + tmpReg32 |= value;
14256 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14257 + }
14258 +
14259 + /* Post change general code */
14260 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14261 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14262 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14263 +
14264 + BUILD_FD(sizeof(t_HcFrame));
14265 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14266 +
14267 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14268 +
14269 + if (err != E_OK)
14270 + RETURN_ERROR(MINOR, err, NO_MSG);
14271 + }
14272 + }
14273 +
14274 + return E_OK;
14275 +}
14276 +
14277 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14278 +{
14279 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14280 + t_Error err;
14281 + t_HcFrame *p_HcFrame;
14282 + t_DpaaFD fmFd;
14283 + uint32_t retVal;
14284 + uint8_t relativeSchemeId;
14285 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14286 + uint32_t seqNum;
14287 +
14288 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14289 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14290 + {
14291 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14292 + return 0;
14293 + }
14294 +
14295 + /* first read scheme and check that it is valid */
14296 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14297 + if (!p_HcFrame)
14298 + {
14299 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14300 + return 0;
14301 + }
14302 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14303 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14304 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14305 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14306 + p_HcFrame->commandSequence = seqNum;
14307 +
14308 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14309 +
14310 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14311 + if (err != E_OK)
14312 + {
14313 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14314 + REPORT_ERROR(MINOR, err, NO_MSG);
14315 + return 0;
14316 + }
14317 +
14318 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14319 + {
14320 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14321 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14322 + return 0;
14323 + }
14324 +
14325 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14326 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14327 +
14328 + return retVal;
14329 +}
14330 +
14331 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14332 +{
14333 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14334 + t_Error err = E_OK;
14335 + t_HcFrame *p_HcFrame;
14336 + t_DpaaFD fmFd;
14337 + uint8_t relativeSchemeId, physicalSchemeId;
14338 + uint32_t seqNum;
14339 +
14340 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14341 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14342 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14343 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14344 +
14345 + /* first read scheme and check that it is valid */
14346 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14347 + if (!p_HcFrame)
14348 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14349 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14350 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14351 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14352 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14353 + /* write counter */
14354 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14355 + p_HcFrame->commandSequence = seqNum;
14356 +
14357 + BUILD_FD(sizeof(t_HcFrame));
14358 +
14359 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14360 +
14361 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14362 + return err;
14363 +}
14364 +
14365 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14366 +{
14367 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14368 + t_HcFrame *p_HcFrame;
14369 + t_DpaaFD fmFd;
14370 + uint8_t i, idx;
14371 + uint32_t seqNum;
14372 + t_Error err = E_OK;
14373 +
14374 + ASSERT_COND(p_FmHc);
14375 +
14376 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14377 + if (!p_HcFrame)
14378 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14379 +
14380 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14381 + {
14382 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14383 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14384 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14385 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14386 +
14387 + idx = (uint8_t)(i - p_Set->baseEntry);
14388 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14389 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14390 + p_HcFrame->commandSequence = seqNum;
14391 +
14392 + BUILD_FD(sizeof(t_HcFrame));
14393 +
14394 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14395 + {
14396 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14397 + RETURN_ERROR(MINOR, err, NO_MSG);
14398 + }
14399 + }
14400 +
14401 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14402 + return err;
14403 +}
14404 +
14405 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14406 +{
14407 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14408 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14409 +
14410 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14411 + if (!p_ClsPlanSet)
14412 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14413 +
14414 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14415 +
14416 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14417 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14418 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14419 +
14420 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14421 + {
14422 + XX_Free(p_ClsPlanSet);
14423 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14424 + }
14425 +
14426 + XX_Free(p_ClsPlanSet);
14427 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14428 +
14429 + return E_OK;
14430 +}
14431 +
14432 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14433 +{
14434 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14435 + t_HcFrame *p_HcFrame;
14436 + t_DpaaFD fmFd;
14437 + t_Error err;
14438 + uint32_t seqNum;
14439 +
14440 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14441 +
14442 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14443 + if (!p_HcFrame)
14444 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14445 +
14446 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14447 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14448 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14449 + p_HcFrame->commandSequence = seqNum;
14450 + BUILD_FD(sizeof(t_HcFrame));
14451 +
14452 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14453 +
14454 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14455 + return err;
14456 +}
14457 +
14458 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14459 +{
14460 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14461 + t_HcFrame *p_HcFrame;
14462 + t_DpaaFD fmFd;
14463 + t_Error err;
14464 + uint32_t seqNum;
14465 +
14466 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14467 +
14468 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14469 + if (!p_HcFrame)
14470 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14471 +
14472 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14473 +
14474 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14475 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14476 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14477 + if (fill == TRUE)
14478 + {
14479 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14480 + }
14481 + p_HcFrame->commandSequence = seqNum;
14482 +
14483 + BUILD_FD(sizeof(t_HcFrame));
14484 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14485 + {
14486 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14487 + RETURN_ERROR(MINOR, err, NO_MSG);
14488 + }
14489 +
14490 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14491 +
14492 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14493 + return E_OK;
14494 +}
14495 +
14496 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14497 +{
14498 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14499 + t_HcFrame *p_HcFrame;
14500 + t_DpaaFD fmFd;
14501 + t_Error err;
14502 + uint32_t seqNum;
14503 +
14504 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14505 +
14506 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14507 + if (!p_HcFrame)
14508 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14509 +
14510 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14511 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14512 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14513 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14514 + p_HcFrame->commandSequence = seqNum;
14515 +
14516 + BUILD_FD(sizeof(t_HcFrame));
14517 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14518 + {
14519 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14520 + RETURN_ERROR(MINOR, err, NO_MSG);
14521 + }
14522 +
14523 + *p_Result = (uint8_t)
14524 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14525 +
14526 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14527 + return E_OK;
14528 +}
14529 +
14530 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14531 +{
14532 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14533 + t_HcFrame *p_HcFrame;
14534 + t_DpaaFD fmFd;
14535 + t_Error err;
14536 + uint32_t tmpReg32 = 0;
14537 + uint32_t requiredActionTmp, requiredActionFlag;
14538 + uint32_t seqNum;
14539 +
14540 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14541 +
14542 + /* Profile is locked by calling routine */
14543 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14544 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14545 + */
14546 +
14547 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14548 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14549 +
14550 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14551 + {
14552 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14553 + {
14554 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14555 + if (!p_HcFrame)
14556 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14557 + /* first read scheme and check that it is valid */
14558 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14559 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14560 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14561 + p_HcFrame->extraReg = 0x00008000;
14562 + p_HcFrame->commandSequence = seqNum;
14563 +
14564 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14565 +
14566 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14567 + {
14568 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14569 + RETURN_ERROR(MINOR, err, NO_MSG);
14570 + }
14571 +
14572 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14573 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14574 + {
14575 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14576 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14577 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14578 + }
14579 +
14580 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14581 +
14582 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14583 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14584 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14585 + p_HcFrame->extraReg = 0x00008000;
14586 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14587 +
14588 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14589 +
14590 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14591 + {
14592 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14593 + RETURN_ERROR(MINOR, err, NO_MSG);
14594 + }
14595 +
14596 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14597 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14598 + {
14599 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14600 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14601 + }
14602 +
14603 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14604 +
14605 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14606 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14607 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14608 + p_HcFrame->extraReg = 0x00008000;
14609 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14610 +
14611 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14612 +
14613 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14614 + {
14615 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14616 + RETURN_ERROR(MINOR, err, NO_MSG);
14617 + }
14618 +
14619 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14620 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14621 + {
14622 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14623 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14624 + }
14625 +
14626 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14627 +
14628 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14629 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14630 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14631 + p_HcFrame->extraReg = 0x00008000;
14632 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14633 +
14634 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14635 +
14636 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14637 + {
14638 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14639 + RETURN_ERROR(MINOR, err, NO_MSG);
14640 + }
14641 +
14642 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14643 + }
14644 + }
14645 +
14646 + return E_OK;
14647 +}
14648 +
14649 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14650 +{
14651 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14652 + t_Error err = E_OK;
14653 + uint16_t profileIndx;
14654 + t_HcFrame *p_HcFrame;
14655 + t_DpaaFD fmFd;
14656 + uint32_t seqNum;
14657 +
14658 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14659 + if (!p_HcFrame)
14660 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14661 +
14662 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14663 +
14664 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14665 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14666 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14667 + p_HcFrame->extraReg = 0x00008000;
14668 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14669 + p_HcFrame->commandSequence = seqNum;
14670 +
14671 + BUILD_FD(sizeof(t_HcFrame));
14672 +
14673 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14674 +
14675 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14676 +
14677 + if (err != E_OK)
14678 + RETURN_ERROR(MINOR, err, NO_MSG);
14679 +
14680 + return E_OK;
14681 +}
14682 +
14683 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14684 +{
14685 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14686 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14687 + t_Error err = E_OK;
14688 + t_HcFrame *p_HcFrame;
14689 + t_DpaaFD fmFd;
14690 + uint32_t seqNum;
14691 +
14692 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14693 + if (!p_HcFrame)
14694 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14695 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14696 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14697 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14698 + p_HcFrame->actionReg |= 0x00008000;
14699 + p_HcFrame->extraReg = 0x00008000;
14700 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14701 + p_HcFrame->commandSequence = seqNum;
14702 +
14703 + BUILD_FD(sizeof(t_HcFrame));
14704 +
14705 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14706 +
14707 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14708 +
14709 + if (err != E_OK)
14710 + RETURN_ERROR(MINOR, err, NO_MSG);
14711 +
14712 + return E_OK;
14713 +}
14714 +
14715 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14716 +{
14717 +
14718 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14719 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14720 + t_Error err = E_OK;
14721 + t_HcFrame *p_HcFrame;
14722 + t_DpaaFD fmFd;
14723 + uint32_t seqNum;
14724 +
14725 + /* first read scheme and check that it is valid */
14726 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14727 + if (!p_HcFrame)
14728 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14729 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14730 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14731 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14732 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14733 + p_HcFrame->extraReg = 0x00008000;
14734 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14735 + p_HcFrame->commandSequence = seqNum;
14736 +
14737 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14738 +
14739 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14740 +
14741 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14742 +
14743 + if (err != E_OK)
14744 + RETURN_ERROR(MINOR, err, NO_MSG);
14745 +
14746 + return E_OK;
14747 +}
14748 +
14749 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14750 +{
14751 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14752 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14753 + t_Error err;
14754 + t_HcFrame *p_HcFrame;
14755 + t_DpaaFD fmFd;
14756 + uint32_t retVal = 0;
14757 + uint32_t seqNum;
14758 +
14759 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14760 +
14761 + /* first read scheme and check that it is valid */
14762 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14763 + if (!p_HcFrame)
14764 + {
14765 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14766 + return 0;
14767 + }
14768 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14769 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14770 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14771 + p_HcFrame->extraReg = 0x00008000;
14772 + p_HcFrame->commandSequence = seqNum;
14773 +
14774 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14775 +
14776 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14777 + if (err != E_OK)
14778 + {
14779 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14780 + REPORT_ERROR(MINOR, err, NO_MSG);
14781 + return 0;
14782 + }
14783 +
14784 + switch (counter)
14785 + {
14786 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14787 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14788 + break;
14789 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14790 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14791 + break;
14792 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14793 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14794 + break;
14795 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14796 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14797 + break;
14798 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14799 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14800 + break;
14801 + default:
14802 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14803 + }
14804 +
14805 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14806 + return retVal;
14807 +}
14808 +
14809 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14810 +{
14811 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14812 + t_HcFrame *p_HcFrame;
14813 + t_DpaaFD fmFd;
14814 + t_Error err = E_OK;
14815 + uint32_t seqNum;
14816 +
14817 + ASSERT_COND(p_FmHc);
14818 +
14819 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14820 + if (!p_HcFrame)
14821 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14822 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14823 + /* first read SP register */
14824 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14825 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14826 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14827 + p_HcFrame->commandSequence = seqNum;
14828 +
14829 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14830 +
14831 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14832 + {
14833 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14834 + RETURN_ERROR(MINOR, err, NO_MSG);
14835 + }
14836 +
14837 + /* spReg is the first reg, so we can use it both for read and for write */
14838 + if (add)
14839 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14840 + else
14841 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14842 +
14843 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14844 +
14845 + BUILD_FD(sizeof(t_HcFrame));
14846 +
14847 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14848 +
14849 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14850 +
14851 + if (err != E_OK)
14852 + RETURN_ERROR(MINOR, err, NO_MSG);
14853 +
14854 + return E_OK;
14855 +}
14856 +
14857 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14858 +{
14859 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14860 + t_HcFrame *p_HcFrame;
14861 + t_DpaaFD fmFd;
14862 + t_Error err = E_OK;
14863 + uint32_t seqNum;
14864 +
14865 + ASSERT_COND(p_FmHc);
14866 +
14867 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14868 + if (!p_HcFrame)
14869 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14870 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14871 + /* first read SP register */
14872 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14873 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14874 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14875 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14876 + p_HcFrame->commandSequence = seqNum;
14877 +
14878 + BUILD_FD(sizeof(t_HcFrame));
14879 +
14880 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14881 +
14882 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14883 +
14884 + if (err != E_OK)
14885 + RETURN_ERROR(MINOR, err, NO_MSG);
14886 +
14887 + return E_OK;
14888 +}
14889 +
14890 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14891 +{
14892 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14893 + t_HcFrame *p_HcFrame;
14894 + t_DpaaFD fmFd;
14895 + t_Error err = E_OK;
14896 + uint32_t seqNum;
14897 +
14898 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14899 +
14900 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14901 + if (!p_HcFrame)
14902 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14903 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14904 +
14905 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14906 + p_HcFrame->actionReg = newAdAddrOffset;
14907 + p_HcFrame->actionReg |= 0xc0000000;
14908 + p_HcFrame->extraReg = oldAdAddrOffset;
14909 + p_HcFrame->commandSequence = seqNum;
14910 +
14911 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14912 +
14913 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14914 +
14915 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14916 +
14917 + if (err != E_OK)
14918 + RETURN_ERROR(MAJOR, err, NO_MSG);
14919 +
14920 + return E_OK;
14921 +}
14922 +
14923 +t_Error FmHcPcdSync(t_Handle h_FmHc)
14924 +{
14925 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14926 + t_HcFrame *p_HcFrame;
14927 + t_DpaaFD fmFd;
14928 + t_Error err = E_OK;
14929 + uint32_t seqNum;
14930 +
14931 + ASSERT_COND(p_FmHc);
14932 +
14933 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14934 + if (!p_HcFrame)
14935 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14936 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14937 + /* first read SP register */
14938 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
14939 + p_HcFrame->actionReg = 0;
14940 + p_HcFrame->extraReg = 0;
14941 + p_HcFrame->commandSequence = seqNum;
14942 +
14943 + BUILD_FD(sizeof(t_HcFrame));
14944 +
14945 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14946 +
14947 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14948 +
14949 + if (err != E_OK)
14950 + RETURN_ERROR(MINOR, err, NO_MSG);
14951 +
14952 + return E_OK;
14953 +}
14954 +
14955 +t_Handle FmHcGetPort(t_Handle h_FmHc)
14956 +{
14957 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14958 + return p_FmHc->h_HcPortDev;
14959 +}
14960 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14961 new file mode 100644
14962 index 00000000..f6b090da
14963 --- /dev/null
14964 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14965 @@ -0,0 +1,28 @@
14966 +#
14967 +# Makefile for the Freescale Ethernet controllers
14968 +#
14969 +ccflags-y += -DVERSION=\"\"
14970 +#
14971 +#Include netcomm SW specific definitions
14972 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
14973 +
14974 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
14975 +
14976 +ccflags-y += -I$(NCSW_FM_INC)
14977 +
14978 +obj-y += fsl-ncsw-MAC.o
14979 +
14980 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
14981 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
14982 + fman_tgec.o fman_crc32.o
14983 +
14984 +ifeq ($(CONFIG_FMAN_V3H),y)
14985 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14986 +endif
14987 +ifeq ($(CONFIG_FMAN_V3L),y)
14988 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14989 +endif
14990 +ifeq ($(CONFIG_FMAN_ARM),y)
14991 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14992 +endif
14993 +
14994 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14995 new file mode 100644
14996 index 00000000..f853825f
14997 --- /dev/null
14998 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14999 @@ -0,0 +1,1464 @@
15000 +/*
15001 + * Copyright 2008-2013 Freescale Semiconductor Inc.
15002 + *
15003 + * Redistribution and use in source and binary forms, with or without
15004 + * modification, are permitted provided that the following conditions are met:
15005 + * * Redistributions of source code must retain the above copyright
15006 + * notice, this list of conditions and the following disclaimer.
15007 + * * Redistributions in binary form must reproduce the above copyright
15008 + * notice, this list of conditions and the following disclaimer in the
15009 + * documentation and/or other materials provided with the distribution.
15010 + * * Neither the name of Freescale Semiconductor nor the
15011 + * names of its contributors may be used to endorse or promote products
15012 + * derived from this software without specific prior written permission.
15013 + *
15014 + *
15015 + * ALTERNATIVELY, this software may be distributed under the terms of the
15016 + * GNU General Public License ("GPL") as published by the Free Software
15017 + * Foundation, either version 2 of that License or (at your option) any
15018 + * later version.
15019 + *
15020 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15021 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15022 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15023 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15024 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15025 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15026 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15027 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15028 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15029 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15030 + */
15031 +
15032 +/******************************************************************************
15033 + @File dtsec.c
15034 +
15035 + @Description FMan dTSEC driver
15036 +*//***************************************************************************/
15037 +
15038 +#include "std_ext.h"
15039 +#include "error_ext.h"
15040 +#include "string_ext.h"
15041 +#include "xx_ext.h"
15042 +#include "endian_ext.h"
15043 +#include "debug_ext.h"
15044 +#include "crc_mac_addr_ext.h"
15045 +
15046 +#include "fm_common.h"
15047 +#include "dtsec.h"
15048 +#include "fsl_fman_dtsec.h"
15049 +#include "fsl_fman_dtsec_mii_acc.h"
15050 +
15051 +/*****************************************************************************/
15052 +/* Internal routines */
15053 +/*****************************************************************************/
15054 +
15055 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
15056 +{
15057 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
15058 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
15059 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
15060 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
15061 + if (p_Dtsec->addr == 0)
15062 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
15063 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
15064 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
15065 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
15066 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
15067 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
15068 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
15069 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
15070 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
15071 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
15072 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
15073 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
15074 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
15075 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
15076 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
15077 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
15078 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
15079 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
15080 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
15081 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
15082 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
15083 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
15084 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
15085 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
15086 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
15087 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
15088 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
15089 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
15090 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
15091 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
15092 +
15093 + /* If Auto negotiation process is disabled, need to */
15094 + /* Set up the PHY using the MII Management Interface */
15095 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
15096 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
15097 + if (!p_Dtsec->f_Exception)
15098 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
15099 + if (!p_Dtsec->f_Event)
15100 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
15101 +
15102 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
15103 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
15104 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
15105 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15106 +
15107 + return E_OK;
15108 +}
15109 +
15110 +/* ......................................................................... */
15111 +
15112 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15113 +{
15114 + uint32_t crc;
15115 +
15116 + /* CRC calculation */
15117 + GET_MAC_ADDR_CRC(ethAddr, crc);
15118 +
15119 + crc = GetMirror32(crc);
15120 +
15121 + return crc;
15122 +}
15123 +
15124 +/* ......................................................................... */
15125 +
15126 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15127 +{
15128 + uint32_t car1, car2;
15129 +
15130 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15131 +
15132 + if (car1)
15133 + {
15134 + if (car1 & CAR1_TR64)
15135 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15136 + if (car1 & CAR1_TR127)
15137 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15138 + if (car1 & CAR1_TR255)
15139 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15140 + if (car1 & CAR1_TR511)
15141 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15142 + if (car1 & CAR1_TRK1)
15143 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15144 + if (car1 & CAR1_TRMAX)
15145 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15146 + if (car1 & CAR1_TRMGV)
15147 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15148 + if (car1 & CAR1_RBYT)
15149 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15150 + if (car1 & CAR1_RPKT)
15151 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15152 + if (car1 & CAR1_RMCA)
15153 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15154 + if (car1 & CAR1_RBCA)
15155 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15156 + if (car1 & CAR1_RXPF)
15157 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15158 + if (car1 & CAR1_RALN)
15159 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15160 + if (car1 & CAR1_RFLR)
15161 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15162 + if (car1 & CAR1_RCDE)
15163 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15164 + if (car1 & CAR1_RCSE)
15165 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15166 + if (car1 & CAR1_RUND)
15167 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15168 + if (car1 & CAR1_ROVR)
15169 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15170 + if (car1 & CAR1_RFRG)
15171 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15172 + if (car1 & CAR1_RJBR)
15173 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15174 + if (car1 & CAR1_RDRP)
15175 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15176 + }
15177 + if (car2)
15178 + {
15179 + if (car2 & CAR2_TFCS)
15180 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15181 + if (car2 & CAR2_TBYT)
15182 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15183 + if (car2 & CAR2_TPKT)
15184 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15185 + if (car2 & CAR2_TMCA)
15186 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15187 + if (car2 & CAR2_TBCA)
15188 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15189 + if (car2 & CAR2_TXPF)
15190 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15191 + if (car2 & CAR2_TDRP)
15192 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15193 + }
15194 +}
15195 +
15196 +/* .............................................................................. */
15197 +
15198 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15199 +{
15200 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15201 +
15202 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15203 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15204 +
15205 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15206 +}
15207 +
15208 +/* .............................................................................. */
15209 +
15210 +static void DtsecIsr(t_Handle h_Dtsec)
15211 +{
15212 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15213 + uint32_t event;
15214 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15215 +
15216 + /* do not handle MDIO events */
15217 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15218 +
15219 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15220 +
15221 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15222 +
15223 + if (event & DTSEC_IMASK_BREN)
15224 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15225 + if (event & DTSEC_IMASK_RXCEN)
15226 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15227 + if (event & DTSEC_IMASK_MSROEN)
15228 + UpdateStatistics(p_Dtsec);
15229 + if (event & DTSEC_IMASK_GTSCEN)
15230 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15231 + if (event & DTSEC_IMASK_BTEN)
15232 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15233 + if (event & DTSEC_IMASK_TXCEN)
15234 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15235 + if (event & DTSEC_IMASK_TXEEN)
15236 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15237 + if (event & DTSEC_IMASK_LCEN)
15238 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15239 + if (event & DTSEC_IMASK_CRLEN)
15240 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15241 + if (event & DTSEC_IMASK_XFUNEN)
15242 + {
15243 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15244 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15245 + {
15246 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15247 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15248 + /* This is a read only regidter */
15249 +
15250 + /* b. Read and save the value of TPKT */
15251 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15252 +
15253 + /* c. Read the register at dTSEC address offset 0x32C */
15254 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15255 +
15256 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15257 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15258 + {
15259 + /* If they are not equal, save the value of this register and wait for at least
15260 + * MAXFRM*16 ns */
15261 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15262 + }
15263 +
15264 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15265 + 0x32C again*/
15266 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15267 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15268 +
15269 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15270 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15271 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15272 + the transmit portion of the dTSEC controller is locked up and the user should
15273 + proceed to the recover sequence. */
15274 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15275 + {
15276 + /* recover sequence */
15277 +
15278 + /* a.Write a 1 to RCTRL[GRS]*/
15279 +
15280 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15281 +
15282 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15283 + for (i = 0 ; i < 100 ; i++ )
15284 + {
15285 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15286 + break;
15287 + XX_UDelay(1);
15288 + }
15289 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15290 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15291 + else
15292 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15293 +
15294 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15295 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15296 +
15297 + /* d.Wait 4 Tx clocks (32 ns) */
15298 + XX_UDelay(1);
15299 +
15300 + /* e.Write a 0 to bit n of FM_RSTC. */
15301 + /* cleared by FMAN */
15302 + }
15303 + }
15304 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15305 +
15306 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15307 + }
15308 + if (event & DTSEC_IMASK_MAGEN)
15309 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15310 + if (event & DTSEC_IMASK_GRSCEN)
15311 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15312 + if (event & DTSEC_IMASK_TDPEEN)
15313 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15314 + if (event & DTSEC_IMASK_RDPEEN)
15315 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15316 +
15317 + /* - masked interrupts */
15318 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15319 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15320 +}
15321 +
15322 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15323 +{
15324 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15325 + uint32_t event;
15326 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15327 +
15328 + event = GET_UINT32(p_DtsecMemMap->ievent);
15329 + /* handle only MDIO events */
15330 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15331 + if (event)
15332 + {
15333 + event &= GET_UINT32(p_DtsecMemMap->imask);
15334 +
15335 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15336 +
15337 + if (event & DTSEC_IMASK_MMRDEN)
15338 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15339 + if (event & DTSEC_IMASK_MMWREN)
15340 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15341 + }
15342 +}
15343 +
15344 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15345 +{
15346 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15347 + uint32_t event;
15348 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15349 +
15350 + if (p_Dtsec->ptpTsuEnabled)
15351 + {
15352 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15353 +
15354 + if (event)
15355 + {
15356 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15357 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15358 + }
15359 + }
15360 +}
15361 +
15362 +/* ........................................................................... */
15363 +
15364 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15365 +{
15366 + if (p_Dtsec->mdioIrq != NO_IRQ)
15367 + {
15368 + XX_DisableIntr(p_Dtsec->mdioIrq);
15369 + XX_FreeIntr(p_Dtsec->mdioIrq);
15370 + }
15371 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15372 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15373 +
15374 + /* release the driver's group hash table */
15375 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15376 + p_Dtsec->p_MulticastAddrHash = NULL;
15377 +
15378 + /* release the driver's individual hash table */
15379 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15380 + p_Dtsec->p_UnicastAddrHash = NULL;
15381 +}
15382 +
15383 +/* ........................................................................... */
15384 +
15385 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15386 +{
15387 + struct dtsec_regs *p_MemMap;
15388 +
15389 + ASSERT_COND(p_Dtsec);
15390 +
15391 + p_MemMap = p_Dtsec->p_MemMap;
15392 + ASSERT_COND(p_MemMap);
15393 +
15394 + /* Assert the graceful transmit stop bit */
15395 + if (mode & e_COMM_MODE_RX)
15396 + {
15397 + fman_dtsec_stop_rx(p_MemMap);
15398 +
15399 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15400 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15401 + XX_UDelay(100);
15402 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15403 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15404 + XX_UDelay(10);
15405 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15406 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15407 + }
15408 +
15409 + if (mode & e_COMM_MODE_TX)
15410 +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15411 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15412 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15413 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15414 +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
15415 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
15416 +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15417 + fman_dtsec_stop_tx(p_MemMap);
15418 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15419 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15420 +
15421 + return E_OK;
15422 +}
15423 +
15424 +/* .............................................................................. */
15425 +
15426 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15427 +{
15428 + struct dtsec_regs *p_MemMap;
15429 +
15430 + ASSERT_COND(p_Dtsec);
15431 + p_MemMap = p_Dtsec->p_MemMap;
15432 + ASSERT_COND(p_MemMap);
15433 +
15434 + /* clear the graceful receive stop bit */
15435 + if (mode & e_COMM_MODE_TX)
15436 + fman_dtsec_start_tx(p_MemMap);
15437 +
15438 + if (mode & e_COMM_MODE_RX)
15439 + fman_dtsec_start_rx(p_MemMap);
15440 +
15441 + return E_OK;
15442 +}
15443 +
15444 +
15445 +/*****************************************************************************/
15446 +/* dTSEC Configs modification functions */
15447 +/*****************************************************************************/
15448 +
15449 +/* .............................................................................. */
15450 +
15451 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15452 +{
15453 +
15454 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15455 +
15456 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15457 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15458 +
15459 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15460 +
15461 + return E_OK;
15462 +}
15463 +
15464 +/* .............................................................................. */
15465 +
15466 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15467 +{
15468 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15469 +
15470 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15471 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15472 +
15473 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15474 +
15475 + return E_OK;
15476 +}
15477 +
15478 +/* .............................................................................. */
15479 +
15480 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15481 +{
15482 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15483 +
15484 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15485 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15486 +
15487 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15488 +
15489 + return E_OK;
15490 +}
15491 +
15492 +/* .............................................................................. */
15493 +
15494 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15495 +{
15496 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15497 +
15498 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15499 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15500 +
15501 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15502 +
15503 + return E_OK;
15504 +}
15505 +
15506 +/* .............................................................................. */
15507 +
15508 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15509 +{
15510 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15511 +
15512 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15513 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15514 +
15515 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15516 +
15517 + return E_OK;
15518 +}
15519 +
15520 +/* .............................................................................. */
15521 +
15522 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15523 +{
15524 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15525 +
15526 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15527 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15528 +
15529 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15530 +
15531 + return E_OK;
15532 +}
15533 +
15534 +/* .............................................................................. */
15535 +
15536 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15537 +{
15538 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15539 + uint32_t bitMask = 0;
15540 +
15541 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15542 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15543 +
15544 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15545 + {
15546 + GET_EXCEPTION_FLAG(bitMask, exception);
15547 + if (bitMask)
15548 + {
15549 + if (enable)
15550 + p_Dtsec->exceptions |= bitMask;
15551 + else
15552 + p_Dtsec->exceptions &= ~bitMask;
15553 + }
15554 + else
15555 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15556 + }
15557 + else
15558 + {
15559 + if (!p_Dtsec->ptpTsuEnabled)
15560 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15561 +
15562 + if (enable)
15563 + p_Dtsec->enTsuErrExeption = TRUE;
15564 + else
15565 + p_Dtsec->enTsuErrExeption = FALSE;
15566 + }
15567 +
15568 + return E_OK;
15569 +}
15570 +
15571 +
15572 +/*****************************************************************************/
15573 +/* dTSEC Run Time API functions */
15574 +/*****************************************************************************/
15575 +
15576 +/* .............................................................................. */
15577 +
15578 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15579 +{
15580 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15581 +
15582 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15583 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15584 +
15585 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15586 + (bool)!!(mode & e_COMM_MODE_RX),
15587 + (bool)!!(mode & e_COMM_MODE_TX));
15588 +
15589 + GracefulRestart(p_Dtsec, mode);
15590 +
15591 + return E_OK;
15592 +}
15593 +
15594 +/* .............................................................................. */
15595 +
15596 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
15597 +{
15598 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15599 +
15600 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15601 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15602 +
15603 + GracefulStop(p_Dtsec, mode);
15604 +
15605 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15606 + (bool)!!(mode & e_COMM_MODE_RX),
15607 + (bool)!!(mode & e_COMM_MODE_TX));
15608 +
15609 + return E_OK;
15610 +}
15611 +
15612 +/* .............................................................................. */
15613 +
15614 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15615 + uint8_t priority,
15616 + uint16_t pauseTime,
15617 + uint16_t threshTime)
15618 +{
15619 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15620 +
15621 + UNUSED(priority);UNUSED(threshTime);
15622 +
15623 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15624 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15625 +
15626 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15627 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15628 + if (0 < pauseTime && pauseTime <= 320)
15629 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15630 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15631 + " value should be greater than 320."));
15632 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15633 +
15634 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15635 + return E_OK;
15636 +}
15637 +
15638 +/* .............................................................................. */
15639 +/* backward compatibility. will be removed in the future. */
15640 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15641 +{
15642 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15643 +}
15644 +
15645 +/* .............................................................................. */
15646 +
15647 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15648 +{
15649 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15650 + bool accept_pause = !en;
15651 +
15652 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15653 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15654 +
15655 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15656 +
15657 + return E_OK;
15658 +}
15659 +
15660 +/* .............................................................................. */
15661 +
15662 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15663 +{
15664 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15665 +
15666 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15667 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15668 +
15669 + p_Dtsec->ptpTsuEnabled = TRUE;
15670 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15671 +
15672 + return E_OK;
15673 +}
15674 +
15675 +/* .............................................................................. */
15676 +
15677 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15678 +{
15679 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15680 +
15681 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15682 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15683 +
15684 + p_Dtsec->ptpTsuEnabled = FALSE;
15685 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15686 +
15687 + return E_OK;
15688 +}
15689 +
15690 +/* .............................................................................. */
15691 +
15692 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15693 +{
15694 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15695 + struct dtsec_regs *p_DtsecMemMap;
15696 +
15697 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15698 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15699 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15700 +
15701 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15702 +
15703 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15704 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15705 +
15706 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15707 +
15708 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15709 + {
15710 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15711 + + p_Dtsec->internalStatistics.tr64;
15712 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15713 + + p_Dtsec->internalStatistics.tr127;
15714 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15715 + + p_Dtsec->internalStatistics.tr255;
15716 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15717 + + p_Dtsec->internalStatistics.tr511;
15718 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15719 + + p_Dtsec->internalStatistics.tr1k;
15720 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15721 + + p_Dtsec->internalStatistics.trmax;
15722 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15723 + + p_Dtsec->internalStatistics.trmgv;
15724 +
15725 + /* MIB II */
15726 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15727 + + p_Dtsec->internalStatistics.rbyt;
15728 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15729 + + p_Dtsec->internalStatistics.rpkt;
15730 + p_Statistics->ifInUcastPkts = 0;
15731 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15732 + + p_Dtsec->internalStatistics.rmca;
15733 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15734 + + p_Dtsec->internalStatistics.rbca;
15735 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15736 + + p_Dtsec->internalStatistics.tbyt;
15737 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15738 + + p_Dtsec->internalStatistics.tpkt;
15739 + p_Statistics->ifOutUcastPkts = 0;
15740 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15741 + + p_Dtsec->internalStatistics.tmca;
15742 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15743 + + p_Dtsec->internalStatistics.tbca;
15744 + }
15745 +
15746 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15747 + + p_Dtsec->internalStatistics.rfrg;
15748 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15749 + + p_Dtsec->internalStatistics.rjbr;
15750 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15751 + + p_Dtsec->internalStatistics.rdrp;
15752 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15753 + + p_Dtsec->internalStatistics.raln;
15754 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15755 + + p_Dtsec->internalStatistics.rund;
15756 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15757 + + p_Dtsec->internalStatistics.rovr;
15758 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15759 + + p_Dtsec->internalStatistics.rxpf;
15760 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15761 + + p_Dtsec->internalStatistics.txpf;
15762 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15763 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15764 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15765 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15766 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15767 +
15768 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15769 + + p_Dtsec->internalStatistics.tdrp;
15770 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15771 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15772 + + p_Dtsec->internalStatistics.tfcs;
15773 +
15774 + return E_OK;
15775 +}
15776 +
15777 +/* .............................................................................. */
15778 +
15779 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15780 +{
15781 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15782 +
15783 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15784 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15785 +
15786 + /* Initialize MAC Station Address registers (1 & 2) */
15787 + /* Station address have to be swapped (big endian to little endian */
15788 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15789 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15790 +
15791 + return E_OK;
15792 +}
15793 +
15794 +/* .............................................................................. */
15795 +
15796 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15797 +{
15798 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15799 +
15800 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15801 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15802 +
15803 + /* clear HW counters */
15804 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15805 +
15806 + /* clear SW counters holding carries */
15807 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15808 +
15809 + return E_OK;
15810 +}
15811 +
15812 +/* .............................................................................. */
15813 +
15814 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15815 +{
15816 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15817 + uint64_t ethAddr;
15818 + uint8_t paddrNum;
15819 +
15820 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15821 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15822 +
15823 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15824 +
15825 + if (ethAddr & GROUP_ADDRESS)
15826 + /* Multicast address has no effect in PADDR */
15827 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15828 +
15829 + /* Make sure no PADDR contains this address */
15830 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15831 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15832 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15833 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15834 +
15835 + /* Find first unused PADDR */
15836 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15837 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15838 + {
15839 + /* mark this PADDR as used */
15840 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15841 + /* store address */
15842 + p_Dtsec->paddr[paddrNum] = ethAddr;
15843 +
15844 + /* put in hardware */
15845 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15846 + p_Dtsec->numOfIndAddrInRegs++;
15847 +
15848 + return E_OK;
15849 + }
15850 +
15851 + /* No free PADDR */
15852 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15853 +}
15854 +
15855 +/* .............................................................................. */
15856 +
15857 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15858 +{
15859 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15860 + uint64_t ethAddr;
15861 + uint8_t paddrNum;
15862 +
15863 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15864 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15865 +
15866 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15867 +
15868 + /* Find used PADDR containing this address */
15869 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15870 + {
15871 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15872 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15873 + {
15874 + /* mark this PADDR as not used */
15875 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15876 + /* clear in hardware */
15877 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15878 + p_Dtsec->numOfIndAddrInRegs--;
15879 +
15880 + return E_OK;
15881 + }
15882 + }
15883 +
15884 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
15885 +}
15886 +
15887 +/* .............................................................................. */
15888 +
15889 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15890 +{
15891 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15892 + t_EthHashEntry *p_HashEntry;
15893 + uint64_t ethAddr;
15894 + int32_t bucket;
15895 + uint32_t crc;
15896 + bool mcast, ghtx;
15897 +
15898 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15899 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15900 +
15901 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15902 +
15903 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15904 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15905 +
15906 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15907 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15908 +
15909 + crc = GetMacAddrHashCode(ethAddr);
15910 +
15911 + /* considering the 9 highest order bits in crc H[8:0]:
15912 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
15913 + * and H[5:1] (next 5 bits) identify the hash bit
15914 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
15915 + * and H[4:0] (next 5 bits) identify the hash bit.
15916 + *
15917 + * In bucket index output the low 5 bits identify the hash register bit,
15918 + * while the higher 4 bits identify the hash register
15919 + */
15920 +
15921 + if (ghtx)
15922 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15923 + else {
15924 + bucket = (int32_t)((crc >> 24) & 0xff);
15925 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15926 + if (mcast)
15927 + bucket += 0x100;
15928 + }
15929 +
15930 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
15931 +
15932 + /* Create element to be added to the driver hash table */
15933 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
15934 + p_HashEntry->addr = ethAddr;
15935 + INIT_LIST(&p_HashEntry->node);
15936 +
15937 + if (ethAddr & MAC_GROUP_ADDRESS)
15938 + /* Group Address */
15939 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
15940 + else
15941 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
15942 +
15943 + return E_OK;
15944 +}
15945 +
15946 +/* .............................................................................. */
15947 +
15948 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15949 +{
15950 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15951 + t_List *p_Pos;
15952 + t_EthHashEntry *p_HashEntry = NULL;
15953 + uint64_t ethAddr;
15954 + int32_t bucket;
15955 + uint32_t crc;
15956 + bool mcast, ghtx;
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 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15962 +
15963 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15964 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15965 +
15966 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15967 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15968 +
15969 + crc = GetMacAddrHashCode(ethAddr);
15970 +
15971 + if (ghtx)
15972 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15973 + else {
15974 + bucket = (int32_t)((crc >> 24) & 0xff);
15975 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15976 + if (mcast)
15977 + bucket += 0x100;
15978 + }
15979 +
15980 + if (ethAddr & MAC_GROUP_ADDRESS)
15981 + {
15982 + /* Group Address */
15983 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15984 + {
15985 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15986 + if (p_HashEntry->addr == ethAddr)
15987 + {
15988 + LIST_DelAndInit(&p_HashEntry->node);
15989 + XX_Free(p_HashEntry);
15990 + break;
15991 + }
15992 + }
15993 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15994 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15995 + }
15996 + else
15997 + {
15998 + /* Individual Address */
15999 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
16000 + {
16001 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
16002 + if (p_HashEntry->addr == ethAddr)
16003 + {
16004 + LIST_DelAndInit(&p_HashEntry->node);
16005 + XX_Free(p_HashEntry);
16006 + break;
16007 + }
16008 + }
16009 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
16010 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
16011 + }
16012 +
16013 + /* address does not exist */
16014 + ASSERT_COND(p_HashEntry != NULL);
16015 +
16016 + return E_OK;
16017 +}
16018 +
16019 +/* .............................................................................. */
16020 +
16021 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
16022 +{
16023 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
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 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
16029 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
16030 +
16031 + return E_OK;
16032 +}
16033 +
16034 +/* .............................................................................. */
16035 +
16036 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
16037 +{
16038 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16039 + t_Error err;
16040 +
16041 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16042 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16043 +
16044 + p_Dtsec->statisticsLevel = statisticsLevel;
16045 +
16046 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
16047 + (enum dtsec_stat_level)statisticsLevel);
16048 + if (err != E_OK)
16049 + return err;
16050 +
16051 + switch (statisticsLevel)
16052 + {
16053 + case (e_FM_MAC_NONE_STATISTICS):
16054 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
16055 + break;
16056 + case (e_FM_MAC_PARTIAL_STATISTICS):
16057 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16058 + break;
16059 + case (e_FM_MAC_FULL_STATISTICS):
16060 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16061 + break;
16062 + default:
16063 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
16064 + }
16065 +
16066 + return E_OK;
16067 +}
16068 +
16069 +/* .............................................................................. */
16070 +
16071 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
16072 +{
16073 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16074 +
16075 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
16076 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16077 +
16078 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
16079 +
16080 + return E_OK;
16081 +}
16082 +
16083 +/* .............................................................................. */
16084 +
16085 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
16086 +{
16087 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16088 + int err;
16089 + enum enet_interface enet_interface;
16090 + enum enet_speed enet_speed;
16091 +
16092 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16093 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16094 +
16095 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
16096 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16097 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16098 + p_Dtsec->halfDuplex = !fullDuplex;
16099 +
16100 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
16101 +
16102 + if (err == -EINVAL)
16103 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
16104 +
16105 + return (t_Error)err;
16106 +}
16107 +
16108 +/* .............................................................................. */
16109 +
16110 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16111 +{
16112 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16113 + uint16_t tmpReg16;
16114 +
16115 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16116 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16117 +
16118 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16119 +
16120 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16121 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16122 +
16123 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16124 +
16125 + return E_OK;
16126 +}
16127 +
16128 +/* .............................................................................. */
16129 +
16130 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16131 +{
16132 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16133 +
16134 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16135 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16136 +
16137 + *macId = p_Dtsec->macId;
16138 +
16139 + return E_OK;
16140 +}
16141 +
16142 +/* .............................................................................. */
16143 +
16144 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16145 +{
16146 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16147 +
16148 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16149 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16150 +
16151 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16152 +
16153 + return E_OK;
16154 +}
16155 +
16156 +/* .............................................................................. */
16157 +
16158 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16159 +{
16160 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16161 + uint32_t bitMask = 0;
16162 +
16163 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16164 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16165 +
16166 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16167 + {
16168 + GET_EXCEPTION_FLAG(bitMask, exception);
16169 + if (bitMask)
16170 + {
16171 + if (enable)
16172 + p_Dtsec->exceptions |= bitMask;
16173 + else
16174 + p_Dtsec->exceptions &= ~bitMask;
16175 + }
16176 + else
16177 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16178 +
16179 + if (enable)
16180 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16181 + else
16182 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16183 + }
16184 + else
16185 + {
16186 + if (!p_Dtsec->ptpTsuEnabled)
16187 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16188 +
16189 + if (enable)
16190 + {
16191 + p_Dtsec->enTsuErrExeption = TRUE;
16192 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16193 + }
16194 + else
16195 + {
16196 + p_Dtsec->enTsuErrExeption = FALSE;
16197 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16198 + }
16199 + }
16200 +
16201 + return E_OK;
16202 +}
16203 +
16204 +
16205 +/*****************************************************************************/
16206 +/* dTSEC Init & Free API */
16207 +/*****************************************************************************/
16208 +
16209 +/* .............................................................................. */
16210 +
16211 +static t_Error DtsecInit(t_Handle h_Dtsec)
16212 +{
16213 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16214 + struct dtsec_cfg *p_DtsecDriverParam;
16215 + t_Error err;
16216 + uint16_t maxFrmLn;
16217 + enum enet_interface enet_interface;
16218 + enum enet_speed enet_speed;
16219 + t_EnetAddr ethAddr;
16220 +
16221 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16222 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16223 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16224 +
16225 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16226 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16227 +
16228 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16229 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16230 +
16231 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16232 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16233 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16234 +
16235 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16236 + p_DtsecDriverParam,
16237 + enet_interface,
16238 + enet_speed,
16239 + (uint8_t*)ethAddr,
16240 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16241 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16242 + p_Dtsec->exceptions);
16243 + if (err)
16244 + {
16245 + FreeInitResources(p_Dtsec);
16246 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16247 + }
16248 +
16249 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16250 + {
16251 + uint16_t tmpReg16;
16252 +
16253 + /* Configure the TBI PHY Control Register */
16254 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16255 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16256 +
16257 + tmpReg16 = PHY_TBICON_CLK_SEL;
16258 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16259 +
16260 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16261 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16262 +
16263 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16264 + tmpReg16 = PHY_TBIANA_1000X;
16265 + else
16266 + tmpReg16 = PHY_TBIANA_SGMII;
16267 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16268 +
16269 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16270 +
16271 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16272 + }
16273 +
16274 + /* Max Frame Length */
16275 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16276 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16277 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16278 + if (err)
16279 + RETURN_ERROR(MINOR,err, NO_MSG);
16280 +
16281 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16282 + if (!p_Dtsec->p_MulticastAddrHash) {
16283 + FreeInitResources(p_Dtsec);
16284 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16285 + }
16286 +
16287 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16288 + if (!p_Dtsec->p_UnicastAddrHash)
16289 + {
16290 + FreeInitResources(p_Dtsec);
16291 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16292 + }
16293 +
16294 + /* register err intr handler for dtsec to FPM (err)*/
16295 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16296 + e_FM_MOD_1G_MAC,
16297 + p_Dtsec->macId,
16298 + e_FM_INTR_TYPE_ERR,
16299 + DtsecIsr,
16300 + p_Dtsec);
16301 + /* register 1588 intr handler for TMR to FPM (normal)*/
16302 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16303 + e_FM_MOD_1G_MAC,
16304 + p_Dtsec->macId,
16305 + e_FM_INTR_TYPE_NORMAL,
16306 + Dtsec1588Isr,
16307 + p_Dtsec);
16308 + /* register normal intr handler for dtsec to main interrupt controller. */
16309 + if (p_Dtsec->mdioIrq != NO_IRQ)
16310 + {
16311 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16312 + XX_EnableIntr(p_Dtsec->mdioIrq);
16313 + }
16314 +
16315 + XX_Free(p_DtsecDriverParam);
16316 + p_Dtsec->p_DtsecDriverParam = NULL;
16317 +
16318 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16319 + if (err)
16320 + {
16321 + FreeInitResources(p_Dtsec);
16322 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16323 + }
16324 +
16325 + return E_OK;
16326 +}
16327 +
16328 +/* ........................................................................... */
16329 +
16330 +static t_Error DtsecFree(t_Handle h_Dtsec)
16331 +{
16332 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16333 +
16334 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16335 +
16336 + if (p_Dtsec->p_DtsecDriverParam)
16337 + {
16338 + /* Called after config */
16339 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16340 + p_Dtsec->p_DtsecDriverParam = NULL;
16341 + }
16342 + else
16343 + /* Called after init */
16344 + FreeInitResources(p_Dtsec);
16345 +
16346 + XX_Free(p_Dtsec);
16347 +
16348 + return E_OK;
16349 +}
16350 +
16351 +/* .............................................................................. */
16352 +
16353 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16354 +{
16355 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16356 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16357 +
16358 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16359 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16360 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16361 +
16362 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16363 +
16364 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16365 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16366 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16367 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16368 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16369 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16370 +
16371 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16372 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16373 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16374 +
16375 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16376 +
16377 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16378 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16379 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16380 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16381 +
16382 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16383 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16384 +
16385 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16386 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16387 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16388 +
16389 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16390 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16391 +
16392 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16393 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16394 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16395 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16396 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16397 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16398 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16399 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16400 +
16401 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16402 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16403 +
16404 +}
16405 +
16406 +
16407 +/*****************************************************************************/
16408 +/* dTSEC Config Main Entry */
16409 +/*****************************************************************************/
16410 +
16411 +/* .............................................................................. */
16412 +
16413 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16414 +{
16415 + t_Dtsec *p_Dtsec;
16416 + struct dtsec_cfg *p_DtsecDriverParam;
16417 + uintptr_t baseAddr;
16418 +
16419 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16420 +
16421 + baseAddr = p_FmMacParam->baseAddr;
16422 +
16423 + /* allocate memory for the UCC GETH data structure. */
16424 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16425 + if (!p_Dtsec)
16426 + {
16427 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16428 + return NULL;
16429 + }
16430 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16431 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16432 +
16433 + /* allocate memory for the dTSEC driver parameters data structure. */
16434 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16435 + if (!p_DtsecDriverParam)
16436 + {
16437 + XX_Free(p_Dtsec);
16438 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16439 + return NULL;
16440 + }
16441 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16442 +
16443 + /* Plant parameter structure pointer */
16444 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16445 +
16446 + fman_dtsec_defconfig(p_DtsecDriverParam);
16447 +
16448 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16449 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16450 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16451 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16452 + p_Dtsec->macId = p_FmMacParam->macId;
16453 + p_Dtsec->exceptions = DEFAULT_exceptions;
16454 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16455 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16456 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16457 + p_Dtsec->h_App = p_FmMacParam->h_App;
16458 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16459 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16460 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16461 +
16462 + return p_Dtsec;
16463 +}
16464 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16465 new file mode 100644
16466 index 00000000..c26f40cc
16467 --- /dev/null
16468 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16469 @@ -0,0 +1,228 @@
16470 +/*
16471 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16472 + *
16473 + * Redistribution and use in source and binary forms, with or without
16474 + * modification, are permitted provided that the following conditions are met:
16475 + * * Redistributions of source code must retain the above copyright
16476 + * notice, this list of conditions and the following disclaimer.
16477 + * * Redistributions in binary form must reproduce the above copyright
16478 + * notice, this list of conditions and the following disclaimer in the
16479 + * documentation and/or other materials provided with the distribution.
16480 + * * Neither the name of Freescale Semiconductor nor the
16481 + * names of its contributors may be used to endorse or promote products
16482 + * derived from this software without specific prior written permission.
16483 + *
16484 + *
16485 + * ALTERNATIVELY, this software may be distributed under the terms of the
16486 + * GNU General Public License ("GPL") as published by the Free Software
16487 + * Foundation, either version 2 of that License or (at your option) any
16488 + * later version.
16489 + *
16490 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16491 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16492 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16493 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16494 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16495 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16496 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16497 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16498 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16499 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16500 + */
16501 +
16502 +/******************************************************************************
16503 + @File dtsec.h
16504 +
16505 + @Description FM dTSEC ...
16506 +*//***************************************************************************/
16507 +#ifndef __DTSEC_H
16508 +#define __DTSEC_H
16509 +
16510 +#include "std_ext.h"
16511 +#include "error_ext.h"
16512 +#include "list_ext.h"
16513 +#include "enet_ext.h"
16514 +
16515 +#include "dtsec_mii_acc.h"
16516 +#include "fm_mac.h"
16517 +
16518 +
16519 +#define DEFAULT_exceptions \
16520 + ((uint32_t)(DTSEC_IMASK_BREN | \
16521 + DTSEC_IMASK_RXCEN | \
16522 + DTSEC_IMASK_BTEN | \
16523 + DTSEC_IMASK_TXCEN | \
16524 + DTSEC_IMASK_TXEEN | \
16525 + DTSEC_IMASK_ABRTEN | \
16526 + DTSEC_IMASK_LCEN | \
16527 + DTSEC_IMASK_CRLEN | \
16528 + DTSEC_IMASK_XFUNEN | \
16529 + DTSEC_IMASK_IFERREN | \
16530 + DTSEC_IMASK_MAGEN | \
16531 + DTSEC_IMASK_TDPEEN | \
16532 + DTSEC_IMASK_RDPEEN))
16533 +
16534 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16535 + case e_FM_MAC_EX_1G_BAB_RX: \
16536 + bitMask = DTSEC_IMASK_BREN; break; \
16537 + case e_FM_MAC_EX_1G_RX_CTL: \
16538 + bitMask = DTSEC_IMASK_RXCEN; break; \
16539 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16540 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16541 + case e_FM_MAC_EX_1G_BAB_TX: \
16542 + bitMask = DTSEC_IMASK_BTEN ; break; \
16543 + case e_FM_MAC_EX_1G_TX_CTL: \
16544 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16545 + case e_FM_MAC_EX_1G_TX_ERR: \
16546 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16547 + case e_FM_MAC_EX_1G_LATE_COL: \
16548 + bitMask = DTSEC_IMASK_LCEN ; break; \
16549 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16550 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16551 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16552 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16553 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16554 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16555 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16556 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16557 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16558 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16559 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16560 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16561 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16562 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16563 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16564 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16565 + default: bitMask = 0;break;}
16566 +
16567 +
16568 +#define MAX_PACKET_ALIGNMENT 31
16569 +#define MAX_INTER_PACKET_GAP 0x7f
16570 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16571 +#define MAX_RETRANSMISSION 0x0f
16572 +#define MAX_COLLISION_WINDOW 0x03ff
16573 +
16574 +
16575 +/********************* From mac ext ******************************************/
16576 +typedef uint32_t t_ErrorDisable;
16577 +
16578 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16579 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16580 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16581 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16582 +#define ERROR_DISABLE_TxABORT 0x00008000
16583 +#define ERROR_DISABLE_INTERFACE 0x00004000
16584 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16585 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16586 +
16587 +/*****************************************************************************/
16588 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16589 +
16590 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16591 +
16592 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16593 +
16594 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16595 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16596 +
16597 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16598 +
16599 +#define MAX_PHYS 32 /* maximum number of phys */
16600 +
16601 +#define VAL32BIT 0x100000000LL
16602 +#define VAL22BIT 0x00400000
16603 +#define VAL16BIT 0x00010000
16604 +#define VAL12BIT 0x00001000
16605 +
16606 +/* CAR1/2 bits */
16607 +#define CAR1_TR64 0x80000000
16608 +#define CAR1_TR127 0x40000000
16609 +#define CAR1_TR255 0x20000000
16610 +#define CAR1_TR511 0x10000000
16611 +#define CAR1_TRK1 0x08000000
16612 +#define CAR1_TRMAX 0x04000000
16613 +#define CAR1_TRMGV 0x02000000
16614 +
16615 +#define CAR1_RBYT 0x00010000
16616 +#define CAR1_RPKT 0x00008000
16617 +#define CAR1_RMCA 0x00002000
16618 +#define CAR1_RBCA 0x00001000
16619 +#define CAR1_RXPF 0x00000400
16620 +#define CAR1_RALN 0x00000100
16621 +#define CAR1_RFLR 0x00000080
16622 +#define CAR1_RCDE 0x00000040
16623 +#define CAR1_RCSE 0x00000020
16624 +#define CAR1_RUND 0x00000010
16625 +#define CAR1_ROVR 0x00000008
16626 +#define CAR1_RFRG 0x00000004
16627 +#define CAR1_RJBR 0x00000002
16628 +#define CAR1_RDRP 0x00000001
16629 +
16630 +#define CAR2_TFCS 0x00040000
16631 +#define CAR2_TBYT 0x00002000
16632 +#define CAR2_TPKT 0x00001000
16633 +#define CAR2_TMCA 0x00000800
16634 +#define CAR2_TBCA 0x00000400
16635 +#define CAR2_TXPF 0x00000200
16636 +#define CAR2_TDRP 0x00000001
16637 +
16638 +typedef struct t_InternalStatistics
16639 +{
16640 + uint64_t tr64;
16641 + uint64_t tr127;
16642 + uint64_t tr255;
16643 + uint64_t tr511;
16644 + uint64_t tr1k;
16645 + uint64_t trmax;
16646 + uint64_t trmgv;
16647 + uint64_t rfrg;
16648 + uint64_t rjbr;
16649 + uint64_t rdrp;
16650 + uint64_t raln;
16651 + uint64_t rund;
16652 + uint64_t rovr;
16653 + uint64_t rxpf;
16654 + uint64_t txpf;
16655 + uint64_t rbyt;
16656 + uint64_t rpkt;
16657 + uint64_t rmca;
16658 + uint64_t rbca;
16659 + uint64_t rflr;
16660 + uint64_t rcde;
16661 + uint64_t rcse;
16662 + uint64_t tbyt;
16663 + uint64_t tpkt;
16664 + uint64_t tmca;
16665 + uint64_t tbca;
16666 + uint64_t tdrp;
16667 + uint64_t tfcs;
16668 +} t_InternalStatistics;
16669 +
16670 +typedef struct {
16671 + t_FmMacControllerDriver fmMacControllerDriver;
16672 + t_Handle h_App; /**< Handle to the upper layer application */
16673 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16674 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16675 + uint64_t addr; /**< MAC address of device; */
16676 + e_EnetMode enetMode; /**< Ethernet physical interface */
16677 + t_FmMacExceptionCallback *f_Exception;
16678 + int mdioIrq;
16679 + t_FmMacExceptionCallback *f_Event;
16680 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16681 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16682 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16683 + bool halfDuplex;
16684 + t_InternalStatistics internalStatistics;
16685 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16686 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16687 + uint8_t macId;
16688 + uint8_t tbi_phy_addr;
16689 + uint32_t exceptions;
16690 + bool ptpTsuEnabled;
16691 + bool enTsuErrExeption;
16692 + e_FmMacStatisticsLevel statisticsLevel;
16693 + struct dtsec_cfg *p_DtsecDriverParam;
16694 +} t_Dtsec;
16695 +
16696 +
16697 +#endif /* __DTSEC_H */
16698 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16699 new file mode 100644
16700 index 00000000..87da25ff
16701 --- /dev/null
16702 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16703 @@ -0,0 +1,97 @@
16704 +/*
16705 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16706 + *
16707 + * Redistribution and use in source and binary forms, with or without
16708 + * modification, are permitted provided that the following conditions are met:
16709 + * * Redistributions of source code must retain the above copyright
16710 + * notice, this list of conditions and the following disclaimer.
16711 + * * Redistributions in binary form must reproduce the above copyright
16712 + * notice, this list of conditions and the following disclaimer in the
16713 + * documentation and/or other materials provided with the distribution.
16714 + * * Neither the name of Freescale Semiconductor nor the
16715 + * names of its contributors may be used to endorse or promote products
16716 + * derived from this software without specific prior written permission.
16717 + *
16718 + *
16719 + * ALTERNATIVELY, this software may be distributed under the terms of the
16720 + * GNU General Public License ("GPL") as published by the Free Software
16721 + * Foundation, either version 2 of that License or (at your option) any
16722 + * later version.
16723 + *
16724 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16725 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16726 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16727 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16728 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16729 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16730 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16731 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16732 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16733 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16734 + */
16735 +
16736 +
16737 +/******************************************************************************
16738 + @File dtsec_mii_acc.c
16739 +
16740 + @Description FM dtsec MII register access MAC ...
16741 +*//***************************************************************************/
16742 +
16743 +#include "error_ext.h"
16744 +#include "std_ext.h"
16745 +#include "fm_mac.h"
16746 +#include "dtsec.h"
16747 +#include "fsl_fman_dtsec_mii_acc.h"
16748 +
16749 +
16750 +/*****************************************************************************/
16751 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16752 + uint8_t phyAddr,
16753 + uint8_t reg,
16754 + uint16_t data)
16755 +{
16756 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16757 + struct dtsec_mii_reg *miiregs;
16758 + uint16_t dtsec_freq;
16759 + t_Error err;
16760 +
16761 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16762 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16763 +
16764 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16765 + miiregs = p_Dtsec->p_MiiMemMap;
16766 +
16767 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16768 +
16769 + return err;
16770 +}
16771 +
16772 +/*****************************************************************************/
16773 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16774 + uint8_t phyAddr,
16775 + uint8_t reg,
16776 + uint16_t *p_Data)
16777 +{
16778 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16779 + struct dtsec_mii_reg *miiregs;
16780 + uint16_t dtsec_freq;
16781 + t_Error err;
16782 +
16783 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16784 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16785 +
16786 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16787 + miiregs = p_Dtsec->p_MiiMemMap;
16788 +
16789 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16790 +
16791 + if (*p_Data == 0xffff)
16792 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16793 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16794 + phyAddr, reg));
16795 + if (err)
16796 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16797 +
16798 + return E_OK;
16799 +}
16800 +
16801 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16802 new file mode 100644
16803 index 00000000..75cc658a
16804 --- /dev/null
16805 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16806 @@ -0,0 +1,42 @@
16807 +/*
16808 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16809 + *
16810 + * Redistribution and use in source and binary forms, with or without
16811 + * modification, are permitted provided that the following conditions are met:
16812 + * * Redistributions of source code must retain the above copyright
16813 + * notice, this list of conditions and the following disclaimer.
16814 + * * Redistributions in binary form must reproduce the above copyright
16815 + * notice, this list of conditions and the following disclaimer in the
16816 + * documentation and/or other materials provided with the distribution.
16817 + * * Neither the name of Freescale Semiconductor nor the
16818 + * names of its contributors may be used to endorse or promote products
16819 + * derived from this software without specific prior written permission.
16820 + *
16821 + *
16822 + * ALTERNATIVELY, this software may be distributed under the terms of the
16823 + * GNU General Public License ("GPL") as published by the Free Software
16824 + * Foundation, either version 2 of that License or (at your option) any
16825 + * later version.
16826 + *
16827 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16828 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16829 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16830 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16831 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16832 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16833 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16834 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16835 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16836 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16837 + */
16838 +
16839 +#ifndef __DTSEC_MII_ACC_H
16840 +#define __DTSEC_MII_ACC_H
16841 +
16842 +#include "std_ext.h"
16843 +
16844 +
16845 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16846 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16847 +
16848 +#endif /* __DTSEC_MII_ACC_H */
16849 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16850 new file mode 100644
16851 index 00000000..20bf150a
16852 --- /dev/null
16853 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16854 @@ -0,0 +1,658 @@
16855 +/*
16856 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16857 + *
16858 + * Redistribution and use in source and binary forms, with or without
16859 + * modification, are permitted provided that the following conditions are met:
16860 + * * Redistributions of source code must retain the above copyright
16861 + * notice, this list of conditions and the following disclaimer.
16862 + * * Redistributions in binary form must reproduce the above copyright
16863 + * notice, this list of conditions and the following disclaimer in the
16864 + * documentation and/or other materials provided with the distribution.
16865 + * * Neither the name of Freescale Semiconductor nor the
16866 + * names of its contributors may be used to endorse or promote products
16867 + * derived from this software without specific prior written permission.
16868 + *
16869 + *
16870 + * ALTERNATIVELY, this software may be distributed under the terms of the
16871 + * GNU General Public License ("GPL") as published by the Free Software
16872 + * Foundation, either version 2 of that License or (at your option) any
16873 + * later version.
16874 + *
16875 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16876 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16877 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16878 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16879 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16880 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16881 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16882 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16883 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16884 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16885 + */
16886 +
16887 +
16888 +/******************************************************************************
16889 + @File fm_mac.c
16890 +
16891 + @Description FM MAC ...
16892 +*//***************************************************************************/
16893 +#include "std_ext.h"
16894 +#include "string_ext.h"
16895 +#include "sprint_ext.h"
16896 +#include "error_ext.h"
16897 +#include "fm_ext.h"
16898 +
16899 +#include "fm_common.h"
16900 +#include "fm_mac.h"
16901 +
16902 +
16903 +/* ......................................................................... */
16904 +
16905 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
16906 +{
16907 + t_FmMacControllerDriver *p_FmMacControllerDriver;
16908 + uint16_t fmClkFreq;
16909 +
16910 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
16911 +
16912 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
16913 + if (fmClkFreq == 0)
16914 + {
16915 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
16916 + return NULL;
16917 + }
16918 +
16919 +#if (DPAA_VERSION == 10)
16920 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
16921 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
16922 + else
16923 +#if FM_MAX_NUM_OF_10G_MACS > 0
16924 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
16925 +#else
16926 + p_FmMacControllerDriver = NULL;
16927 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
16928 +#else
16929 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
16930 +#endif /* (DPAA_VERSION == 10) */
16931 +
16932 + if (!p_FmMacControllerDriver)
16933 + return NULL;
16934 +
16935 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
16936 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
16937 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
16938 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
16939 +
16940 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
16941 +
16942 + return (t_Handle)p_FmMacControllerDriver;
16943 +}
16944 +
16945 +/* ......................................................................... */
16946 +
16947 +t_Error FM_MAC_Init (t_Handle h_FmMac)
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->resetOnInit &&
16954 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
16955 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
16956 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
16957 + e_FM_MAC_10G : e_FM_MAC_1G),
16958 + p_FmMacControllerDriver->macId) != E_OK))
16959 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
16960 +
16961 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
16962 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
16963 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16964 +}
16965 +
16966 +/* ......................................................................... */
16967 +
16968 +t_Error FM_MAC_Free (t_Handle h_FmMac)
16969 +{
16970 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16971 +
16972 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16973 +
16974 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
16975 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
16976 +
16977 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16978 +}
16979 +
16980 +/* ......................................................................... */
16981 +
16982 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
16983 +{
16984 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16985 +
16986 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16987 +
16988 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
16989 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
16990 +
16991 + p_FmMacControllerDriver->resetOnInit = enable;
16992 +
16993 + return E_OK;
16994 +}
16995 +
16996 +/* ......................................................................... */
16997 +
16998 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
16999 +{
17000 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17001 +
17002 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17003 +
17004 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
17005 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
17006 +
17007 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17008 +}
17009 +
17010 +/* ......................................................................... */
17011 +
17012 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
17013 +{
17014 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17015 +
17016 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17017 +
17018 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
17019 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
17020 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17021 +}
17022 +
17023 +/* ......................................................................... */
17024 +
17025 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
17026 +{
17027 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17028 +
17029 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17030 +
17031 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
17032 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
17033 +
17034 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17035 +}
17036 +
17037 +/* ......................................................................... */
17038 +
17039 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
17040 +{
17041 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17042 +
17043 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17044 +
17045 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
17046 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
17047 +
17048 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17049 +}
17050 +
17051 +/* ......................................................................... */
17052 +
17053 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
17054 +{
17055 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17056 +
17057 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17058 +
17059 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
17060 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
17061 +
17062 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17063 +}
17064 +
17065 +/* ......................................................................... */
17066 +
17067 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
17068 +{
17069 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17070 +
17071 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17072 +
17073 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
17074 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
17075 +
17076 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17077 +}
17078 +
17079 +/* ......................................................................... */
17080 +
17081 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
17082 +{
17083 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17084 +
17085 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17086 +
17087 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
17088 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
17089 +
17090 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17091 +}
17092 +
17093 +/* ......................................................................... */
17094 +
17095 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17096 +{
17097 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17098 +
17099 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17100 +
17101 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
17102 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
17103 +
17104 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17105 +}
17106 +
17107 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17108 +/* ......................................................................... */
17109 +
17110 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
17111 +{
17112 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17113 +
17114 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17115 +
17116 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17117 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17118 +
17119 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17120 +}
17121 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17122 +
17123 +
17124 +/*****************************************************************************/
17125 +/* Run Time Control */
17126 +/*****************************************************************************/
17127 +
17128 +/* ......................................................................... */
17129 +
17130 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
17131 +{
17132 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17133 +
17134 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17135 +
17136 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
17137 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17138 +
17139 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17140 +}
17141 +
17142 +/* ......................................................................... */
17143 +
17144 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
17145 +{
17146 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17147 +
17148 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17149 +
17150 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
17151 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17152 +
17153 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17154 +}
17155 +
17156 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
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_Resume)
17163 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17164 +
17165 + return E_OK;
17166 +}
17167 +
17168 +/* ......................................................................... */
17169 +
17170 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
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_Enable1588TimeStamp)
17177 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17178 +
17179 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17180 +}
17181 +
17182 +/* ......................................................................... */
17183 +
17184 +t_Error FM_MAC_Disable1588TimeStamp (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_Disable1588TimeStamp)
17191 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17192 +
17193 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17194 +}
17195 +
17196 +/* ......................................................................... */
17197 +
17198 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17199 + uint16_t pauseTime)
17200 +{
17201 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17202 +
17203 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17204 +
17205 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17206 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17207 + pauseTime);
17208 +
17209 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17210 +}
17211 +
17212 +/* ......................................................................... */
17213 +
17214 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17215 + uint8_t priority,
17216 + uint16_t pauseTime,
17217 + uint16_t threshTime)
17218 +{
17219 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17220 +
17221 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17222 +
17223 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17224 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17225 + priority,
17226 + pauseTime,
17227 + threshTime);
17228 +
17229 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17230 +}
17231 +
17232 +/* ......................................................................... */
17233 +
17234 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17235 +{
17236 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17237 +
17238 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17239 +
17240 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17241 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17242 +
17243 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17244 +}
17245 +
17246 +/* ......................................................................... */
17247 +
17248 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17249 +{
17250 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17251 +
17252 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17253 +
17254 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17255 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17256 +
17257 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17258 +}
17259 +
17260 +/* ......................................................................... */
17261 +
17262 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17263 +{
17264 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17265 +
17266 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17267 +
17268 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17269 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17270 +
17271 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17272 +}
17273 +
17274 +/* ......................................................................... */
17275 +
17276 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17277 +{
17278 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17279 +
17280 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17281 +
17282 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17283 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17284 +
17285 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17286 +}
17287 +
17288 +/* ......................................................................... */
17289 +
17290 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17291 +{
17292 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17293 +
17294 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17295 +
17296 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17297 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17298 +
17299 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17300 +}
17301 +
17302 +/* ......................................................................... */
17303 +
17304 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
17305 +{
17306 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17307 +
17308 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17309 +
17310 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
17311 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17312 +
17313 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17314 +}
17315 +
17316 +/* ......................................................................... */
17317 +
17318 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17319 +{
17320 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17321 +
17322 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17323 +
17324 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17325 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17326 +
17327 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17328 +}
17329 +
17330 +/* ......................................................................... */
17331 +
17332 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17333 +{
17334 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17335 +
17336 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17337 +
17338 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17339 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17340 +
17341 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17342 +}
17343 +
17344 +/* ......................................................................... */
17345 +
17346 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17347 +{
17348 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17349 +
17350 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17351 +
17352 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17353 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17354 +
17355 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17356 +}
17357 +
17358 +/* ......................................................................... */
17359 +
17360 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17361 +{
17362 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17363 +
17364 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17365 +
17366 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17367 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17368 +
17369 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17370 +}
17371 +
17372 +/* ......................................................................... */
17373 +
17374 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17375 +{
17376 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17377 +
17378 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17379 +
17380 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17381 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17382 +
17383 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17384 +}
17385 +
17386 +/* ......................................................................... */
17387 +
17388 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17389 +{
17390 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17391 +
17392 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17393 +
17394 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17395 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17396 +
17397 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17398 +
17399 +}
17400 +
17401 +/* ......................................................................... */
17402 +
17403 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17404 +{
17405 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17406 +
17407 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17408 +
17409 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17410 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17411 +
17412 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17413 +}
17414 +
17415 +/* ......................................................................... */
17416 +
17417 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17418 +{
17419 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17420 +
17421 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17422 +
17423 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17424 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17425 +
17426 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17427 +}
17428 +
17429 +/* ......................................................................... */
17430 +
17431 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17432 +{
17433 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17434 +
17435 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17436 +
17437 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17438 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17439 +
17440 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17441 +}
17442 +
17443 +/* ......................................................................... */
17444 +
17445 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17446 +{
17447 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17448 +
17449 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17450 +
17451 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17452 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17453 +
17454 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17455 +}
17456 +
17457 +/* ......................................................................... */
17458 +
17459 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17460 +{
17461 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17462 +
17463 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17464 +
17465 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17466 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17467 +
17468 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17469 +}
17470 +
17471 +/* ......................................................................... */
17472 +
17473 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17474 +{
17475 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17476 +
17477 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17478 +
17479 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17480 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17481 +
17482 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17483 +}
17484 +
17485 +/* ......................................................................... */
17486 +
17487 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17488 +{
17489 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17490 +
17491 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17492 +
17493 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17494 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17495 +
17496 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17497 + return 0;
17498 +}
17499 +
17500 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17501 +/*****************************************************************************/
17502 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17503 +{
17504 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17505 +
17506 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17507 +
17508 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17509 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17510 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17511 +}
17512 +#endif /* (defined(DEBUG_ERRORS) && ... */
17513 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17514 new file mode 100644
17515 index 00000000..77b9a89d
17516 --- /dev/null
17517 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17518 @@ -0,0 +1,225 @@
17519 +/*
17520 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17521 + *
17522 + * Redistribution and use in source and binary forms, with or without
17523 + * modification, are permitted provided that the following conditions are met:
17524 + * * Redistributions of source code must retain the above copyright
17525 + * notice, this list of conditions and the following disclaimer.
17526 + * * Redistributions in binary form must reproduce the above copyright
17527 + * notice, this list of conditions and the following disclaimer in the
17528 + * documentation and/or other materials provided with the distribution.
17529 + * * Neither the name of Freescale Semiconductor nor the
17530 + * names of its contributors may be used to endorse or promote products
17531 + * derived from this software without specific prior written permission.
17532 + *
17533 + *
17534 + * ALTERNATIVELY, this software may be distributed under the terms of the
17535 + * GNU General Public License ("GPL") as published by the Free Software
17536 + * Foundation, either version 2 of that License or (at your option) any
17537 + * later version.
17538 + *
17539 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17540 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17541 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17542 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17543 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17544 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17545 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17546 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17547 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17548 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17549 + */
17550 +
17551 +
17552 +/******************************************************************************
17553 + @File fm_mac.h
17554 +
17555 + @Description FM MAC ...
17556 +*//***************************************************************************/
17557 +#ifndef __FM_MAC_H
17558 +#define __FM_MAC_H
17559 +
17560 +#include "std_ext.h"
17561 +#include "error_ext.h"
17562 +#include "list_ext.h"
17563 +#include "fm_mac_ext.h"
17564 +#include "fm_common.h"
17565 +
17566 +
17567 +#define __ERR_MODULE__ MODULE_FM_MAC
17568 +
17569 +/**************************************************************************//**
17570 + @Description defaults
17571 +*//***************************************************************************/
17572 +
17573 +
17574 +#define DEFAULT_halfDuplex FALSE
17575 +#define DEFAULT_padAndCrcEnable TRUE
17576 +#define DEFAULT_resetOnInit FALSE
17577 +
17578 +
17579 +typedef struct {
17580 + uint64_t addr; /* Ethernet Address */
17581 + t_List node;
17582 +} t_EthHashEntry;
17583 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17584 +
17585 +typedef struct {
17586 + uint16_t size;
17587 + t_List *p_Lsts;
17588 +} t_EthHash;
17589 +
17590 +typedef struct {
17591 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17592 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17593 +
17594 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17595 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17596 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17597 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17598 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17599 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17600 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17601 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17602 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17603 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17604 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17605 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17606 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17607 +
17608 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17609 +
17610 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17611 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17612 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17613 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17614 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17615 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17616 +
17617 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17618 + uint16_t pauseTime);
17619 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17620 + uint8_t priority,
17621 + uint16_t pauseTime,
17622 + uint16_t threshTime);
17623 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17624 +
17625 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17626 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17627 +
17628 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17629 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17630 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17631 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17632 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17633 +
17634 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17635 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17636 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17637 +
17638 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17639 +
17640 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17641 +
17642 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17643 +
17644 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17645 +
17646 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17647 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17648 +
17649 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17650 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17651 +#endif /* (defined(DEBUG_ERRORS) && ... */
17652 +
17653 + t_Handle h_Fm;
17654 + t_FmRevisionInfo fmRevInfo;
17655 + e_EnetMode enetMode;
17656 + uint8_t macId;
17657 + bool resetOnInit;
17658 + uint16_t clkFreq;
17659 +} t_FmMacControllerDriver;
17660 +
17661 +
17662 +#if (DPAA_VERSION == 10)
17663 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17664 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17665 +#else
17666 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17667 +#endif /* (DPAA_VERSION == 10) */
17668 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17669 +
17670 +
17671 +/* ........................................................................... */
17672 +
17673 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17674 +{
17675 + t_EthHashEntry *p_HashEntry = NULL;
17676 + if (!LIST_IsEmpty(p_AddrLst))
17677 + {
17678 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17679 + LIST_DelAndInit(&p_HashEntry->node);
17680 + }
17681 + return p_HashEntry;
17682 +}
17683 +
17684 +/* ........................................................................... */
17685 +
17686 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17687 +{
17688 + t_EthHashEntry *p_HashEntry;
17689 + int i = 0;
17690 +
17691 + if (p_Hash)
17692 + {
17693 + if (p_Hash->p_Lsts)
17694 + {
17695 + for (i=0; i<p_Hash->size; i++)
17696 + {
17697 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17698 + while (p_HashEntry)
17699 + {
17700 + XX_Free(p_HashEntry);
17701 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17702 + }
17703 + }
17704 +
17705 + XX_Free(p_Hash->p_Lsts);
17706 + }
17707 +
17708 + XX_Free(p_Hash);
17709 + }
17710 +}
17711 +
17712 +/* ........................................................................... */
17713 +
17714 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17715 +{
17716 + uint32_t i;
17717 + t_EthHash *p_Hash;
17718 +
17719 + /* Allocate address hash table */
17720 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17721 + if (!p_Hash)
17722 + {
17723 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17724 + return NULL;
17725 + }
17726 + p_Hash->size = size;
17727 +
17728 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17729 + if (!p_Hash->p_Lsts)
17730 + {
17731 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17732 + XX_Free(p_Hash);
17733 + return NULL;
17734 + }
17735 +
17736 + for (i=0 ; i<p_Hash->size; i++)
17737 + INIT_LIST(&p_Hash->p_Lsts[i]);
17738 +
17739 + return p_Hash;
17740 +}
17741 +
17742 +
17743 +#endif /* __FM_MAC_H */
17744 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17745 new file mode 100644
17746 index 00000000..b6a4ca25
17747 --- /dev/null
17748 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17749 @@ -0,0 +1,119 @@
17750 +/*
17751 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17752 + *
17753 + * Redistribution and use in source and binary forms, with or without
17754 + * modification, are permitted provided that the following conditions are met:
17755 + * * Redistributions of source code must retain the above copyright
17756 + * notice, this list of conditions and the following disclaimer.
17757 + * * Redistributions in binary form must reproduce the above copyright
17758 + * notice, this list of conditions and the following disclaimer in the
17759 + * documentation and/or other materials provided with the distribution.
17760 + * * Neither the name of Freescale Semiconductor nor the
17761 + * names of its contributors may be used to endorse or promote products
17762 + * derived from this software without specific prior written permission.
17763 + *
17764 + *
17765 + * ALTERNATIVELY, this software may be distributed under the terms of the
17766 + * GNU General Public License ("GPL") as published by the Free Software
17767 + * Foundation, either version 2 of that License or (at your option) any
17768 + * later version.
17769 + *
17770 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17771 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17772 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17773 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17774 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17775 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17776 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17777 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17778 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17779 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17780 + */
17781 +
17782 +
17783 +#include "fman_crc32.h"
17784 +#include "common/general.h"
17785 +
17786 +
17787 +/* precomputed CRC values for address hashing */
17788 +static const uint32_t crc_tbl[256] = {
17789 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17790 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17791 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17792 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17793 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17794 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17795 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17796 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17797 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17798 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17799 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17800 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17801 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17802 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17803 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17804 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17805 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17806 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17807 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17808 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17809 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17810 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17811 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17812 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17813 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17814 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17815 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17816 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17817 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17818 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17819 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17820 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17821 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17822 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17823 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17824 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17825 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17826 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17827 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17828 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17829 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17830 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17831 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17832 +};
17833 +
17834 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17835 +static inline uint8_t get_mirror8(uint8_t n)
17836 +{
17837 + uint8_t mirror[16] = {
17838 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17839 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17840 + };
17841 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17842 +}
17843 +
17844 +static inline uint32_t get_mirror32(uint32_t n)
17845 +{
17846 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17847 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17848 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17849 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17850 +}
17851 +
17852 +uint32_t get_mac_addr_crc(uint64_t _addr)
17853 +{
17854 + uint32_t i;
17855 + uint8_t data;
17856 + uint32_t crc;
17857 +
17858 + /* CRC calculation */
17859 + crc = 0xffffffff;
17860 + for (i = 0; i < 6; i++) {
17861 + data = (uint8_t)(_addr >> ((5-i)*8));
17862 + crc = crc ^ data;
17863 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17864 + }
17865 +
17866 + crc = get_mirror32(crc);
17867 + return crc;
17868 +}
17869 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17870 new file mode 100644
17871 index 00000000..6e32fdc6
17872 --- /dev/null
17873 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17874 @@ -0,0 +1,43 @@
17875 +/*
17876 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17877 + *
17878 + * Redistribution and use in source and binary forms, with or without
17879 + * modification, are permitted provided that the following conditions are met:
17880 + * * Redistributions of source code must retain the above copyright
17881 + * notice, this list of conditions and the following disclaimer.
17882 + * * Redistributions in binary form must reproduce the above copyright
17883 + * notice, this list of conditions and the following disclaimer in the
17884 + * documentation and/or other materials provided with the distribution.
17885 + * * Neither the name of Freescale Semiconductor nor the
17886 + * names of its contributors may be used to endorse or promote products
17887 + * derived from this software without specific prior written permission.
17888 + *
17889 + *
17890 + * ALTERNATIVELY, this software may be distributed under the terms of the
17891 + * GNU General Public License ("GPL") as published by the Free Software
17892 + * Foundation, either version 2 of that License or (at your option) any
17893 + * later version.
17894 + *
17895 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17896 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17897 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17898 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17899 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17900 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17901 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17902 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17903 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17904 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17905 + */
17906 +
17907 +
17908 +#ifndef __FMAN_CRC32_H
17909 +#define __FMAN_CRC32_H
17910 +
17911 +#include "common/general.h"
17912 +
17913 +
17914 +uint32_t get_mac_addr_crc(uint64_t _addr);
17915 +
17916 +
17917 +#endif /* __FMAN_CRC32_H */
17918 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17919 new file mode 100644
17920 index 00000000..5b092865
17921 --- /dev/null
17922 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17923 @@ -0,0 +1,845 @@
17924 +/*
17925 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17926 + *
17927 + * Redistribution and use in source and binary forms, with or without
17928 + * modification, are permitted provided that the following conditions are met:
17929 + * * Redistributions of source code must retain the above copyright
17930 + * notice, this list of conditions and the following disclaimer.
17931 + * * Redistributions in binary form must reproduce the above copyright
17932 + * notice, this list of conditions and the following disclaimer in the
17933 + * documentation and/or other materials provided with the distribution.
17934 + * * Neither the name of Freescale Semiconductor nor the
17935 + * names of its contributors may be used to endorse or promote products
17936 + * derived from this software without specific prior written permission.
17937 + *
17938 + *
17939 + * ALTERNATIVELY, this software may be distributed under the terms of the
17940 + * GNU General Public License ("GPL") as published by the Free Software
17941 + * Foundation, either version 2 of that License or (at your option) any
17942 + * later version.
17943 + *
17944 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17945 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17946 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17947 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17948 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17949 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17950 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17951 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17952 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17953 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17954 + */
17955 +
17956 +
17957 +#include "fsl_fman_dtsec.h"
17958 +
17959 +
17960 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
17961 +{
17962 + /* Assert the graceful stop bit */
17963 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
17964 +}
17965 +
17966 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
17967 +{
17968 + /* Assert the graceful stop bit */
17969 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
17970 +}
17971 +
17972 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
17973 +{
17974 + /* clear the graceful stop bit */
17975 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
17976 +}
17977 +
17978 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
17979 +{
17980 + /* clear the graceful stop bit */
17981 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
17982 +}
17983 +
17984 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
17985 +{
17986 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
17987 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
17988 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
17989 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
17990 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
17991 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
17992 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
17993 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
17994 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
17995 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
17996 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
17997 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
17998 + cfg->tx_crc = DEFAULT_TX_CRC;
17999 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
18000 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
18001 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
18002 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
18003 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
18004 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
18005 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
18006 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
18007 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
18008 + cfg->loopback = DEFAULT_LOOPBACK;
18009 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
18010 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
18011 + cfg->rx_flow = DEFAULT_RX_FLOW;
18012 + cfg->tx_flow = DEFAULT_TX_FLOW;
18013 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
18014 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
18015 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
18016 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
18017 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
18018 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
18019 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
18020 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
18021 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
18022 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
18023 +}
18024 +
18025 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
18026 + enum enet_interface iface_mode,
18027 + enum enet_speed iface_speed,
18028 + uint8_t *macaddr,
18029 + uint8_t fm_rev_maj,
18030 + uint8_t fm_rev_min,
18031 + uint32_t exception_mask)
18032 +{
18033 + bool is_rgmii = FALSE;
18034 + bool is_sgmii = FALSE;
18035 + bool is_qsgmii = FALSE;
18036 + int i;
18037 + uint32_t tmp;
18038 +
18039 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
18040 +
18041 + /* let's start with a soft reset */
18042 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
18043 + iowrite32be(0, &regs->maccfg1);
18044 +
18045 + /*************dtsec_id2******************/
18046 + tmp = ioread32be(&regs->tsec_id2);
18047 +
18048 + /* check RGMII support */
18049 + if (iface_mode == E_ENET_IF_RGMII ||
18050 + iface_mode == E_ENET_IF_RMII)
18051 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18052 + return -EINVAL;
18053 +
18054 + if (iface_mode == E_ENET_IF_SGMII ||
18055 + iface_mode == E_ENET_IF_MII)
18056 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18057 + return -EINVAL;
18058 +
18059 + /***************ECNTRL************************/
18060 +
18061 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
18062 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
18063 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
18064 +
18065 + tmp = 0;
18066 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
18067 + tmp |= DTSEC_ECNTRL_GMIIM;
18068 + if (is_sgmii)
18069 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
18070 + if (is_qsgmii)
18071 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
18072 + DTSEC_ECNTRL_QSGMIIM);
18073 + if (is_rgmii)
18074 + tmp |= DTSEC_ECNTRL_RPM;
18075 + if (iface_speed == E_ENET_SPEED_100)
18076 + tmp |= DTSEC_ECNTRL_R100M;
18077 +
18078 + iowrite32be(tmp, &regs->ecntrl);
18079 + /***************ECNTRL************************/
18080 +
18081 + /***************TCTRL************************/
18082 + tmp = 0;
18083 + if (cfg->halfdup_on)
18084 + tmp |= DTSEC_TCTRL_THDF;
18085 + if (cfg->tx_time_stamp_en)
18086 + tmp |= DTSEC_TCTRL_TTSE;
18087 +
18088 + iowrite32be(tmp, &regs->tctrl);
18089 +
18090 + /***************TCTRL************************/
18091 +
18092 + /***************PTV************************/
18093 + tmp = 0;
18094 +
18095 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
18096 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
18097 + cfg->tx_pause_time += 2;
18098 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
18099 +
18100 + if (cfg->tx_pause_time)
18101 + tmp |= cfg->tx_pause_time;
18102 + if (cfg->tx_pause_time_extd)
18103 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
18104 + iowrite32be(tmp, &regs->ptv);
18105 +
18106 + /***************RCTRL************************/
18107 + tmp = 0;
18108 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
18109 + if (cfg->rx_ctrl_acc)
18110 + tmp |= RCTRL_CFA;
18111 + if (cfg->rx_group_hash_exd)
18112 + tmp |= RCTRL_GHTX;
18113 + if (cfg->rx_time_stamp_en)
18114 + tmp |= RCTRL_RTSE;
18115 + if (cfg->rx_drop_bcast)
18116 + tmp |= RCTRL_BC_REJ;
18117 + if (cfg->rx_short_frm)
18118 + tmp |= RCTRL_RSF;
18119 + if (cfg->rx_promisc)
18120 + tmp |= RCTRL_PROM;
18121 +
18122 + iowrite32be(tmp, &regs->rctrl);
18123 + /***************RCTRL************************/
18124 +
18125 + /*
18126 + * Assign a Phy Address to the TBI (TBIPA).
18127 + * Done also in cases where TBI is not selected to avoid conflict with
18128 + * the external PHY's Physical address
18129 + */
18130 + iowrite32be(cfg->tbipa, &regs->tbipa);
18131 +
18132 + /***************TMR_CTL************************/
18133 + iowrite32be(0, &regs->tmr_ctrl);
18134 +
18135 + if (cfg->ptp_tsu_en) {
18136 + tmp = 0;
18137 + tmp |= TMR_PEVENT_TSRE;
18138 + iowrite32be(tmp, &regs->tmr_pevent);
18139 +
18140 + if (cfg->ptp_exception_en) {
18141 + tmp = 0;
18142 + tmp |= TMR_PEMASK_TSREEN;
18143 + iowrite32be(tmp, &regs->tmr_pemask);
18144 + }
18145 + }
18146 +
18147 + /***************MACCFG1***********************/
18148 + tmp = 0;
18149 + if (cfg->loopback)
18150 + tmp |= MACCFG1_LOOPBACK;
18151 + if (cfg->rx_flow)
18152 + tmp |= MACCFG1_RX_FLOW;
18153 + if (cfg->tx_flow)
18154 + tmp |= MACCFG1_TX_FLOW;
18155 + iowrite32be(tmp, &regs->maccfg1);
18156 +
18157 + /***************MACCFG1***********************/
18158 +
18159 + /***************MACCFG2***********************/
18160 + tmp = 0;
18161 +
18162 + if (iface_speed < E_ENET_SPEED_1000)
18163 + tmp |= MACCFG2_NIBBLE_MODE;
18164 + else if (iface_speed == E_ENET_SPEED_1000)
18165 + tmp |= MACCFG2_BYTE_MODE;
18166 +
18167 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18168 + << PREAMBLE_LENGTH_SHIFT;
18169 +
18170 + if (cfg->rx_preamble)
18171 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18172 + if (cfg->tx_preamble)
18173 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18174 + if (cfg->rx_len_check)
18175 + tmp |= MACCFG2_LENGTH_CHECK;
18176 + if (cfg->tx_pad_crc)
18177 + tmp |= MACCFG2_PAD_CRC_EN;
18178 + if (cfg->tx_crc)
18179 + tmp |= MACCFG2_CRC_EN;
18180 + if (!cfg->halfdup_on)
18181 + tmp |= MACCFG2_FULL_DUPLEX;
18182 + iowrite32be(tmp, &regs->maccfg2);
18183 +
18184 + /***************MACCFG2***********************/
18185 +
18186 + /***************IPGIFG************************/
18187 + tmp = (((cfg->non_back_to_back_ipg1 <<
18188 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18189 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18190 + | ((cfg->non_back_to_back_ipg2 <<
18191 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18192 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18193 + | ((cfg->min_ifg_enforcement <<
18194 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18195 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18196 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18197 + iowrite32be(tmp, &regs->ipgifg);
18198 +
18199 + /***************IPGIFG************************/
18200 +
18201 + /***************HAFDUP************************/
18202 + tmp = 0;
18203 +
18204 + if (cfg->halfdup_alt_backoff_en)
18205 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18206 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18207 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18208 + if (cfg->halfdup_bp_no_backoff)
18209 + tmp |= HAFDUP_BP_NO_BACKOFF;
18210 + if (cfg->halfdup_no_backoff)
18211 + tmp |= HAFDUP_NO_BACKOFF;
18212 + if (cfg->halfdup_excess_defer)
18213 + tmp |= HAFDUP_EXCESS_DEFER;
18214 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18215 + & HAFDUP_RETRANSMISSION_MAX);
18216 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18217 +
18218 + iowrite32be(tmp, &regs->hafdup);
18219 + /***************HAFDUP************************/
18220 +
18221 + /***************MAXFRM************************/
18222 + /* Initialize MAXFRM */
18223 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18224 +
18225 + /***************MAXFRM************************/
18226 +
18227 + /***************CAM1************************/
18228 + iowrite32be(0xffffffff, &regs->cam1);
18229 + iowrite32be(0xffffffff, &regs->cam2);
18230 +
18231 + /***************IMASK************************/
18232 + iowrite32be(exception_mask, &regs->imask);
18233 + /***************IMASK************************/
18234 +
18235 + /***************IEVENT************************/
18236 + iowrite32be(0xffffffff, &regs->ievent);
18237 +
18238 + /***************MACSTNADDR1/2*****************/
18239 +
18240 + tmp = (uint32_t)((macaddr[5] << 24) |
18241 + (macaddr[4] << 16) |
18242 + (macaddr[3] << 8) |
18243 + macaddr[2]);
18244 + iowrite32be(tmp, &regs->macstnaddr1);
18245 +
18246 + tmp = (uint32_t)((macaddr[1] << 24) |
18247 + (macaddr[0] << 16));
18248 + iowrite32be(tmp, &regs->macstnaddr2);
18249 +
18250 + /***************MACSTNADDR1/2*****************/
18251 +
18252 + /*****************HASH************************/
18253 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18254 + /* Initialize IADDRx */
18255 + iowrite32be(0, &regs->igaddr[i]);
18256 + /* Initialize GADDRx */
18257 + iowrite32be(0, &regs->gaddr[i]);
18258 + }
18259 +
18260 + fman_dtsec_reset_stat(regs);
18261 +
18262 + return 0;
18263 +}
18264 +
18265 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18266 +{
18267 + return (uint16_t)ioread32be(&regs->maxfrm);
18268 +}
18269 +
18270 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18271 +{
18272 + iowrite32be(length, &regs->maxfrm);
18273 +}
18274 +
18275 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18276 +{
18277 + uint32_t tmp;
18278 +
18279 + tmp = (uint32_t)((adr[5] << 24) |
18280 + (adr[4] << 16) |
18281 + (adr[3] << 8) |
18282 + adr[2]);
18283 + iowrite32be(tmp, &regs->macstnaddr1);
18284 +
18285 + tmp = (uint32_t)((adr[1] << 24) |
18286 + (adr[0] << 16));
18287 + iowrite32be(tmp, &regs->macstnaddr2);
18288 +}
18289 +
18290 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18291 +{
18292 + uint32_t tmp1, tmp2;
18293 +
18294 + tmp1 = ioread32be(&regs->macstnaddr1);
18295 + tmp2 = ioread32be(&regs->macstnaddr2);
18296 +
18297 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18298 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18299 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18300 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18301 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18302 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18303 +}
18304 +
18305 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18306 +{
18307 + int32_t bucket;
18308 + if (ghtx)
18309 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18310 + else {
18311 + bucket = (int32_t)((crc >> 24) & 0xff);
18312 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18313 + if (mcast)
18314 + bucket += 0x100;
18315 + }
18316 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18317 +}
18318 +
18319 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18320 +{
18321 + int reg_idx = (bucket >> 5) & 0xf;
18322 + int bit_idx = bucket & 0x1f;
18323 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18324 + uint32_t *reg;
18325 +
18326 + if (reg_idx > 7)
18327 + reg = &regs->gaddr[reg_idx-8];
18328 + else
18329 + reg = &regs->igaddr[reg_idx];
18330 +
18331 + if (enable)
18332 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18333 + else
18334 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18335 +}
18336 +
18337 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18338 +{
18339 + int i;
18340 + bool ghtx;
18341 +
18342 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18343 +
18344 + if (ucast || (ghtx && mcast)) {
18345 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18346 + iowrite32be(0, &regs->igaddr[i]);
18347 + }
18348 + if (mcast) {
18349 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18350 + iowrite32be(0, &regs->gaddr[i]);
18351 + }
18352 +}
18353 +
18354 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18355 + uint8_t addr)
18356 +{
18357 + if (addr > 0 && addr < 32)
18358 + iowrite32be(addr, &regs->tbipa);
18359 + else
18360 + return -EINVAL;
18361 +
18362 + return 0;
18363 +}
18364 +
18365 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18366 +{
18367 + uint32_t tmp;
18368 +
18369 + tmp = ioread32be(&regs->maccfg2);
18370 + if (en)
18371 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18372 + else
18373 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18374 + iowrite32be(tmp, &regs->maccfg2);
18375 +}
18376 +
18377 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18378 + enum enet_interface iface_mode,
18379 + enum enet_speed speed, bool full_dx)
18380 +{
18381 + uint32_t tmp;
18382 +
18383 + UNUSED(iface_mode);
18384 +
18385 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18386 + return -EINVAL;
18387 +
18388 + tmp = ioread32be(&regs->maccfg2);
18389 + if (!full_dx)
18390 + tmp &= ~MACCFG2_FULL_DUPLEX;
18391 + else
18392 + tmp |= MACCFG2_FULL_DUPLEX;
18393 +
18394 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18395 + if (speed < E_ENET_SPEED_1000)
18396 + tmp |= MACCFG2_NIBBLE_MODE;
18397 + else if (speed == E_ENET_SPEED_1000)
18398 + tmp |= MACCFG2_BYTE_MODE;
18399 + iowrite32be(tmp, &regs->maccfg2);
18400 +
18401 + tmp = ioread32be(&regs->ecntrl);
18402 + if (speed == E_ENET_SPEED_100)
18403 + tmp |= DTSEC_ECNTRL_R100M;
18404 + else
18405 + tmp &= ~DTSEC_ECNTRL_R100M;
18406 + iowrite32be(tmp, &regs->ecntrl);
18407 +
18408 + return 0;
18409 +}
18410 +
18411 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18412 +{
18413 + uint32_t tmp;
18414 +
18415 + tmp = ioread32be(&regs->rctrl);
18416 +
18417 + if (enable)
18418 + tmp |= RCTRL_UPROM;
18419 + else
18420 + tmp &= ~RCTRL_UPROM;
18421 +
18422 + iowrite32be(tmp, &regs->rctrl);
18423 +}
18424 +
18425 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18426 +{
18427 + uint32_t tmp;
18428 +
18429 + tmp = ioread32be(&regs->rctrl);
18430 +
18431 + if (enable)
18432 + tmp |= RCTRL_MPROM;
18433 + else
18434 + tmp &= ~RCTRL_MPROM;
18435 +
18436 + iowrite32be(tmp, &regs->rctrl);
18437 +}
18438 +
18439 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18440 + uint32_t *car1, uint32_t *car2)
18441 +{
18442 + /* read carry registers */
18443 + *car1 = ioread32be(&regs->car1);
18444 + *car2 = ioread32be(&regs->car2);
18445 + /* clear carry registers */
18446 + if (*car1)
18447 + iowrite32be(*car1, &regs->car1);
18448 + if (*car2)
18449 + iowrite32be(*car2, &regs->car2);
18450 +
18451 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18452 +}
18453 +
18454 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18455 +{
18456 + /* clear HW counters */
18457 + iowrite32be(ioread32be(&regs->ecntrl) |
18458 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18459 +}
18460 +
18461 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18462 +{
18463 + switch (level) {
18464 + case E_MAC_STAT_NONE:
18465 + iowrite32be(0xffffffff, &regs->cam1);
18466 + iowrite32be(0xffffffff, &regs->cam2);
18467 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18468 + &regs->ecntrl);
18469 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18470 + &regs->imask);
18471 + break;
18472 + case E_MAC_STAT_PARTIAL:
18473 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18474 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18475 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18476 + &regs->ecntrl);
18477 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18478 + &regs->imask);
18479 + break;
18480 + case E_MAC_STAT_MIB_GRP1:
18481 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18482 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18483 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18484 + &regs->ecntrl);
18485 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18486 + &regs->imask);
18487 + break;
18488 + case E_MAC_STAT_FULL:
18489 + iowrite32be(0, &regs->cam1);
18490 + iowrite32be(0, &regs->cam2);
18491 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18492 + &regs->ecntrl);
18493 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18494 + &regs->imask);
18495 + break;
18496 + default:
18497 + return -EINVAL;
18498 + }
18499 +
18500 + return 0;
18501 +}
18502 +
18503 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18504 +{
18505 + if (en) {
18506 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18507 + &regs->rctrl);
18508 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18509 + &regs->tctrl);
18510 + } else {
18511 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18512 + &regs->rctrl);
18513 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18514 + &regs->tctrl);
18515 + }
18516 +}
18517 +
18518 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18519 +{
18520 + uint32_t tmp;
18521 +
18522 + tmp = ioread32be(&regs->maccfg1);
18523 +
18524 + if (apply_rx)
18525 + tmp |= MACCFG1_RX_EN ;
18526 +
18527 + if (apply_tx)
18528 + tmp |= MACCFG1_TX_EN ;
18529 +
18530 + iowrite32be(tmp, &regs->maccfg1);
18531 +}
18532 +
18533 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18534 +{
18535 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18536 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18537 +}
18538 +
18539 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18540 + uint64_t addr,
18541 + uint8_t paddr_num)
18542 +{
18543 + uint32_t tmp;
18544 +
18545 + tmp = (uint32_t)(addr);
18546 + /* swap */
18547 + tmp = (((tmp & 0x000000FF) << 24) |
18548 + ((tmp & 0x0000FF00) << 8) |
18549 + ((tmp & 0x00FF0000) >> 8) |
18550 + ((tmp & 0xFF000000) >> 24));
18551 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18552 +
18553 + tmp = (uint32_t)(addr>>32);
18554 + /* swap */
18555 + tmp = (((tmp & 0x000000FF) << 24) |
18556 + ((tmp & 0x0000FF00) << 8) |
18557 + ((tmp & 0x00FF0000) >> 8) |
18558 + ((tmp & 0xFF000000) >> 24));
18559 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18560 +}
18561 +
18562 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18563 +{
18564 + uint32_t tmp;
18565 +
18566 + tmp = ioread32be(&regs->maccfg1);
18567 +
18568 + if (apply_rx)
18569 + tmp &= ~MACCFG1_RX_EN;
18570 +
18571 + if (apply_tx)
18572 + tmp &= ~MACCFG1_TX_EN;
18573 +
18574 + iowrite32be(tmp, &regs->maccfg1);
18575 +}
18576 +
18577 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18578 +{
18579 + uint32_t ptv = 0;
18580 +
18581 + /* fixme: don't enable tx pause for half-duplex */
18582 +
18583 + if (time) {
18584 + ptv = ioread32be(&regs->ptv);
18585 + ptv &= 0xffff0000;
18586 + ptv |= time & 0x0000ffff;
18587 + iowrite32be(ptv, &regs->ptv);
18588 +
18589 + /* trigger the transmission of a flow-control pause frame */
18590 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18591 + &regs->maccfg1);
18592 + } else
18593 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18594 + &regs->maccfg1);
18595 +}
18596 +
18597 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18598 +{
18599 + uint32_t tmp;
18600 +
18601 + /* todo: check if mac is set to full-duplex */
18602 +
18603 + tmp = ioread32be(&regs->maccfg1);
18604 + if (en)
18605 + tmp |= MACCFG1_RX_FLOW;
18606 + else
18607 + tmp &= ~MACCFG1_RX_FLOW;
18608 + iowrite32be(tmp, &regs->maccfg1);
18609 +}
18610 +
18611 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18612 +{
18613 + return ioread32be(&regs->rctrl);
18614 +}
18615 +
18616 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18617 +{
18618 + return ioread32be(&regs->tsec_id);
18619 +}
18620 +
18621 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18622 +{
18623 + return ioread32be(&regs->ievent) & ev_mask;
18624 +}
18625 +
18626 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18627 +{
18628 + iowrite32be(ev_mask, &regs->ievent);
18629 +}
18630 +
18631 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18632 +{
18633 + return ioread32be(&regs->imask);
18634 +}
18635 +
18636 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18637 +{
18638 + uint32_t event;
18639 +
18640 + event = ioread32be(&regs->tmr_pevent);
18641 + event &= ioread32be(&regs->tmr_pemask);
18642 +
18643 + if (event)
18644 + iowrite32be(event, &regs->tmr_pevent);
18645 + return event;
18646 +}
18647 +
18648 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18649 +{
18650 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18651 + &regs->tmr_pemask);
18652 +}
18653 +
18654 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18655 +{
18656 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18657 + &regs->tmr_pemask);
18658 +}
18659 +
18660 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18661 +{
18662 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18663 +}
18664 +
18665 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18666 +{
18667 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18668 +}
18669 +
18670 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18671 + enum dtsec_stat_counters reg_name)
18672 +{
18673 + uint32_t ret_val;
18674 +
18675 + switch (reg_name) {
18676 + case E_DTSEC_STAT_TR64:
18677 + ret_val = ioread32be(&regs->tr64);
18678 + break;
18679 + case E_DTSEC_STAT_TR127:
18680 + ret_val = ioread32be(&regs->tr127);
18681 + break;
18682 + case E_DTSEC_STAT_TR255:
18683 + ret_val = ioread32be(&regs->tr255);
18684 + break;
18685 + case E_DTSEC_STAT_TR511:
18686 + ret_val = ioread32be(&regs->tr511);
18687 + break;
18688 + case E_DTSEC_STAT_TR1K:
18689 + ret_val = ioread32be(&regs->tr1k);
18690 + break;
18691 + case E_DTSEC_STAT_TRMAX:
18692 + ret_val = ioread32be(&regs->trmax);
18693 + break;
18694 + case E_DTSEC_STAT_TRMGV:
18695 + ret_val = ioread32be(&regs->trmgv);
18696 + break;
18697 + case E_DTSEC_STAT_RBYT:
18698 + ret_val = ioread32be(&regs->rbyt);
18699 + break;
18700 + case E_DTSEC_STAT_RPKT:
18701 + ret_val = ioread32be(&regs->rpkt);
18702 + break;
18703 + case E_DTSEC_STAT_RMCA:
18704 + ret_val = ioread32be(&regs->rmca);
18705 + break;
18706 + case E_DTSEC_STAT_RBCA:
18707 + ret_val = ioread32be(&regs->rbca);
18708 + break;
18709 + case E_DTSEC_STAT_RXPF:
18710 + ret_val = ioread32be(&regs->rxpf);
18711 + break;
18712 + case E_DTSEC_STAT_RALN:
18713 + ret_val = ioread32be(&regs->raln);
18714 + break;
18715 + case E_DTSEC_STAT_RFLR:
18716 + ret_val = ioread32be(&regs->rflr);
18717 + break;
18718 + case E_DTSEC_STAT_RCDE:
18719 + ret_val = ioread32be(&regs->rcde);
18720 + break;
18721 + case E_DTSEC_STAT_RCSE:
18722 + ret_val = ioread32be(&regs->rcse);
18723 + break;
18724 + case E_DTSEC_STAT_RUND:
18725 + ret_val = ioread32be(&regs->rund);
18726 + break;
18727 + case E_DTSEC_STAT_ROVR:
18728 + ret_val = ioread32be(&regs->rovr);
18729 + break;
18730 + case E_DTSEC_STAT_RFRG:
18731 + ret_val = ioread32be(&regs->rfrg);
18732 + break;
18733 + case E_DTSEC_STAT_RJBR:
18734 + ret_val = ioread32be(&regs->rjbr);
18735 + break;
18736 + case E_DTSEC_STAT_RDRP:
18737 + ret_val = ioread32be(&regs->rdrp);
18738 + break;
18739 + case E_DTSEC_STAT_TFCS:
18740 + ret_val = ioread32be(&regs->tfcs);
18741 + break;
18742 + case E_DTSEC_STAT_TBYT:
18743 + ret_val = ioread32be(&regs->tbyt);
18744 + break;
18745 + case E_DTSEC_STAT_TPKT:
18746 + ret_val = ioread32be(&regs->tpkt);
18747 + break;
18748 + case E_DTSEC_STAT_TMCA:
18749 + ret_val = ioread32be(&regs->tmca);
18750 + break;
18751 + case E_DTSEC_STAT_TBCA:
18752 + ret_val = ioread32be(&regs->tbca);
18753 + break;
18754 + case E_DTSEC_STAT_TXPF:
18755 + ret_val = ioread32be(&regs->txpf);
18756 + break;
18757 + case E_DTSEC_STAT_TNCL:
18758 + ret_val = ioread32be(&regs->tncl);
18759 + break;
18760 + case E_DTSEC_STAT_TDRP:
18761 + ret_val = ioread32be(&regs->tdrp);
18762 + break;
18763 + default:
18764 + ret_val = 0;
18765 + }
18766 +
18767 + return ret_val;
18768 +}
18769 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18770 new file mode 100644
18771 index 00000000..8819f8fc
18772 --- /dev/null
18773 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18774 @@ -0,0 +1,163 @@
18775 +/*
18776 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18777 + *
18778 + * Redistribution and use in source and binary forms, with or without
18779 + * modification, are permitted provided that the following conditions are met:
18780 + * * Redistributions of source code must retain the above copyright
18781 + * notice, this list of conditions and the following disclaimer.
18782 + * * Redistributions in binary form must reproduce the above copyright
18783 + * notice, this list of conditions and the following disclaimer in the
18784 + * documentation and/or other materials provided with the distribution.
18785 + * * Neither the name of Freescale Semiconductor nor the
18786 + * names of its contributors may be used to endorse or promote products
18787 + * derived from this software without specific prior written permission.
18788 + *
18789 + *
18790 + * ALTERNATIVELY, this software may be distributed under the terms of the
18791 + * GNU General Public License ("GPL") as published by the Free Software
18792 + * Foundation, either version 2 of that License or (at your option) any
18793 + * later version.
18794 + *
18795 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18796 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18797 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18798 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18799 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18800 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18801 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18802 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18803 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18804 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18805 + */
18806 +
18807 +
18808 +#include "common/general.h"
18809 +#include "fsl_fman_dtsec_mii_acc.h"
18810 +
18811 +
18812 +/**
18813 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18814 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18815 + *
18816 + * This function calculates the dtsec mii clock divider that determines
18817 + * the MII MDC clock. MII MDC clock will be set to work in the range
18818 + * of 1.5 to 2.5Mhz
18819 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18820 + * implicitly determines the divider value.
18821 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18822 + *
18823 + * The table below which reflects dtsec_mii_get_div() functionality
18824 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18825 + * and the MII frequency:
18826 + *
18827 + * dtsec freq MgmtClk div MII freq Mhz
18828 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18829 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18830 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18831 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18832 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18833 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18834 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18835 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18836 + *
18837 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18838 + */
18839 +
18840 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18841 +{
18842 + uint16_t mgmt_clk;
18843 +
18844 + if (dtsec_freq < 80) mgmt_clk = 1;
18845 + else if (dtsec_freq < 120) mgmt_clk = 2;
18846 + else if (dtsec_freq < 160) mgmt_clk = 3;
18847 + else if (dtsec_freq < 200) mgmt_clk = 4;
18848 + else if (dtsec_freq < 280) mgmt_clk = 5;
18849 + else if (dtsec_freq < 400) mgmt_clk = 6;
18850 + else mgmt_clk = 7;
18851 +
18852 + return (uint8_t)mgmt_clk;
18853 +}
18854 +
18855 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18856 +{
18857 + /* Reset the management interface */
18858 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18859 + &regs->miimcfg);
18860 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18861 + &regs->miimcfg);
18862 +}
18863 +
18864 +
18865 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18866 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18867 +{
18868 + uint32_t tmp;
18869 +
18870 + /* Setup the MII Mgmt clock speed */
18871 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18872 + wmb();
18873 +
18874 + /* Stop the MII management read cycle */
18875 + iowrite32be(0, &regs->miimcom);
18876 + /* Dummy read to make sure MIIMCOM is written */
18877 + tmp = ioread32be(&regs->miimcom);
18878 + wmb();
18879 +
18880 + /* Setting up MII Management Address Register */
18881 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18882 + iowrite32be(tmp, &regs->miimadd);
18883 + wmb();
18884 +
18885 + /* Setting up MII Management Control Register with data */
18886 + iowrite32be((uint32_t)data, &regs->miimcon);
18887 + /* Dummy read to make sure MIIMCON is written */
18888 + tmp = ioread32be(&regs->miimcon);
18889 + wmb();
18890 +
18891 + /* Wait until MII management write is complete */
18892 + /* todo: a timeout could be useful here */
18893 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18894 + /* busy wait */;
18895 +
18896 + return 0;
18897 +}
18898 +
18899 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18900 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
18901 +{
18902 + uint32_t tmp;
18903 +
18904 + /* Setup the MII Mgmt clock speed */
18905 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18906 + wmb();
18907 +
18908 + /* Setting up the MII Management Address Register */
18909 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18910 + iowrite32be(tmp, &regs->miimadd);
18911 + wmb();
18912 +
18913 + /* Perform an MII management read cycle */
18914 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
18915 + /* Dummy read to make sure MIIMCOM is written */
18916 + tmp = ioread32be(&regs->miimcom);
18917 + wmb();
18918 +
18919 + /* Wait until MII management read is complete */
18920 + /* todo: a timeout could be useful here */
18921 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18922 + /* busy wait */;
18923 +
18924 + /* Read MII management status */
18925 + *data = (uint16_t)ioread32be(&regs->miimstat);
18926 + wmb();
18927 +
18928 + iowrite32be(0, &regs->miimcom);
18929 + /* Dummy read to make sure MIIMCOM is written */
18930 + tmp = ioread32be(&regs->miimcom);
18931 +
18932 + if (*data == 0xffff)
18933 + return -ENXIO;
18934 +
18935 + return 0;
18936 +}
18937 +
18938 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18939 new file mode 100644
18940 index 00000000..00995a10
18941 --- /dev/null
18942 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18943 @@ -0,0 +1,511 @@
18944 +/*
18945 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18946 + *
18947 + * Redistribution and use in source and binary forms, with or without
18948 + * modification, are permitted provided that the following conditions are met:
18949 + * * Redistributions of source code must retain the above copyright
18950 + * notice, this list of conditions and the following disclaimer.
18951 + * * Redistributions in binary form must reproduce the above copyright
18952 + * notice, this list of conditions and the following disclaimer in the
18953 + * documentation and/or other materials provided with the distribution.
18954 + * * Neither the name of Freescale Semiconductor nor the
18955 + * names of its contributors may be used to endorse or promote products
18956 + * derived from this software without specific prior written permission.
18957 + *
18958 + *
18959 + * ALTERNATIVELY, this software may be distributed under the terms of the
18960 + * GNU General Public License ("GPL") as published by the Free Software
18961 + * Foundation, either version 2 of that License or (at your option) any
18962 + * later version.
18963 + *
18964 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18965 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18966 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18967 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18968 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18969 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18970 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18971 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18972 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18973 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18974 + */
18975 +
18976 +
18977 +#include "fsl_fman_memac.h"
18978 +
18979 +
18980 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
18981 +{
18982 + return ioread32be(&regs->ievent) & ev_mask;
18983 +}
18984 +
18985 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
18986 +{
18987 + return ioread32be(&regs->imask);
18988 +}
18989 +
18990 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
18991 +{
18992 + iowrite32be(ev_mask, &regs->ievent);
18993 +}
18994 +
18995 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
18996 +{
18997 + uint32_t tmp;
18998 +
18999 + tmp = ioread32be(&regs->command_config);
19000 +
19001 + if (val)
19002 + tmp |= CMD_CFG_PROMIS_EN;
19003 + else
19004 + tmp &= ~CMD_CFG_PROMIS_EN;
19005 +
19006 + iowrite32be(tmp, &regs->command_config);
19007 +}
19008 +
19009 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
19010 + uint8_t paddr_num)
19011 +{
19012 + if (paddr_num == 0) {
19013 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
19014 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
19015 + } else {
19016 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
19017 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
19018 + }
19019 +}
19020 +
19021 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
19022 + uint8_t *adr,
19023 + uint8_t paddr_num)
19024 +{
19025 + uint32_t tmp0, tmp1;
19026 +
19027 + tmp0 = (uint32_t)(adr[0] |
19028 + adr[1] << 8 |
19029 + adr[2] << 16 |
19030 + adr[3] << 24);
19031 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19032 +
19033 + if (paddr_num == 0) {
19034 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
19035 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
19036 + } else {
19037 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
19038 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
19039 + }
19040 +}
19041 +
19042 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19043 +{
19044 + uint32_t tmp;
19045 +
19046 + tmp = ioread32be(&regs->command_config);
19047 +
19048 + if (apply_rx)
19049 + tmp |= CMD_CFG_RX_EN;
19050 +
19051 + if (apply_tx)
19052 + tmp |= CMD_CFG_TX_EN;
19053 +
19054 + iowrite32be(tmp, &regs->command_config);
19055 +}
19056 +
19057 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19058 +{
19059 + uint32_t tmp;
19060 +
19061 + tmp = ioread32be(&regs->command_config);
19062 +
19063 + if (apply_rx)
19064 + tmp &= ~CMD_CFG_RX_EN;
19065 +
19066 + if (apply_tx)
19067 + tmp &= ~CMD_CFG_TX_EN;
19068 +
19069 + iowrite32be(tmp, &regs->command_config);
19070 +}
19071 +
19072 +void fman_memac_reset_stat(struct memac_regs *regs)
19073 +{
19074 + uint32_t tmp;
19075 +
19076 + tmp = ioread32be(&regs->statn_config);
19077 +
19078 + tmp |= STATS_CFG_CLR;
19079 +
19080 + iowrite32be(tmp, &regs->statn_config);
19081 +
19082 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
19083 +}
19084 +
19085 +void fman_memac_reset(struct memac_regs *regs)
19086 +{
19087 + uint32_t tmp;
19088 +
19089 + tmp = ioread32be(&regs->command_config);
19090 +
19091 + tmp |= CMD_CFG_SW_RESET;
19092 +
19093 + iowrite32be(tmp, &regs->command_config);
19094 +
19095 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
19096 +}
19097 +
19098 +int fman_memac_init(struct memac_regs *regs,
19099 + struct memac_cfg *cfg,
19100 + enum enet_interface enet_interface,
19101 + enum enet_speed enet_speed,
19102 + bool slow_10g_if,
19103 + uint32_t exceptions)
19104 +{
19105 + uint32_t tmp;
19106 +
19107 + /* Config */
19108 + tmp = 0;
19109 + if (cfg->wan_mode_enable)
19110 + tmp |= CMD_CFG_WAN_MODE;
19111 + if (cfg->promiscuous_mode_enable)
19112 + tmp |= CMD_CFG_PROMIS_EN;
19113 + if (cfg->pause_forward_enable)
19114 + tmp |= CMD_CFG_PAUSE_FWD;
19115 + if (cfg->pause_ignore)
19116 + tmp |= CMD_CFG_PAUSE_IGNORE;
19117 + if (cfg->tx_addr_ins_enable)
19118 + tmp |= CMD_CFG_TX_ADDR_INS;
19119 + if (cfg->loopback_enable)
19120 + tmp |= CMD_CFG_LOOPBACK_EN;
19121 + if (cfg->cmd_frame_enable)
19122 + tmp |= CMD_CFG_CNT_FRM_EN;
19123 + if (cfg->send_idle_enable)
19124 + tmp |= CMD_CFG_SEND_IDLE;
19125 + if (cfg->no_length_check_enable)
19126 + tmp |= CMD_CFG_NO_LEN_CHK;
19127 + if (cfg->rx_sfd_any)
19128 + tmp |= CMD_CFG_SFD_ANY;
19129 + if (cfg->pad_enable)
19130 + tmp |= CMD_CFG_TX_PAD_EN;
19131 + if (cfg->wake_on_lan)
19132 + tmp |= CMD_CFG_MG;
19133 +
19134 + tmp |= CMD_CFG_CRC_FWD;
19135 +
19136 + iowrite32be(tmp, &regs->command_config);
19137 +
19138 + /* Max Frame Length */
19139 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19140 +
19141 + /* Pause Time */
19142 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19143 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19144 +
19145 + /* IF_MODE */
19146 + tmp = 0;
19147 + switch (enet_interface) {
19148 + case E_ENET_IF_XGMII:
19149 + case E_ENET_IF_XFI:
19150 + tmp |= IF_MODE_XGMII;
19151 + break;
19152 + default:
19153 + tmp |= IF_MODE_GMII;
19154 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19155 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19156 + }
19157 + iowrite32be(tmp, &regs->if_mode);
19158 +
19159 + /* TX_FIFO_SECTIONS */
19160 + tmp = 0;
19161 + if (enet_interface == E_ENET_IF_XGMII ||
19162 + enet_interface == E_ENET_IF_XFI) {
19163 + if(slow_10g_if) {
19164 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19165 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19166 + } else {
19167 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19168 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19169 + }
19170 + } else {
19171 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19172 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19173 + }
19174 + iowrite32be(tmp, &regs->tx_fifo_sections);
19175 +
19176 + /* clear all pending events and set-up interrupts */
19177 + fman_memac_ack_event(regs, 0xffffffff);
19178 + fman_memac_set_exception(regs, exceptions, TRUE);
19179 +
19180 + return 0;
19181 +}
19182 +
19183 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19184 +{
19185 + uint32_t tmp;
19186 +
19187 + tmp = ioread32be(&regs->imask);
19188 + if (enable)
19189 + tmp |= val;
19190 + else
19191 + tmp &= ~val;
19192 +
19193 + iowrite32be(tmp, &regs->imask);
19194 +}
19195 +
19196 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19197 +{
19198 + uint32_t i;
19199 + for (i = 0; i < 64; i++)
19200 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19201 +}
19202 +
19203 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19204 +{
19205 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19206 +}
19207 +
19208 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19209 +{
19210 + iowrite32be(val, &regs->hashtable_ctrl);
19211 +}
19212 +
19213 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19214 +{
19215 + uint32_t tmp;
19216 +
19217 + tmp = ioread32be(&regs->maxfrm);
19218 +
19219 + return(uint16_t)tmp;
19220 +}
19221 +
19222 +
19223 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19224 + uint8_t priority,
19225 + uint16_t pause_time,
19226 + uint16_t thresh_time)
19227 +{
19228 + uint32_t tmp;
19229 +
19230 + tmp = ioread32be(&regs->tx_fifo_sections);
19231 +
19232 + if (priority == 0xff) {
19233 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19234 + iowrite32be(tmp, &regs->tx_fifo_sections);
19235 +
19236 + tmp = ioread32be(&regs->command_config);
19237 + tmp &= ~CMD_CFG_PFC_MODE;
19238 + priority = 0;
19239 + } else {
19240 + GET_TX_EMPTY_PFC_VALUE(tmp);
19241 + iowrite32be(tmp, &regs->tx_fifo_sections);
19242 +
19243 + tmp = ioread32be(&regs->command_config);
19244 + tmp |= CMD_CFG_PFC_MODE;
19245 + }
19246 +
19247 + iowrite32be(tmp, &regs->command_config);
19248 +
19249 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19250 + if (priority % 2)
19251 + tmp &= 0x0000FFFF;
19252 + else
19253 + tmp &= 0xFFFF0000;
19254 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19255 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19256 +
19257 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19258 + if (priority % 2)
19259 + tmp &= 0x0000FFFF;
19260 + else
19261 + tmp &= 0xFFFF0000;
19262 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19263 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19264 +}
19265 +
19266 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19267 +{
19268 + uint32_t tmp;
19269 +
19270 + tmp = ioread32be(&regs->command_config);
19271 + if (enable)
19272 + tmp |= CMD_CFG_PAUSE_IGNORE;
19273 + else
19274 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19275 +
19276 + iowrite32be(tmp, &regs->command_config);
19277 +}
19278 +
19279 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19280 +{
19281 + uint32_t tmp;
19282 +
19283 + tmp = ioread32be(&regs->command_config);
19284 +
19285 + if (enable)
19286 + tmp |= CMD_CFG_MG;
19287 + else
19288 + tmp &= ~CMD_CFG_MG;
19289 +
19290 + iowrite32be(tmp, &regs->command_config);
19291 +}
19292 +
19293 +#define GET_MEMAC_CNTR_64(bn) \
19294 + (ioread32be(&regs->bn ## _l) | \
19295 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19296 +
19297 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19298 + enum memac_counters reg_name)
19299 +{
19300 + uint64_t ret_val;
19301 +
19302 + switch (reg_name) {
19303 + case E_MEMAC_COUNTER_R64:
19304 + ret_val = GET_MEMAC_CNTR_64(r64);
19305 + break;
19306 + case E_MEMAC_COUNTER_R127:
19307 + ret_val = GET_MEMAC_CNTR_64(r127);
19308 + break;
19309 + case E_MEMAC_COUNTER_R255:
19310 + ret_val = GET_MEMAC_CNTR_64(r255);
19311 + break;
19312 + case E_MEMAC_COUNTER_R511:
19313 + ret_val = GET_MEMAC_CNTR_64(r511);
19314 + break;
19315 + case E_MEMAC_COUNTER_R1023:
19316 + ret_val = GET_MEMAC_CNTR_64(r1023);
19317 + break;
19318 + case E_MEMAC_COUNTER_R1518:
19319 + ret_val = GET_MEMAC_CNTR_64(r1518);
19320 + break;
19321 + case E_MEMAC_COUNTER_R1519X:
19322 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19323 + break;
19324 + case E_MEMAC_COUNTER_RFRG:
19325 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19326 + break;
19327 + case E_MEMAC_COUNTER_RJBR:
19328 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19329 + break;
19330 + case E_MEMAC_COUNTER_RDRP:
19331 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19332 + break;
19333 + case E_MEMAC_COUNTER_RALN:
19334 + ret_val = GET_MEMAC_CNTR_64(raln);
19335 + break;
19336 + case E_MEMAC_COUNTER_TUND:
19337 + ret_val = GET_MEMAC_CNTR_64(tund);
19338 + break;
19339 + case E_MEMAC_COUNTER_ROVR:
19340 + ret_val = GET_MEMAC_CNTR_64(rovr);
19341 + break;
19342 + case E_MEMAC_COUNTER_RXPF:
19343 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19344 + break;
19345 + case E_MEMAC_COUNTER_TXPF:
19346 + ret_val = GET_MEMAC_CNTR_64(txpf);
19347 + break;
19348 + case E_MEMAC_COUNTER_ROCT:
19349 + ret_val = GET_MEMAC_CNTR_64(roct);
19350 + break;
19351 + case E_MEMAC_COUNTER_RMCA:
19352 + ret_val = GET_MEMAC_CNTR_64(rmca);
19353 + break;
19354 + case E_MEMAC_COUNTER_RBCA:
19355 + ret_val = GET_MEMAC_CNTR_64(rbca);
19356 + break;
19357 + case E_MEMAC_COUNTER_RPKT:
19358 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19359 + break;
19360 + case E_MEMAC_COUNTER_RUCA:
19361 + ret_val = GET_MEMAC_CNTR_64(ruca);
19362 + break;
19363 + case E_MEMAC_COUNTER_RERR:
19364 + ret_val = GET_MEMAC_CNTR_64(rerr);
19365 + break;
19366 + case E_MEMAC_COUNTER_TOCT:
19367 + ret_val = GET_MEMAC_CNTR_64(toct);
19368 + break;
19369 + case E_MEMAC_COUNTER_TMCA:
19370 + ret_val = GET_MEMAC_CNTR_64(tmca);
19371 + break;
19372 + case E_MEMAC_COUNTER_TBCA:
19373 + ret_val = GET_MEMAC_CNTR_64(tbca);
19374 + break;
19375 + case E_MEMAC_COUNTER_TUCA:
19376 + ret_val = GET_MEMAC_CNTR_64(tuca);
19377 + break;
19378 + case E_MEMAC_COUNTER_TERR:
19379 + ret_val = GET_MEMAC_CNTR_64(terr);
19380 + break;
19381 + default:
19382 + ret_val = 0;
19383 + }
19384 +
19385 + return ret_val;
19386 +}
19387 +
19388 +void fman_memac_adjust_link(struct memac_regs *regs,
19389 + enum enet_interface iface_mode,
19390 + enum enet_speed speed, bool full_dx)
19391 +{
19392 + uint32_t tmp;
19393 +
19394 + tmp = ioread32be(&regs->if_mode);
19395 +
19396 + if (full_dx)
19397 + tmp &= ~IF_MODE_HD;
19398 + else
19399 + tmp |= IF_MODE_HD;
19400 +
19401 + if (iface_mode == E_ENET_IF_RGMII) {
19402 + /* Configure RGMII in manual mode */
19403 + tmp &= ~IF_MODE_RGMII_AUTO;
19404 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19405 +
19406 + if (full_dx)
19407 + tmp |= IF_MODE_RGMII_FD;
19408 + else
19409 + tmp &= ~IF_MODE_RGMII_FD;
19410 +
19411 + switch (speed) {
19412 + case E_ENET_SPEED_1000:
19413 + tmp |= IF_MODE_RGMII_1000;
19414 + break;
19415 + case E_ENET_SPEED_100:
19416 + tmp |= IF_MODE_RGMII_100;
19417 + break;
19418 + case E_ENET_SPEED_10:
19419 + tmp |= IF_MODE_RGMII_10;
19420 + break;
19421 + default:
19422 + break;
19423 + }
19424 + }
19425 +
19426 + iowrite32be(tmp, &regs->if_mode);
19427 +}
19428 +
19429 +void fman_memac_defconfig(struct memac_cfg *cfg)
19430 +{
19431 + cfg->reset_on_init = FALSE;
19432 + cfg->wan_mode_enable = FALSE;
19433 + cfg->promiscuous_mode_enable = FALSE;
19434 + cfg->pause_forward_enable = FALSE;
19435 + cfg->pause_ignore = FALSE;
19436 + cfg->tx_addr_ins_enable = FALSE;
19437 + cfg->loopback_enable = FALSE;
19438 + cfg->cmd_frame_enable = FALSE;
19439 + cfg->rx_error_discard = FALSE;
19440 + cfg->send_idle_enable = FALSE;
19441 + cfg->no_length_check_enable = TRUE;
19442 + cfg->lgth_check_nostdr = FALSE;
19443 + cfg->time_stamp_enable = FALSE;
19444 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19445 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19446 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19447 + cfg->pad_enable = TRUE;
19448 + cfg->phy_tx_ena_on = FALSE;
19449 + cfg->rx_sfd_any = FALSE;
19450 + cfg->rx_pbl_fwd = FALSE;
19451 + cfg->tx_pbl_fwd = FALSE;
19452 + cfg->debug_mode = FALSE;
19453 + cfg->wake_on_lan = FALSE;
19454 +}
19455 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19456 new file mode 100755
19457 index 00000000..ccda11ec
19458 --- /dev/null
19459 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19460 @@ -0,0 +1,213 @@
19461 +/*
19462 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19463 + *
19464 + * Redistribution and use in source and binary forms, with or without
19465 + * modification, are permitted provided that the following conditions are met:
19466 + * * Redistributions of source code must retain the above copyright
19467 + * notice, this list of conditions and the following disclaimer.
19468 + * * Redistributions in binary form must reproduce the above copyright
19469 + * notice, this list of conditions and the following disclaimer in the
19470 + * documentation and/or other materials provided with the distribution.
19471 + * * Neither the name of Freescale Semiconductor nor the
19472 + * names of its contributors may be used to endorse or promote products
19473 + * derived from this software without specific prior written permission.
19474 + *
19475 + *
19476 + * ALTERNATIVELY, this software may be distributed under the terms of the
19477 + * GNU General Public License ("GPL") as published by the Free Software
19478 + * Foundation, either version 2 of that License or (at your option) any
19479 + * later version.
19480 + *
19481 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19482 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19483 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19484 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19485 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19486 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19487 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19488 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19489 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19490 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19491 + */
19492 +
19493 +
19494 +#include "fsl_fman_memac_mii_acc.h"
19495 +
19496 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19497 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19498 +{
19499 + uint32_t tmp_reg;
19500 +
19501 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19502 + /* Leave only MDIO_CLK_DIV bits set on */
19503 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19504 + /* Set maximum MDIO_HOLD value to allow phy to see
19505 + change of data signal */
19506 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19507 + /* Add 10G interface mode */
19508 + tmp_reg |= MDIO_CFG_ENC45;
19509 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19510 +
19511 + /* Wait for command completion */
19512 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19513 + udelay(1);
19514 +
19515 + /* Specify phy and register to be accessed */
19516 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19517 + iowrite32be(reg, &mii_regs->mdio_addr);
19518 + wmb();
19519 +
19520 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19521 + udelay(1);
19522 +
19523 + /* Write data */
19524 + iowrite32be(data, &mii_regs->mdio_data);
19525 + wmb();
19526 +
19527 + /* Wait for write transaction end */
19528 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19529 + udelay(1);
19530 +}
19531 +
19532 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19533 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19534 +{
19535 + uint32_t tmp_reg;
19536 +
19537 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19538 + /* Leave only MDIO_CLK_DIV bits set on */
19539 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19540 + /* Set maximum MDIO_HOLD value to allow phy to see
19541 + change of data signal */
19542 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19543 + /* Add 10G interface mode */
19544 + tmp_reg |= MDIO_CFG_ENC45;
19545 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19546 +
19547 + /* Wait for command completion */
19548 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19549 + udelay(1);
19550 +
19551 + /* Specify phy and register to be accessed */
19552 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19553 + iowrite32be(reg, &mii_regs->mdio_addr);
19554 + wmb();
19555 +
19556 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19557 + udelay(1);
19558 +
19559 + /* Read cycle */
19560 + tmp_reg = phy_addr;
19561 + tmp_reg |= MDIO_CTL_READ;
19562 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19563 + wmb();
19564 +
19565 + /* Wait for data to be available */
19566 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19567 + udelay(1);
19568 +
19569 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19570 +
19571 + /* Check if there was an error */
19572 + return ioread32be(&mii_regs->mdio_cfg);
19573 +}
19574 +
19575 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19576 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19577 +{
19578 + uint32_t tmp_reg;
19579 +
19580 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19581 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19582 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19583 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19584 +
19585 + /* Wait for command completion */
19586 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19587 + udelay(1);
19588 +
19589 + /* Write transaction */
19590 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19591 + tmp_reg |= reg;
19592 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19593 +
19594 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19595 + udelay(1);
19596 +
19597 + iowrite32be(data, &mii_regs->mdio_data);
19598 +
19599 + wmb();
19600 +
19601 + /* Wait for write transaction to end */
19602 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19603 + udelay(1);
19604 +}
19605 +
19606 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19607 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19608 +{
19609 + uint32_t tmp_reg;
19610 +
19611 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19612 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19613 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19614 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19615 +
19616 + /* Wait for command completion */
19617 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19618 + udelay(1);
19619 +
19620 + /* Read transaction */
19621 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19622 + tmp_reg |= reg;
19623 + tmp_reg |= MDIO_CTL_READ;
19624 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19625 +
19626 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19627 + udelay(1);
19628 +
19629 + /* Wait for data to be available */
19630 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19631 + udelay(1);
19632 +
19633 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19634 +
19635 + /* Check error */
19636 + return ioread32be(&mii_regs->mdio_cfg);
19637 +}
19638 +
19639 +/*****************************************************************************/
19640 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19641 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19642 + enum enet_speed enet_speed)
19643 +{
19644 + /* Figure out interface type - 10G vs 1G.
19645 + In 10G interface both phy_addr and devAddr present. */
19646 + if (enet_speed == E_ENET_SPEED_10000)
19647 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19648 + else
19649 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19650 +
19651 + return 0;
19652 +}
19653 +
19654 +/*****************************************************************************/
19655 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19656 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19657 + enum enet_speed enet_speed)
19658 +{
19659 + uint32_t ans;
19660 + /* Figure out interface type - 10G vs 1G.
19661 + In 10G interface both phy_addr and devAddr present. */
19662 + if (enet_speed == E_ENET_SPEED_10000)
19663 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19664 + else
19665 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19666 +
19667 + if (ans & MDIO_CFG_READ_ERR)
19668 + return -EINVAL;
19669 + return 0;
19670 +}
19671 +
19672 +/* ......................................................................... */
19673 +
19674 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19675 new file mode 100644
19676 index 00000000..fff9d5de
19677 --- /dev/null
19678 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19679 @@ -0,0 +1,367 @@
19680 +/*
19681 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19682 + *
19683 + * Redistribution and use in source and binary forms, with or without
19684 + * modification, are permitted provided that the following conditions are met:
19685 + * * Redistributions of source code must retain the above copyright
19686 + * notice, this list of conditions and the following disclaimer.
19687 + * * Redistributions in binary form must reproduce the above copyright
19688 + * notice, this list of conditions and the following disclaimer in the
19689 + * documentation and/or other materials provided with the distribution.
19690 + * * Neither the name of Freescale Semiconductor nor the
19691 + * names of its contributors may be used to endorse or promote products
19692 + * derived from this software without specific prior written permission.
19693 + *
19694 + *
19695 + * ALTERNATIVELY, this software may be distributed under the terms of the
19696 + * GNU General Public License ("GPL") as published by the Free Software
19697 + * Foundation, either version 2 of that License or (at your option) any
19698 + * later version.
19699 + *
19700 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19701 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19702 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19703 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19704 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19705 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19706 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19707 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19708 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19709 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19710 + */
19711 +
19712 +
19713 +#include "fsl_fman_tgec.h"
19714 +
19715 +
19716 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19717 +{
19718 + uint32_t tmp0, tmp1;
19719 +
19720 + tmp0 = (uint32_t)(adr[0] |
19721 + adr[1] << 8 |
19722 + adr[2] << 16 |
19723 + adr[3] << 24);
19724 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19725 + iowrite32be(tmp0, &regs->mac_addr_0);
19726 + iowrite32be(tmp1, &regs->mac_addr_1);
19727 +}
19728 +
19729 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19730 +{
19731 + uint32_t tmp;
19732 +
19733 + tmp = ioread32be(&regs->command_config);
19734 +
19735 + tmp |= CMD_CFG_STAT_CLR;
19736 +
19737 + iowrite32be(tmp, &regs->command_config);
19738 +
19739 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19740 +}
19741 +
19742 +#define GET_TGEC_CNTR_64(bn) \
19743 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19744 + ioread32be(&regs->bn ## _l))
19745 +
19746 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19747 +{
19748 + uint64_t ret_val;
19749 +
19750 + switch (reg_name) {
19751 + case E_TGEC_COUNTER_R64:
19752 + ret_val = GET_TGEC_CNTR_64(r64);
19753 + break;
19754 + case E_TGEC_COUNTER_R127:
19755 + ret_val = GET_TGEC_CNTR_64(r127);
19756 + break;
19757 + case E_TGEC_COUNTER_R255:
19758 + ret_val = GET_TGEC_CNTR_64(r255);
19759 + break;
19760 + case E_TGEC_COUNTER_R511:
19761 + ret_val = GET_TGEC_CNTR_64(r511);
19762 + break;
19763 + case E_TGEC_COUNTER_R1023:
19764 + ret_val = GET_TGEC_CNTR_64(r1023);
19765 + break;
19766 + case E_TGEC_COUNTER_R1518:
19767 + ret_val = GET_TGEC_CNTR_64(r1518);
19768 + break;
19769 + case E_TGEC_COUNTER_R1519X:
19770 + ret_val = GET_TGEC_CNTR_64(r1519x);
19771 + break;
19772 + case E_TGEC_COUNTER_TRFRG:
19773 + ret_val = GET_TGEC_CNTR_64(trfrg);
19774 + break;
19775 + case E_TGEC_COUNTER_TRJBR:
19776 + ret_val = GET_TGEC_CNTR_64(trjbr);
19777 + break;
19778 + case E_TGEC_COUNTER_RDRP:
19779 + ret_val = GET_TGEC_CNTR_64(rdrp);
19780 + break;
19781 + case E_TGEC_COUNTER_RALN:
19782 + ret_val = GET_TGEC_CNTR_64(raln);
19783 + break;
19784 + case E_TGEC_COUNTER_TRUND:
19785 + ret_val = GET_TGEC_CNTR_64(trund);
19786 + break;
19787 + case E_TGEC_COUNTER_TROVR:
19788 + ret_val = GET_TGEC_CNTR_64(trovr);
19789 + break;
19790 + case E_TGEC_COUNTER_RXPF:
19791 + ret_val = GET_TGEC_CNTR_64(rxpf);
19792 + break;
19793 + case E_TGEC_COUNTER_TXPF:
19794 + ret_val = GET_TGEC_CNTR_64(txpf);
19795 + break;
19796 + case E_TGEC_COUNTER_ROCT:
19797 + ret_val = GET_TGEC_CNTR_64(roct);
19798 + break;
19799 + case E_TGEC_COUNTER_RMCA:
19800 + ret_val = GET_TGEC_CNTR_64(rmca);
19801 + break;
19802 + case E_TGEC_COUNTER_RBCA:
19803 + ret_val = GET_TGEC_CNTR_64(rbca);
19804 + break;
19805 + case E_TGEC_COUNTER_RPKT:
19806 + ret_val = GET_TGEC_CNTR_64(rpkt);
19807 + break;
19808 + case E_TGEC_COUNTER_RUCA:
19809 + ret_val = GET_TGEC_CNTR_64(ruca);
19810 + break;
19811 + case E_TGEC_COUNTER_RERR:
19812 + ret_val = GET_TGEC_CNTR_64(rerr);
19813 + break;
19814 + case E_TGEC_COUNTER_TOCT:
19815 + ret_val = GET_TGEC_CNTR_64(toct);
19816 + break;
19817 + case E_TGEC_COUNTER_TMCA:
19818 + ret_val = GET_TGEC_CNTR_64(tmca);
19819 + break;
19820 + case E_TGEC_COUNTER_TBCA:
19821 + ret_val = GET_TGEC_CNTR_64(tbca);
19822 + break;
19823 + case E_TGEC_COUNTER_TUCA:
19824 + ret_val = GET_TGEC_CNTR_64(tuca);
19825 + break;
19826 + case E_TGEC_COUNTER_TERR:
19827 + ret_val = GET_TGEC_CNTR_64(terr);
19828 + break;
19829 + default:
19830 + ret_val = 0;
19831 + }
19832 +
19833 + return ret_val;
19834 +}
19835 +
19836 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19837 +{
19838 + uint32_t tmp;
19839 +
19840 + tmp = ioread32be(&regs->command_config);
19841 + if (apply_rx)
19842 + tmp |= CMD_CFG_RX_EN;
19843 + if (apply_tx)
19844 + tmp |= CMD_CFG_TX_EN;
19845 + iowrite32be(tmp, &regs->command_config);
19846 +}
19847 +
19848 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19849 +{
19850 + uint32_t tmp_reg_32;
19851 +
19852 + tmp_reg_32 = ioread32be(&regs->command_config);
19853 + if (apply_rx)
19854 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19855 + if (apply_tx)
19856 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19857 + iowrite32be(tmp_reg_32, &regs->command_config);
19858 +}
19859 +
19860 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19861 +{
19862 + uint32_t tmp;
19863 +
19864 + tmp = ioread32be(&regs->command_config);
19865 + if (val)
19866 + tmp |= CMD_CFG_PROMIS_EN;
19867 + else
19868 + tmp &= ~CMD_CFG_PROMIS_EN;
19869 + iowrite32be(tmp, &regs->command_config);
19870 +}
19871 +
19872 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
19873 +{
19874 + uint32_t i;
19875 + for (i = 0; i < 512; i++)
19876 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19877 +}
19878 +
19879 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
19880 +{
19881 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
19882 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19883 +}
19884 +
19885 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
19886 +{
19887 + iowrite32be(value, &regs->hashtable_ctrl);
19888 +}
19889 +
19890 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
19891 +{
19892 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
19893 +}
19894 +
19895 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
19896 +{
19897 + uint32_t tmp;
19898 +
19899 + tmp = ioread32be(&regs->command_config);
19900 + if (en)
19901 + tmp |= CMD_CFG_PAUSE_IGNORE;
19902 + else
19903 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19904 + iowrite32be(tmp, &regs->command_config);
19905 +}
19906 +
19907 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
19908 +{
19909 + uint32_t tmp;
19910 +
19911 + tmp = ioread32be(&regs->command_config);
19912 + if (en)
19913 + tmp |= CMD_CFG_EN_TIMESTAMP;
19914 + else
19915 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
19916 + iowrite32be(tmp, &regs->command_config);
19917 +}
19918 +
19919 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
19920 +{
19921 + return ioread32be(&regs->ievent) & ev_mask;
19922 +}
19923 +
19924 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
19925 +{
19926 + iowrite32be(ev_mask, &regs->ievent);
19927 +}
19928 +
19929 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
19930 +{
19931 + return ioread32be(&regs->imask);
19932 +}
19933 +
19934 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
19935 +{
19936 + uint32_t tmp0, tmp1;
19937 +
19938 + tmp0 = (uint32_t)(adr[0] |
19939 + adr[1] << 8 |
19940 + adr[2] << 16 |
19941 + adr[3] << 24);
19942 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19943 + iowrite32be(tmp0, &regs->mac_addr_2);
19944 + iowrite32be(tmp1, &regs->mac_addr_3);
19945 +}
19946 +
19947 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
19948 +{
19949 + iowrite32be(0, &regs->mac_addr_2);
19950 + iowrite32be(0, &regs->mac_addr_3);
19951 +}
19952 +
19953 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
19954 +{
19955 + return ioread32be(&regs->tgec_id);
19956 +}
19957 +
19958 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19959 +{
19960 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
19961 +}
19962 +
19963 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19964 +{
19965 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
19966 +}
19967 +
19968 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
19969 +{
19970 + return (uint16_t) ioread32be(&regs->maxfrm);
19971 +}
19972 +
19973 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
19974 +{
19975 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
19976 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
19977 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
19978 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
19979 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
19980 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
19981 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
19982 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
19983 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
19984 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
19985 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
19986 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
19987 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19988 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
19989 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
19990 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19991 + cfg->skip_fman11_workaround = FALSE;
19992 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19993 +}
19994 +
19995 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
19996 + uint32_t exception_mask)
19997 +{
19998 + uint32_t tmp;
19999 +
20000 + /* Config */
20001 + tmp = 0x40; /* CRC forward */
20002 + if (cfg->wan_mode_enable)
20003 + tmp |= CMD_CFG_WAN_MODE;
20004 + if (cfg->promiscuous_mode_enable)
20005 + tmp |= CMD_CFG_PROMIS_EN;
20006 + if (cfg->pause_forward_enable)
20007 + tmp |= CMD_CFG_PAUSE_FWD;
20008 + if (cfg->pause_ignore)
20009 + tmp |= CMD_CFG_PAUSE_IGNORE;
20010 + if (cfg->tx_addr_ins_enable)
20011 + tmp |= CMD_CFG_TX_ADDR_INS;
20012 + if (cfg->loopback_enable)
20013 + tmp |= CMD_CFG_LOOPBACK_EN;
20014 + if (cfg->cmd_frame_enable)
20015 + tmp |= CMD_CFG_CMD_FRM_EN;
20016 + if (cfg->rx_error_discard)
20017 + tmp |= CMD_CFG_RX_ER_DISC;
20018 + if (cfg->send_idle_enable)
20019 + tmp |= CMD_CFG_SEND_IDLE;
20020 + if (cfg->no_length_check_enable)
20021 + tmp |= CMD_CFG_NO_LEN_CHK;
20022 + if (cfg->time_stamp_enable)
20023 + tmp |= CMD_CFG_EN_TIMESTAMP;
20024 + iowrite32be(tmp, &regs->command_config);
20025 +
20026 + /* Max Frame Length */
20027 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
20028 + /* Pause Time */
20029 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
20030 +
20031 + /* clear all pending events and set-up interrupts */
20032 + fman_tgec_ack_event(regs, 0xffffffff);
20033 + fman_tgec_enable_interrupt(regs, exception_mask);
20034 +
20035 + return 0;
20036 +}
20037 +
20038 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
20039 +{
20040 + uint32_t tmp;
20041 +
20042 + /* restore the default tx ipg Length */
20043 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
20044 +
20045 + iowrite32be(tmp, &regs->tx_ipg_len);
20046 +}
20047 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
20048 new file mode 100644
20049 index 00000000..85426c5f
20050 --- /dev/null
20051 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
20052 @@ -0,0 +1,1096 @@
20053 +/*
20054 + * Copyright 2008-2012 Freescale Semiconductor Inc.
20055 + *
20056 + * Redistribution and use in source and binary forms, with or without
20057 + * modification, are permitted provided that the following conditions are met:
20058 + * * Redistributions of source code must retain the above copyright
20059 + * notice, this list of conditions and the following disclaimer.
20060 + * * Redistributions in binary form must reproduce the above copyright
20061 + * notice, this list of conditions and the following disclaimer in the
20062 + * documentation and/or other materials provided with the distribution.
20063 + * * Neither the name of Freescale Semiconductor nor the
20064 + * names of its contributors may be used to endorse or promote products
20065 + * derived from this software without specific prior written permission.
20066 + *
20067 + *
20068 + * ALTERNATIVELY, this software may be distributed under the terms of the
20069 + * GNU General Public License ("GPL") as published by the Free Software
20070 + * Foundation, either version 2 of that License or (at your option) any
20071 + * later version.
20072 + *
20073 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20074 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20075 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20076 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20077 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20078 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20079 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20080 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20081 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20082 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20083 + */
20084 +
20085 +
20086 +/******************************************************************************
20087 + @File memac.c
20088 +
20089 + @Description FM mEMAC driver
20090 +*//***************************************************************************/
20091 +
20092 +#include "std_ext.h"
20093 +#include "string_ext.h"
20094 +#include "error_ext.h"
20095 +#include "xx_ext.h"
20096 +#include "endian_ext.h"
20097 +#include "debug_ext.h"
20098 +
20099 +#include "fm_common.h"
20100 +#include "memac.h"
20101 +
20102 +
20103 +/*****************************************************************************/
20104 +/* Internal routines */
20105 +/*****************************************************************************/
20106 +
20107 +/* ......................................................................... */
20108 +
20109 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
20110 +{
20111 + uint64_t mask1, mask2;
20112 + uint32_t xorVal = 0;
20113 + uint8_t i, j;
20114 +
20115 + for (i=0; i<6; i++)
20116 + {
20117 + mask1 = ethAddr & (uint64_t)0x01;
20118 + ethAddr >>= 1;
20119 +
20120 + for (j=0; j<7; j++)
20121 + {
20122 + mask2 = ethAddr & (uint64_t)0x01;
20123 + mask1 ^= mask2;
20124 + ethAddr >>= 1;
20125 + }
20126 +
20127 + xorVal |= (mask1 << (5-i));
20128 + }
20129 +
20130 + return xorVal;
20131 +}
20132 +
20133 +/* ......................................................................... */
20134 +
20135 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20136 +{
20137 + uint16_t tmpReg16;
20138 + e_EnetMode enetMode;
20139 +
20140 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20141 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20142 + to 1G one, so MII functions can work correctly. */
20143 + enetMode = p_Memac->enetMode;
20144 +
20145 + /* SGMII mode + AN enable */
20146 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20147 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20148 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20149 +
20150 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20151 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20152 +
20153 + /* Device ability according to SGMII specification */
20154 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20155 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20156 +
20157 + /* Adjust link timer for SGMII -
20158 + According to Cisco SGMII specification the timer should be 1.6 ms.
20159 + The link_timer register is configured in units of the clock.
20160 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20161 + unit = 1 / (125*10^6 Hz) = 8 ns.
20162 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20163 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20164 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20165 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20166 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20167 + we always set up here a value of 2.5 SGMII. */
20168 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20169 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20170 +
20171 + /* Restart AN */
20172 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20173 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20174 +
20175 + /* Restore original enet mode */
20176 + p_Memac->enetMode = enetMode;
20177 +}
20178 +
20179 +/* ......................................................................... */
20180 +
20181 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20182 +{
20183 + uint16_t tmpReg16;
20184 + e_EnetMode enetMode;
20185 +
20186 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20187 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20188 + to 1G one, so MII functions can work correctly. */
20189 + enetMode = p_Memac->enetMode;
20190 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20191 +
20192 + /* 1000BaseX mode */
20193 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20194 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20195 +
20196 + /* AN Device capability */
20197 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20198 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20199 +
20200 + /* Adjust link timer for SGMII -
20201 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20202 + The link_timer register is configured in units of the clock.
20203 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20204 + unit = 1 / (125*10^6 Hz) = 8 ns.
20205 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20206 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20207 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20208 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20209 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20210 + we always set up here a value of 2.5 SGMII. */
20211 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20212 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20213 +
20214 + /* Restart AN */
20215 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20216 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20217 +
20218 + /* Restore original enet mode */
20219 + p_Memac->enetMode = enetMode;
20220 +}
20221 +
20222 +/* ......................................................................... */
20223 +
20224 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20225 +{
20226 + e_FmMacType portType;
20227 +
20228 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20229 +
20230 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20231 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20232 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20233 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20234 +
20235 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20236 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20237 + if (p_Memac->addr == 0)
20238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20239 + if (!p_Memac->f_Exception)
20240 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20241 + if (!p_Memac->f_Event)
20242 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20243 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20244 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20245 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20246 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20247 +
20248 + return E_OK;
20249 +}
20250 +
20251 +/* ........................................................................... */
20252 +
20253 +static void MemacErrException(t_Handle h_Memac)
20254 +{
20255 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20256 + uint32_t event, imask;
20257 +
20258 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20259 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20260 +
20261 + /* Imask include both error and notification/event bits.
20262 + Leaving only error bits enabled by imask.
20263 + The imask error bits are shifted by 16 bits offset from
20264 + their corresponding location in the ievent - hence the >> 16 */
20265 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20266 +
20267 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20268 +
20269 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20270 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20271 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20272 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20273 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20274 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20275 +}
20276 +
20277 +static void MemacException(t_Handle h_Memac)
20278 +{
20279 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20280 + uint32_t event, imask;
20281 +
20282 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20283 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20284 +
20285 + /* Imask include both error and notification/event bits.
20286 + Leaving only error bits enabled by imask.
20287 + The imask error bits are shifted by 16 bits offset from
20288 + their corresponding location in the ievent - hence the >> 16 */
20289 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20290 +
20291 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20292 +
20293 + if (event & MEMAC_IEVNT_MGI)
20294 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20295 +}
20296 +
20297 +/* ......................................................................... */
20298 +
20299 +static void FreeInitResources(t_Memac *p_Memac)
20300 +{
20301 + e_FmMacType portType;
20302 +
20303 + portType =
20304 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20305 +
20306 + if (portType == e_FM_MAC_10G)
20307 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20308 + else
20309 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20310 +
20311 + /* release the driver's group hash table */
20312 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20313 + p_Memac->p_MulticastAddrHash = NULL;
20314 +
20315 + /* release the driver's individual hash table */
20316 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20317 + p_Memac->p_UnicastAddrHash = NULL;
20318 +}
20319 +
20320 +
20321 +/*****************************************************************************/
20322 +/* mEMAC API routines */
20323 +/*****************************************************************************/
20324 +
20325 +/* ......................................................................... */
20326 +
20327 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
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 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20335 +
20336 + return E_OK;
20337 +}
20338 +
20339 +/* ......................................................................... */
20340 +
20341 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
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 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20349 +
20350 + return E_OK;
20351 +}
20352 +
20353 +/* ......................................................................... */
20354 +
20355 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool 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 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20363 +
20364 + return E_OK;
20365 +}
20366 +
20367 +/* .............................................................................. */
20368 +
20369 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
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 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20377 + RETURN_ERROR(MAJOR, E_CONFLICT,
20378 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20379 +
20380 + fman_memac_adjust_link(p_Memac->p_MemMap,
20381 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20382 + (enum enet_speed)speed,
20383 + fullDuplex);
20384 + return E_OK;
20385 +}
20386 +
20387 +
20388 +/*****************************************************************************/
20389 +/* Memac Configs modification functions */
20390 +/*****************************************************************************/
20391 +
20392 +/* ......................................................................... */
20393 +
20394 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20395 +{
20396 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20397 +
20398 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20399 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20400 +
20401 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20402 +
20403 + return E_OK;
20404 +}
20405 +
20406 +/* ......................................................................... */
20407 +
20408 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20409 +{
20410 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20411 +
20412 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20413 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20414 +
20415 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20416 +
20417 + return E_OK;
20418 +}
20419 +
20420 +/* ......................................................................... */
20421 +
20422 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20423 +{
20424 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20425 +
20426 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20427 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20428 +
20429 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20430 +
20431 + return E_OK;
20432 +}
20433 +
20434 +/* ......................................................................... */
20435 +
20436 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20437 +{
20438 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20439 +
20440 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20441 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20442 +
20443 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20444 +
20445 + return E_OK;
20446 +}
20447 +
20448 +/* ......................................................................... */
20449 +
20450 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20451 +{
20452 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20453 +
20454 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20455 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20456 +
20457 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20458 +
20459 + return E_OK;
20460 +}
20461 +
20462 +/* ......................................................................... */
20463 +
20464 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20465 +{
20466 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20467 + uint32_t bitMask = 0;
20468 +
20469 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20470 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20471 +
20472 + GET_EXCEPTION_FLAG(bitMask, exception);
20473 + if (bitMask)
20474 + {
20475 + if (enable)
20476 + p_Memac->exceptions |= bitMask;
20477 + else
20478 + p_Memac->exceptions &= ~bitMask;
20479 + }
20480 + else
20481 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20482 +
20483 + return E_OK;
20484 +}
20485 +
20486 +/* ......................................................................... */
20487 +
20488 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20489 +{
20490 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20491 +
20492 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20493 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20494 +
20495 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20496 +
20497 + return E_OK;
20498 +}
20499 +
20500 +
20501 +/*****************************************************************************/
20502 +/* Memac Run Time API functions */
20503 +/*****************************************************************************/
20504 +
20505 +/* ......................................................................... */
20506 +
20507 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20508 + uint8_t priority,
20509 + uint16_t pauseTime,
20510 + uint16_t threshTime)
20511 +{
20512 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20513 +
20514 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20515 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20516 +
20517 + if (priority != 0xFF)
20518 + {
20519 + bool PortConfigured, PreFetchEnabled;
20520 +
20521 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20522 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20523 +
20524 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20525 + p_Memac->fmMacControllerDriver.macId,
20526 + &PortConfigured,
20527 + &PreFetchEnabled);
20528 +
20529 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20530 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20531 +
20532 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20533 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20534 + }
20535 +
20536 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20537 +
20538 + return E_OK;
20539 +}
20540 +
20541 +/* ......................................................................... */
20542 +
20543 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20544 + uint16_t pauseTime)
20545 +{
20546 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20547 +}
20548 +
20549 +/* ......................................................................... */
20550 +
20551 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20552 +{
20553 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20554 +
20555 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20556 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20557 +
20558 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20559 +
20560 + return E_OK;
20561 +}
20562 +
20563 +/* ......................................................................... */
20564 +
20565 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20566 +{
20567 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20568 +
20569 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20570 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20571 +
20572 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20573 +
20574 + return E_OK;
20575 +}
20576 +
20577 +/* .............................................................................. */
20578 +
20579 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20580 +{
20581 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20582 +
20583 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20584 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20585 +UNUSED(p_Memac);
20586 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20587 +
20588 + return E_OK;
20589 +}
20590 +
20591 +/* Counters handling */
20592 +/* ......................................................................... */
20593 +
20594 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20595 +{
20596 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20597 +
20598 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20599 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20600 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20601 +
20602 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20603 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20604 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20605 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20606 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20607 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20608 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20609 +/* */
20610 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20611 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20612 +
20613 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20614 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20615 +
20616 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20617 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20618 +/* Pause */
20619 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20620 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20621 +
20622 +/* MIB II */
20623 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20624 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20625 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20626 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20627 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20628 + + p_Statistics->ifInMcastPkts
20629 + + p_Statistics->ifInBcastPkts;
20630 + p_Statistics->ifInDiscards = 0;
20631 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20632 +
20633 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20634 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20635 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20636 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20637 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20638 + + p_Statistics->ifOutMcastPkts
20639 + + p_Statistics->ifOutBcastPkts;
20640 + p_Statistics->ifOutDiscards = 0;
20641 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20642 +
20643 + return E_OK;
20644 +}
20645 +
20646 +/* ......................................................................... */
20647 +
20648 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20649 +{
20650 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20651 +
20652 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20653 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20654 +
20655 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20656 +
20657 + return E_OK;
20658 +}
20659 +
20660 +/* ......................................................................... */
20661 +
20662 +static t_Error MemacResetCounters (t_Handle h_Memac)
20663 +{
20664 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20665 +
20666 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20667 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20668 +
20669 + fman_memac_reset_stat(p_Memac->p_MemMap);
20670 +
20671 + return E_OK;
20672 +}
20673 +
20674 +/* ......................................................................... */
20675 +
20676 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20677 +{
20678 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20679 + uint64_t ethAddr;
20680 + uint8_t paddrNum;
20681 +
20682 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20683 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20684 +
20685 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20686 +
20687 + if (ethAddr & GROUP_ADDRESS)
20688 + /* Multicast address has no effect in PADDR */
20689 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20690 +
20691 + /* Make sure no PADDR contains this address */
20692 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20693 + if (p_Memac->indAddrRegUsed[paddrNum])
20694 + if (p_Memac->paddr[paddrNum] == ethAddr)
20695 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20696 +
20697 + /* Find first unused PADDR */
20698 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20699 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20700 + {
20701 + /* mark this PADDR as used */
20702 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20703 + /* store address */
20704 + p_Memac->paddr[paddrNum] = ethAddr;
20705 +
20706 + /* put in hardware */
20707 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20708 + p_Memac->numOfIndAddrInRegs++;
20709 +
20710 + return E_OK;
20711 + }
20712 +
20713 + /* No free PADDR */
20714 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20715 +}
20716 +
20717 +/* ......................................................................... */
20718 +
20719 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20720 +{
20721 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20722 + uint64_t ethAddr;
20723 + uint8_t paddrNum;
20724 +
20725 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20726 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20727 +
20728 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20729 +
20730 + /* Find used PADDR containing this address */
20731 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20732 + {
20733 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20734 + (p_Memac->paddr[paddrNum] == ethAddr))
20735 + {
20736 + /* mark this PADDR as not used */
20737 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20738 + /* clear in hardware */
20739 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20740 + p_Memac->numOfIndAddrInRegs--;
20741 +
20742 + return E_OK;
20743 + }
20744 + }
20745 +
20746 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20747 +}
20748 +
20749 +/* ......................................................................... */
20750 +
20751 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20752 +{
20753 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20754 +
20755 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20756 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20757 +
20758 + *macId = p_Memac->macId;
20759 +
20760 + return E_OK;
20761 +}
20762 +
20763 +/* ......................................................................... */
20764 +
20765 +
20766 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20767 +{
20768 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20769 + t_EthHashEntry *p_HashEntry;
20770 + uint32_t hash;
20771 + uint64_t ethAddr;
20772 +
20773 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20774 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20775 +
20776 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20777 +
20778 + if (!(ethAddr & GROUP_ADDRESS))
20779 + /* Unicast addresses not supported in hash */
20780 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20781 +
20782 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20783 +
20784 + /* Create element to be added to the driver hash table */
20785 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20786 + p_HashEntry->addr = ethAddr;
20787 + INIT_LIST(&p_HashEntry->node);
20788 +
20789 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20790 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20791 +
20792 + return E_OK;
20793 +}
20794 +
20795 +/* ......................................................................... */
20796 +
20797 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20798 +{
20799 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20800 + t_EthHashEntry *p_HashEntry = NULL;
20801 + t_List *p_Pos;
20802 + uint32_t hash;
20803 + uint64_t ethAddr;
20804 +
20805 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20806 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20807 +
20808 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20809 +
20810 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20811 +
20812 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20813 + {
20814 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20815 + if (p_HashEntry->addr == ethAddr)
20816 + {
20817 + LIST_DelAndInit(&p_HashEntry->node);
20818 + XX_Free(p_HashEntry);
20819 + break;
20820 + }
20821 + }
20822 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20823 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
20824 +
20825 + return E_OK;
20826 +}
20827 +
20828 +
20829 +/* ......................................................................... */
20830 +
20831 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20832 +{
20833 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20834 + uint32_t bitMask = 0;
20835 +
20836 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20837 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20838 +
20839 + GET_EXCEPTION_FLAG(bitMask, exception);
20840 + if (bitMask)
20841 + {
20842 + if (enable)
20843 + p_Memac->exceptions |= bitMask;
20844 + else
20845 + p_Memac->exceptions &= ~bitMask;
20846 + }
20847 + else
20848 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20849 +
20850 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
20851 +
20852 + return E_OK;
20853 +}
20854 +
20855 +/* ......................................................................... */
20856 +
20857 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
20858 +{
20859 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20860 +
20861 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
20862 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
20863 +
20864 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
20865 +}
20866 +
20867 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
20868 +{
20869 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20870 + uint8_t i, phyAddr;
20871 +
20872 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
20873 + {
20874 + /* Configure internal SGMII PHY */
20875 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20876 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
20877 + else
20878 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
20879 + }
20880 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
20881 + {
20882 + /* Configure 4 internal SGMII PHYs */
20883 + for (i = 0; i < 4; i++)
20884 + {
20885 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
20886 + phyAddress; the lower 2 bits are used to extend
20887 + register address space and access each one of 4
20888 + ports inside QSGMII. */
20889 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
20890 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20891 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
20892 + else
20893 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
20894 + }
20895 + }
20896 + return E_OK;
20897 +}
20898 +
20899 +/*****************************************************************************/
20900 +/* mEMAC Init & Free API */
20901 +/*****************************************************************************/
20902 +
20903 +/* ......................................................................... */
20904 +void *g_MemacRegs;
20905 +static t_Error MemacInit(t_Handle h_Memac)
20906 +{
20907 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20908 + struct memac_cfg *p_MemacDriverParam;
20909 + enum enet_interface enet_interface;
20910 + enum enet_speed enet_speed;
20911 + t_EnetAddr ethAddr;
20912 + e_FmMacType portType;
20913 + t_Error err;
20914 + bool slow_10g_if = FALSE;
20915 + if (p_Memac->macId == 3) /* This is a quick WA */
20916 + g_MemacRegs = p_Memac->p_MemMap;
20917 +
20918 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20919 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20920 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
20921 +
20922 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20923 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
20924 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
20925 + slow_10g_if = TRUE;
20926 +
20927 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
20928 +
20929 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
20930 +
20931 + portType =
20932 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20933 +
20934 + /* First, reset the MAC if desired. */
20935 + if (p_MemacDriverParam->reset_on_init)
20936 + fman_memac_reset(p_Memac->p_MemMap);
20937 +
20938 + /* MAC Address */
20939 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
20940 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
20941 +
20942 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
20943 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
20944 +
20945 + fman_memac_init(p_Memac->p_MemMap,
20946 + p_Memac->p_MemacDriverParam,
20947 + enet_interface,
20948 + enet_speed,
20949 + slow_10g_if,
20950 + p_Memac->exceptions);
20951 +
20952 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
20953 + {
20954 + uint32_t tmpReg = 0;
20955 +
20956 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20957 + /* check the FMAN version - the bug exists only in rev1 */
20958 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
20959 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
20960 + {
20961 + /* MAC strips CRC from received frames - this workaround should
20962 + decrease the likelihood of bug appearance
20963 + */
20964 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
20965 + tmpReg &= ~CMD_CFG_CRC_FWD;
20966 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
20967 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
20968 + }
20969 + }
20970 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
20971 +
20972 + MemacInitInternalPhy(h_Memac);
20973 +
20974 + /* Max Frame Length */
20975 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
20976 + portType,
20977 + p_Memac->fmMacControllerDriver.macId,
20978 + p_MemacDriverParam->max_frame_length);
20979 + if (err)
20980 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
20981 +
20982 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20983 + if (!p_Memac->p_MulticastAddrHash)
20984 + {
20985 + FreeInitResources(p_Memac);
20986 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20987 + }
20988 +
20989 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20990 + if (!p_Memac->p_UnicastAddrHash)
20991 + {
20992 + FreeInitResources(p_Memac);
20993 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20994 + }
20995 +
20996 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20997 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20998 + p_Memac->macId,
20999 + e_FM_INTR_TYPE_ERR,
21000 + MemacErrException,
21001 + p_Memac);
21002 +
21003 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
21004 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
21005 + p_Memac->macId,
21006 + e_FM_INTR_TYPE_NORMAL,
21007 + MemacException,
21008 + p_Memac);
21009 +
21010 + XX_Free(p_MemacDriverParam);
21011 + p_Memac->p_MemacDriverParam = NULL;
21012 +
21013 + return E_OK;
21014 +}
21015 +
21016 +/* ......................................................................... */
21017 +
21018 +static t_Error MemacFree(t_Handle h_Memac)
21019 +{
21020 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21021 +
21022 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21023 +
21024 + if (p_Memac->p_MemacDriverParam)
21025 + {
21026 + /* Called after config */
21027 + XX_Free(p_Memac->p_MemacDriverParam);
21028 + p_Memac->p_MemacDriverParam = NULL;
21029 + }
21030 + else
21031 + /* Called after init */
21032 + FreeInitResources(p_Memac);
21033 +
21034 + XX_Free(p_Memac);
21035 +
21036 + return E_OK;
21037 +}
21038 +
21039 +/* ......................................................................... */
21040 +
21041 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
21042 +{
21043 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
21044 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
21045 +
21046 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
21047 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
21048 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
21049 +
21050 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
21051 +
21052 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
21053 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
21054 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
21055 +
21056 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
21057 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
21058 +
21059 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
21060 +
21061 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
21062 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
21063 +
21064 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
21065 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
21066 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
21067 +
21068 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
21069 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
21070 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
21071 +
21072 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
21073 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
21074 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
21075 +
21076 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
21077 +
21078 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
21079 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
21080 +
21081 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
21082 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
21083 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
21084 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
21085 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
21086 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
21087 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
21088 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
21089 +
21090 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
21091 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
21092 +}
21093 +
21094 +
21095 +/*****************************************************************************/
21096 +/* mEMAC Config Main Entry */
21097 +/*****************************************************************************/
21098 +
21099 +/* ......................................................................... */
21100 +
21101 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
21102 +{
21103 + t_Memac *p_Memac;
21104 + struct memac_cfg *p_MemacDriverParam;
21105 + uintptr_t baseAddr;
21106 +
21107 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
21108 +
21109 + baseAddr = p_FmMacParam->baseAddr;
21110 + /* Allocate memory for the mEMAC data structure */
21111 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
21112 + if (!p_Memac)
21113 + {
21114 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
21115 + return NULL;
21116 + }
21117 + memset(p_Memac, 0, sizeof(t_Memac));
21118 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
21119 +
21120 + /* Allocate memory for the mEMAC driver parameters data structure */
21121 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
21122 + if (!p_MemacDriverParam)
21123 + {
21124 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
21125 + XX_Free(p_Memac);
21126 + return NULL;
21127 + }
21128 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
21129 +
21130 + /* Plant parameter structure pointer */
21131 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21132 +
21133 + fman_memac_defconfig(p_MemacDriverParam);
21134 +
21135 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21136 +
21137 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21138 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21139 +
21140 + p_Memac->enetMode = p_FmMacParam->enetMode;
21141 + p_Memac->macId = p_FmMacParam->macId;
21142 + p_Memac->exceptions = MEMAC_default_exceptions;
21143 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21144 + p_Memac->f_Event = p_FmMacParam->f_Event;
21145 + p_Memac->h_App = p_FmMacParam->h_App;
21146 +
21147 + return p_Memac;
21148 +}
21149 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21150 new file mode 100644
21151 index 00000000..2fd89dae
21152 --- /dev/null
21153 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21154 @@ -0,0 +1,110 @@
21155 +/*
21156 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21157 + *
21158 + * Redistribution and use in source and binary forms, with or without
21159 + * modification, are permitted provided that the following conditions are met:
21160 + * * Redistributions of source code must retain the above copyright
21161 + * notice, this list of conditions and the following disclaimer.
21162 + * * Redistributions in binary form must reproduce the above copyright
21163 + * notice, this list of conditions and the following disclaimer in the
21164 + * documentation and/or other materials provided with the distribution.
21165 + * * Neither the name of Freescale Semiconductor nor the
21166 + * names of its contributors may be used to endorse or promote products
21167 + * derived from this software without specific prior written permission.
21168 + *
21169 + *
21170 + * ALTERNATIVELY, this software may be distributed under the terms of the
21171 + * GNU General Public License ("GPL") as published by the Free Software
21172 + * Foundation, either version 2 of that License or (at your option) any
21173 + * later version.
21174 + *
21175 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21176 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21177 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21178 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21179 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21180 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21181 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21182 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21183 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21184 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21185 + */
21186 +
21187 +
21188 +/******************************************************************************
21189 + @File memac.h
21190 +
21191 + @Description FM Multirate Ethernet MAC (mEMAC)
21192 +*//***************************************************************************/
21193 +#ifndef __MEMAC_H
21194 +#define __MEMAC_H
21195 +
21196 +#include "std_ext.h"
21197 +#include "error_ext.h"
21198 +#include "list_ext.h"
21199 +
21200 +#include "fsl_fman_memac_mii_acc.h"
21201 +#include "fm_mac.h"
21202 +#include "fsl_fman_memac.h"
21203 +
21204 +
21205 +#define MEMAC_default_exceptions \
21206 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21207 +
21208 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21209 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21210 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21211 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21212 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21213 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21214 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21215 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21216 + bitMask = MEMAC_IMASK_MGI; break; \
21217 + default: bitMask = 0;break;}
21218 +
21219 +
21220 +typedef struct
21221 +{
21222 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21223 + t_Handle h_App; /**< Handle to the upper layer application */
21224 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21225 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21226 + uint64_t addr; /**< MAC address of device */
21227 + e_EnetMode enetMode; /**< Ethernet physical interface */
21228 + t_FmMacExceptionCallback *f_Exception;
21229 + int mdioIrq;
21230 + t_FmMacExceptionCallback *f_Event;
21231 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21232 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21233 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21234 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21235 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21236 + bool debugMode;
21237 + uint8_t macId;
21238 + uint32_t exceptions;
21239 + struct memac_cfg *p_MemacDriverParam;
21240 +} t_Memac;
21241 +
21242 +
21243 +/* Internal PHY access */
21244 +#define PHY_MDIO_ADDR 0
21245 +
21246 +/* Internal PHY Registers - SGMII */
21247 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21248 +#define PHY_SGMII_CR_RESET_AN 0x0200
21249 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21250 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21251 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21252 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21253 +#define PHY_SGMII_IF_MODE_AN 0x0002
21254 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21255 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21256 +
21257 +
21258 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21259 +
21260 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21261 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21262 +
21263 +
21264 +#endif /* __MEMAC_H */
21265 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21266 new file mode 100644
21267 index 00000000..56eaffbc
21268 --- /dev/null
21269 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21270 @@ -0,0 +1,78 @@
21271 +/*
21272 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21273 + *
21274 + * Redistribution and use in source and binary forms, with or without
21275 + * modification, are permitted provided that the following conditions are met:
21276 + * * Redistributions of source code must retain the above copyright
21277 + * notice, this list of conditions and the following disclaimer.
21278 + * * Redistributions in binary form must reproduce the above copyright
21279 + * notice, this list of conditions and the following disclaimer in the
21280 + * documentation and/or other materials provided with the distribution.
21281 + * * Neither the name of Freescale Semiconductor nor the
21282 + * names of its contributors may be used to endorse or promote products
21283 + * derived from this software without specific prior written permission.
21284 + *
21285 + *
21286 + * ALTERNATIVELY, this software may be distributed under the terms of the
21287 + * GNU General Public License ("GPL") as published by the Free Software
21288 + * Foundation, either version 2 of that License or (at your option) any
21289 + * later version.
21290 + *
21291 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21292 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21293 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21294 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21295 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21296 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21297 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21298 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21299 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21300 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21301 + */
21302 +
21303 +
21304 +#include "error_ext.h"
21305 +#include "std_ext.h"
21306 +#include "fm_mac.h"
21307 +#include "memac.h"
21308 +#include "xx_ext.h"
21309 +
21310 +#include "fm_common.h"
21311 +#include "memac_mii_acc.h"
21312 +
21313 +
21314 +/*****************************************************************************/
21315 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21316 + uint8_t phyAddr,
21317 + uint8_t reg,
21318 + uint16_t data)
21319 +{
21320 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21321 +
21322 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21323 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21324 +
21325 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21326 + phyAddr,
21327 + reg,
21328 + data,
21329 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21330 +}
21331 +
21332 +/*****************************************************************************/
21333 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21334 + uint8_t phyAddr,
21335 + uint8_t reg,
21336 + uint16_t *p_Data)
21337 +{
21338 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21339 +
21340 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21341 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21342 +
21343 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21344 + phyAddr,
21345 + reg,
21346 + p_Data,
21347 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21348 +}
21349 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21350 new file mode 100644
21351 index 00000000..325ec082
21352 --- /dev/null
21353 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21354 @@ -0,0 +1,73 @@
21355 +/*
21356 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21357 + *
21358 + * Redistribution and use in source and binary forms, with or without
21359 + * modification, are permitted provided that the following conditions are met:
21360 + * * Redistributions of source code must retain the above copyright
21361 + * notice, this list of conditions and the following disclaimer.
21362 + * * Redistributions in binary form must reproduce the above copyright
21363 + * notice, this list of conditions and the following disclaimer in the
21364 + * documentation and/or other materials provided with the distribution.
21365 + * * Neither the name of Freescale Semiconductor nor the
21366 + * names of its contributors may be used to endorse or promote products
21367 + * derived from this software without specific prior written permission.
21368 + *
21369 + *
21370 + * ALTERNATIVELY, this software may be distributed under the terms of the
21371 + * GNU General Public License ("GPL") as published by the Free Software
21372 + * Foundation, either version 2 of that License or (at your option) any
21373 + * later version.
21374 + *
21375 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21376 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21377 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21378 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21379 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21380 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21381 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21382 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21383 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21384 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21385 + */
21386 +
21387 +
21388 +#ifndef __MEMAC_MII_ACC_H
21389 +#define __MEMAC_MII_ACC_H
21390 +
21391 +#include "std_ext.h"
21392 +
21393 +
21394 +/* MII Management Registers */
21395 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21396 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21397 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21398 +#define MDIO_CFG_ENC45 0x00000040
21399 +#define MDIO_CFG_READ_ERR 0x00000002
21400 +#define MDIO_CFG_BSY 0x00000001
21401 +
21402 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21403 +#define MDIO_CTL_READ 0x00008000
21404 +
21405 +#define MDIO_DATA_BSY 0x80000000
21406 +
21407 +#if defined(__MWERKS__) && !defined(__GNUC__)
21408 +#pragma pack(push,1)
21409 +#endif /* defined(__MWERKS__) && ... */
21410 +
21411 +/*----------------------------------------------------*/
21412 +/* MII Configuration Control Memory Map Registers */
21413 +/*----------------------------------------------------*/
21414 +typedef struct t_MemacMiiAccessMemMap
21415 +{
21416 + volatile uint32_t mdio_cfg; /* 0x030 */
21417 + volatile uint32_t mdio_ctrl; /* 0x034 */
21418 + volatile uint32_t mdio_data; /* 0x038 */
21419 + volatile uint32_t mdio_addr; /* 0x03c */
21420 +} t_MemacMiiAccessMemMap ;
21421 +
21422 +#if defined(__MWERKS__) && !defined(__GNUC__)
21423 +#pragma pack(pop)
21424 +#endif /* defined(__MWERKS__) && ... */
21425 +
21426 +
21427 +#endif /* __MEMAC_MII_ACC_H */
21428 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21429 new file mode 100644
21430 index 00000000..9b136a69
21431 --- /dev/null
21432 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21433 @@ -0,0 +1,975 @@
21434 +/*
21435 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21436 + *
21437 + * Redistribution and use in source and binary forms, with or without
21438 + * modification, are permitted provided that the following conditions are met:
21439 + * * Redistributions of source code must retain the above copyright
21440 + * notice, this list of conditions and the following disclaimer.
21441 + * * Redistributions in binary form must reproduce the above copyright
21442 + * notice, this list of conditions and the following disclaimer in the
21443 + * documentation and/or other materials provided with the distribution.
21444 + * * Neither the name of Freescale Semiconductor nor the
21445 + * names of its contributors may be used to endorse or promote products
21446 + * derived from this software without specific prior written permission.
21447 + *
21448 + *
21449 + * ALTERNATIVELY, this software may be distributed under the terms of the
21450 + * GNU General Public License ("GPL") as published by the Free Software
21451 + * Foundation, either version 2 of that License or (at your option) any
21452 + * later version.
21453 + *
21454 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21455 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21456 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21457 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21458 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21459 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21460 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21461 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21462 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21463 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21464 + */
21465 +
21466 +
21467 +/******************************************************************************
21468 + @File tgec.c
21469 +
21470 + @Description FM 10G MAC ...
21471 +*//***************************************************************************/
21472 +
21473 +#include "std_ext.h"
21474 +#include "string_ext.h"
21475 +#include "error_ext.h"
21476 +#include "xx_ext.h"
21477 +#include "endian_ext.h"
21478 +#include "debug_ext.h"
21479 +#include "crc_mac_addr_ext.h"
21480 +
21481 +#include "fm_common.h"
21482 +#include "fsl_fman_tgec.h"
21483 +#include "tgec.h"
21484 +
21485 +
21486 +/*****************************************************************************/
21487 +/* Internal routines */
21488 +/*****************************************************************************/
21489 +
21490 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21491 +{
21492 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21493 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21494 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21495 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21496 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21497 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21498 +
21499 + if (p_Tgec->addr == 0)
21500 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21501 + if (!p_Tgec->f_Exception)
21502 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21503 + if (!p_Tgec->f_Event)
21504 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21505 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21506 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21507 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21508 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21509 + return E_OK;
21510 +}
21511 +
21512 +/* ......................................................................... */
21513 +
21514 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21515 +{
21516 + uint32_t crc;
21517 +
21518 + /* CRC calculation */
21519 + GET_MAC_ADDR_CRC(ethAddr, crc);
21520 +
21521 + crc = GetMirror32(crc);
21522 +
21523 + return crc;
21524 +}
21525 +
21526 +/* ......................................................................... */
21527 +
21528 +static void TgecErrException(t_Handle h_Tgec)
21529 +{
21530 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21531 + uint32_t event;
21532 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21533 +
21534 + /* do not handle MDIO events */
21535 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21536 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21537 +
21538 + fman_tgec_ack_event(p_TgecMemMap, event);
21539 +
21540 + if (event & TGEC_IMASK_REM_FAULT)
21541 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21542 + if (event & TGEC_IMASK_LOC_FAULT)
21543 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21544 + if (event & TGEC_IMASK_TX_ECC_ER)
21545 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21546 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21547 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21548 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21549 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21550 + if (event & TGEC_IMASK_TX_ER)
21551 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21552 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21553 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21554 + if (event & TGEC_IMASK_RX_ECC_ER)
21555 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21556 + if (event & TGEC_IMASK_RX_JAB_FRM)
21557 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21558 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21559 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21560 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21561 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21562 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21563 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21564 + if (event & TGEC_IMASK_RX_LEN_ER)
21565 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21566 + if (event & TGEC_IMASK_RX_CRC_ER)
21567 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21568 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21569 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21570 +}
21571 +
21572 +/* ......................................................................... */
21573 +
21574 +static void TgecException(t_Handle h_Tgec)
21575 +{
21576 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21577 + uint32_t event;
21578 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21579 +
21580 + /* handle only MDIO events */
21581 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21582 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21583 +
21584 + fman_tgec_ack_event(p_TgecMemMap, event);
21585 +
21586 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21587 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21588 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21589 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21590 +}
21591 +
21592 +/* ......................................................................... */
21593 +
21594 +static void FreeInitResources(t_Tgec *p_Tgec)
21595 +{
21596 + if (p_Tgec->mdioIrq != NO_IRQ)
21597 + {
21598 + XX_DisableIntr(p_Tgec->mdioIrq);
21599 + XX_FreeIntr(p_Tgec->mdioIrq);
21600 + }
21601 +
21602 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21603 +
21604 + /* release the driver's group hash table */
21605 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21606 + p_Tgec->p_MulticastAddrHash = NULL;
21607 +
21608 + /* release the driver's individual hash table */
21609 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21610 + p_Tgec->p_UnicastAddrHash = NULL;
21611 +}
21612 +
21613 +
21614 +/*****************************************************************************/
21615 +/* 10G MAC API routines */
21616 +/*****************************************************************************/
21617 +
21618 +/* ......................................................................... */
21619 +
21620 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21621 +{
21622 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21623 +
21624 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21625 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21626 +
21627 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21628 +
21629 + return E_OK;
21630 +}
21631 +
21632 +/* ......................................................................... */
21633 +
21634 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21635 +{
21636 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21637 +
21638 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21639 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21640 +
21641 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21642 +
21643 + return E_OK;
21644 +}
21645 +
21646 +/* ......................................................................... */
21647 +
21648 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21649 +{
21650 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21651 +
21652 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21653 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21654 +
21655 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21656 +
21657 + return E_OK;
21658 +}
21659 +
21660 +
21661 +/*****************************************************************************/
21662 +/* Tgec Configs modification functions */
21663 +/*****************************************************************************/
21664 +
21665 +/* ......................................................................... */
21666 +
21667 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21668 +{
21669 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21670 +
21671 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21672 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21673 +
21674 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21675 +
21676 + return E_OK;
21677 +}
21678 +
21679 +/* ......................................................................... */
21680 +
21681 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21682 +{
21683 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21684 +
21685 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21686 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21687 +
21688 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21689 +
21690 + return E_OK;
21691 +}
21692 +
21693 +/* ......................................................................... */
21694 +
21695 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21696 +{
21697 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21698 +
21699 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21700 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21701 +
21702 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21703 +
21704 + return E_OK;
21705 +}
21706 +
21707 +/* ......................................................................... */
21708 +
21709 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21710 +{
21711 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21712 +
21713 + UNUSED(newVal);
21714 +
21715 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21716 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21717 +
21718 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
21719 +
21720 + return E_OK;
21721 +}
21722 +
21723 +/* ......................................................................... */
21724 +
21725 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21726 +{
21727 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21728 + uint32_t bitMask = 0;
21729 +
21730 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21731 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21732 +
21733 + GET_EXCEPTION_FLAG(bitMask, exception);
21734 + if (bitMask)
21735 + {
21736 + if (enable)
21737 + p_Tgec->exceptions |= bitMask;
21738 + else
21739 + p_Tgec->exceptions &= ~bitMask;
21740 + }
21741 + else
21742 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21743 +
21744 + return E_OK;
21745 +}
21746 +
21747 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21748 +/* ......................................................................... */
21749 +
21750 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21751 +{
21752 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21753 +
21754 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21755 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21756 +
21757 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21758 +
21759 + return E_OK;
21760 +}
21761 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21762 +
21763 +
21764 +/*****************************************************************************/
21765 +/* Tgec Run Time API functions */
21766 +/*****************************************************************************/
21767 +
21768 +/* ......................................................................... */
21769 +/* backward compatibility. will be removed in the future. */
21770 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21771 +{
21772 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21773 +
21774 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21775 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21776 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21777 +
21778 +
21779 + return E_OK;
21780 +}
21781 +
21782 +/* ......................................................................... */
21783 +
21784 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21785 + uint8_t priority,
21786 + uint16_t pauseTime,
21787 + uint16_t threshTime)
21788 +{
21789 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21790 +
21791 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21792 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21793 +
21794 + UNUSED(priority); UNUSED(threshTime);
21795 +
21796 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21797 +
21798 + return E_OK;
21799 +}
21800 +
21801 +/* ......................................................................... */
21802 +
21803 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21804 +{
21805 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21806 +
21807 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21808 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21809 +
21810 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21811 +
21812 + return E_OK;
21813 +}
21814 +
21815 +/* ......................................................................... */
21816 +
21817 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21818 +{
21819 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21820 + struct tgec_regs *p_TgecMemMap;
21821 +
21822 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21823 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21824 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21825 +
21826 + p_TgecMemMap = p_Tgec->p_MemMap;
21827 +
21828 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21829 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21830 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21831 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21832 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21833 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21834 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21835 +/* */
21836 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
21837 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
21838 +
21839 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
21840 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
21841 +
21842 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
21843 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
21844 +/* Pause */
21845 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
21846 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
21847 +
21848 +/* MIB II */
21849 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
21850 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
21851 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
21852 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
21853 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
21854 + + p_Statistics->ifInMcastPkts
21855 + + p_Statistics->ifInBcastPkts;
21856 + p_Statistics->ifInDiscards = 0;
21857 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
21858 +
21859 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
21860 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
21861 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
21862 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
21863 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
21864 + + p_Statistics->ifOutMcastPkts
21865 + + p_Statistics->ifOutBcastPkts;
21866 + p_Statistics->ifOutDiscards = 0;
21867 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
21868 +
21869 + return E_OK;
21870 +}
21871 +
21872 +/* ......................................................................... */
21873 +
21874 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
21875 +{
21876 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21877 +
21878 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21879 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21880 +
21881 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
21882 +
21883 + return E_OK;
21884 +}
21885 +
21886 +/* ......................................................................... */
21887 +
21888 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
21889 +{
21890 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21891 +
21892 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21893 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21894 +
21895 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
21896 +
21897 + return E_OK;
21898 +}
21899 +
21900 +/* ......................................................................... */
21901 +
21902 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
21903 +{
21904 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21905 +
21906 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21907 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21908 +
21909 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
21910 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
21911 +
21912 + return E_OK;
21913 +}
21914 +
21915 +/* ......................................................................... */
21916 +
21917 +static t_Error TgecResetCounters (t_Handle h_Tgec)
21918 +{
21919 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21920 +
21921 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21922 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21923 +
21924 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
21925 +
21926 + return E_OK;
21927 +}
21928 +
21929 +/* ......................................................................... */
21930 +
21931 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21932 +{
21933 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21934 + uint64_t ethAddr;
21935 + uint8_t paddrNum;
21936 +
21937 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21938 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21939 +
21940 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21941 +
21942 + if (ethAddr & GROUP_ADDRESS)
21943 + /* Multicast address has no effect in PADDR */
21944 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
21945 +
21946 + /* Make sure no PADDR contains this address */
21947 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21948 + if (p_Tgec->indAddrRegUsed[paddrNum])
21949 + if (p_Tgec->paddr[paddrNum] == ethAddr)
21950 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
21951 +
21952 + /* Find first unused PADDR */
21953 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21954 + {
21955 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
21956 + {
21957 + /* mark this PADDR as used */
21958 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
21959 + /* store address */
21960 + p_Tgec->paddr[paddrNum] = ethAddr;
21961 +
21962 + /* put in hardware */
21963 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
21964 + p_Tgec->numOfIndAddrInRegs++;
21965 +
21966 + return E_OK;
21967 + }
21968 + }
21969 +
21970 + /* No free PADDR */
21971 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
21972 +}
21973 +
21974 +/* ......................................................................... */
21975 +
21976 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21977 +{
21978 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21979 + uint64_t ethAddr;
21980 + uint8_t paddrNum;
21981 +
21982 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21983 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21984 +
21985 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21986 +
21987 + /* Find used PADDR containing this address */
21988 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21989 + {
21990 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
21991 + (p_Tgec->paddr[paddrNum] == ethAddr))
21992 + {
21993 + /* mark this PADDR as not used */
21994 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
21995 + /* clear in hardware */
21996 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
21997 + p_Tgec->numOfIndAddrInRegs--;
21998 +
21999 + return E_OK;
22000 + }
22001 + }
22002 +
22003 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22004 +}
22005 +
22006 +/* ......................................................................... */
22007 +
22008 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22009 +{
22010 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22011 + t_EthHashEntry *p_HashEntry;
22012 + uint32_t crc;
22013 + uint32_t hash;
22014 + uint64_t ethAddr;
22015 +
22016 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22017 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22018 +
22019 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22020 +
22021 + if (!(ethAddr & GROUP_ADDRESS))
22022 + /* Unicast addresses not supported in hash */
22023 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22024 +
22025 + /* CRC calculation */
22026 + crc = GetMacAddrHashCode(ethAddr);
22027 +
22028 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22029 +
22030 + /* Create element to be added to the driver hash table */
22031 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22032 + p_HashEntry->addr = ethAddr;
22033 + INIT_LIST(&p_HashEntry->node);
22034 +
22035 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
22036 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
22037 +
22038 + return E_OK;
22039 +}
22040 +
22041 +/* ......................................................................... */
22042 +
22043 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22044 +{
22045 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22046 + t_EthHashEntry *p_HashEntry = NULL;
22047 + t_List *p_Pos;
22048 + uint32_t crc;
22049 + uint32_t hash;
22050 + uint64_t ethAddr;
22051 +
22052 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22053 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22054 +
22055 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
22056 +
22057 + /* CRC calculation */
22058 + crc = GetMacAddrHashCode(ethAddr);
22059 +
22060 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22061 +
22062 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22063 + {
22064 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22065 + if (p_HashEntry->addr == ethAddr)
22066 + {
22067 + LIST_DelAndInit(&p_HashEntry->node);
22068 + XX_Free(p_HashEntry);
22069 + break;
22070 + }
22071 + }
22072 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22073 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
22074 +
22075 + return E_OK;
22076 +}
22077 +
22078 +/* ......................................................................... */
22079 +
22080 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
22081 +{
22082 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22083 +
22084 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22085 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22086 +
22087 + UNUSED(p_Tgec);
22088 + UNUSED(macId);
22089 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
22090 +}
22091 +
22092 +/* ......................................................................... */
22093 +
22094 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
22095 +{
22096 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22097 +
22098 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22099 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22100 +
22101 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
22102 +
22103 + return E_OK;
22104 +}
22105 +
22106 +/* ......................................................................... */
22107 +
22108 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
22109 +{
22110 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22111 + uint32_t bitMask = 0;
22112 +
22113 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22114 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22115 +
22116 + GET_EXCEPTION_FLAG(bitMask, exception);
22117 + if (bitMask)
22118 + {
22119 + if (enable)
22120 + p_Tgec->exceptions |= bitMask;
22121 + else
22122 + p_Tgec->exceptions &= ~bitMask;
22123 + }
22124 + else
22125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22126 +
22127 + if (enable)
22128 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
22129 + else
22130 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
22131 +
22132 + return E_OK;
22133 +}
22134 +
22135 +/* ......................................................................... */
22136 +
22137 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
22138 +{
22139 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22140 +
22141 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
22142 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
22143 +
22144 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22145 +}
22146 +
22147 +/* ......................................................................... */
22148 +
22149 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22150 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22151 +{
22152 + t_Error err;
22153 +
22154 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22155 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22156 +#endif /* (DEBUG_ERRORS > 0) */
22157 + /* enable and set promiscuous */
22158 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22159 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22160 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22161 + /* disable */
22162 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22163 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22164 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22165 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22166 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22167 + if (err)
22168 + XX_Print("FAILED!\n");
22169 + else
22170 + XX_Print("done.\n");
22171 +#endif /* (DEBUG_ERRORS > 0) */
22172 +
22173 + return err;
22174 +}
22175 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22176 +
22177 +/*****************************************************************************/
22178 +/* FM Init & Free API */
22179 +/*****************************************************************************/
22180 +
22181 +/* ......................................................................... */
22182 +
22183 +static t_Error TgecInit(t_Handle h_Tgec)
22184 +{
22185 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22186 + struct tgec_cfg *p_TgecDriverParam;
22187 + t_EnetAddr ethAddr;
22188 + t_Error err;
22189 +
22190 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22191 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22192 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22193 +
22194 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22195 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22196 +
22197 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22198 +
22199 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22200 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22201 +
22202 + /* interrupts */
22203 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22204 + {
22205 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22206 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22207 + }
22208 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22209 +
22210 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22211 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22212 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22213 + {
22214 + FreeInitResources(p_Tgec);
22215 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22216 + }
22217 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22218 +
22219 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22220 + if (err)
22221 + {
22222 + FreeInitResources(p_Tgec);
22223 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22224 + }
22225 +
22226 + /* Max Frame Length */
22227 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22228 + e_FM_MAC_10G,
22229 + p_Tgec->fmMacControllerDriver.macId,
22230 + p_TgecDriverParam->max_frame_length);
22231 + if (err != E_OK)
22232 + {
22233 + FreeInitResources(p_Tgec);
22234 + RETURN_ERROR(MINOR, err, NO_MSG);
22235 + }
22236 +/* we consider having no IPC a non crasher... */
22237 +
22238 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22239 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22240 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22241 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22242 +
22243 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22244 + if (!p_Tgec->p_MulticastAddrHash)
22245 + {
22246 + FreeInitResources(p_Tgec);
22247 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22248 + }
22249 +
22250 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22251 + if (!p_Tgec->p_UnicastAddrHash)
22252 + {
22253 + FreeInitResources(p_Tgec);
22254 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22255 + }
22256 +
22257 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22258 + e_FM_MOD_10G_MAC,
22259 + p_Tgec->macId,
22260 + e_FM_INTR_TYPE_ERR,
22261 + TgecErrException,
22262 + p_Tgec);
22263 + if (p_Tgec->mdioIrq != NO_IRQ)
22264 + {
22265 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22266 + XX_EnableIntr(p_Tgec->mdioIrq);
22267 + }
22268 +
22269 + XX_Free(p_TgecDriverParam);
22270 + p_Tgec->p_TgecDriverParam = NULL;
22271 +
22272 + return E_OK;
22273 +}
22274 +
22275 +/* ......................................................................... */
22276 +
22277 +static t_Error TgecFree(t_Handle h_Tgec)
22278 +{
22279 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22280 +
22281 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22282 +
22283 + if (p_Tgec->p_TgecDriverParam)
22284 + {
22285 + /* Called after config */
22286 + XX_Free(p_Tgec->p_TgecDriverParam);
22287 + p_Tgec->p_TgecDriverParam = NULL;
22288 + }
22289 + else
22290 + /* Called after init */
22291 + FreeInitResources(p_Tgec);
22292 +
22293 + XX_Free(p_Tgec);
22294 +
22295 + return E_OK;
22296 +}
22297 +
22298 +/* ......................................................................... */
22299 +
22300 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22301 +{
22302 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22303 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22304 +
22305 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22306 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22307 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22308 +
22309 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22310 +
22311 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22312 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22313 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22314 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22315 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22316 +
22317 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22318 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22319 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22320 +
22321 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22322 +
22323 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22324 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22325 +
22326 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22327 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22328 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22329 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22330 +
22331 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22332 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22333 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22334 +
22335 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22336 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22337 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22338 +
22339 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22340 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22341 +
22342 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22343 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22344 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22345 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22346 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22347 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22348 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22349 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22350 +
22351 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22352 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22353 +}
22354 +
22355 +
22356 +/*****************************************************************************/
22357 +/* Tgec Config Main Entry */
22358 +/*****************************************************************************/
22359 +
22360 +/* ......................................................................... */
22361 +
22362 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22363 +{
22364 + t_Tgec *p_Tgec;
22365 + struct tgec_cfg *p_TgecDriverParam;
22366 + uintptr_t baseAddr;
22367 +
22368 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22369 +
22370 + baseAddr = p_FmMacParam->baseAddr;
22371 + /* allocate memory for the UCC GETH data structure. */
22372 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22373 + if (!p_Tgec)
22374 + {
22375 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22376 + return NULL;
22377 + }
22378 + memset(p_Tgec, 0, sizeof(t_Tgec));
22379 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22380 +
22381 + /* allocate memory for the 10G MAC driver parameters data structure. */
22382 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22383 + if (!p_TgecDriverParam)
22384 + {
22385 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22386 + XX_Free(p_Tgec);
22387 + return NULL;
22388 + }
22389 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22390 +
22391 + /* Plant parameter structure pointer */
22392 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22393 +
22394 + fman_tgec_defconfig(p_TgecDriverParam);
22395 +
22396 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22397 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22398 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22399 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22400 + p_Tgec->macId = p_FmMacParam->macId;
22401 + p_Tgec->exceptions = DEFAULT_exceptions;
22402 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22403 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22404 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22405 + p_Tgec->h_App = p_FmMacParam->h_App;
22406 +
22407 + return p_Tgec;
22408 +}
22409 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22410 new file mode 100644
22411 index 00000000..2aa39238
22412 --- /dev/null
22413 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22414 @@ -0,0 +1,151 @@
22415 +/*
22416 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22417 + *
22418 + * Redistribution and use in source and binary forms, with or without
22419 + * modification, are permitted provided that the following conditions are met:
22420 + * * Redistributions of source code must retain the above copyright
22421 + * notice, this list of conditions and the following disclaimer.
22422 + * * Redistributions in binary form must reproduce the above copyright
22423 + * notice, this list of conditions and the following disclaimer in the
22424 + * documentation and/or other materials provided with the distribution.
22425 + * * Neither the name of Freescale Semiconductor nor the
22426 + * names of its contributors may be used to endorse or promote products
22427 + * derived from this software without specific prior written permission.
22428 + *
22429 + *
22430 + * ALTERNATIVELY, this software may be distributed under the terms of the
22431 + * GNU General Public License ("GPL") as published by the Free Software
22432 + * Foundation, either version 2 of that License or (at your option) any
22433 + * later version.
22434 + *
22435 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22436 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22437 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22438 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22439 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22440 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22441 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22442 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22443 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22444 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22445 + */
22446 +
22447 +
22448 +/******************************************************************************
22449 + @File tgec.h
22450 +
22451 + @Description FM 10G MAC ...
22452 +*//***************************************************************************/
22453 +#ifndef __TGEC_H
22454 +#define __TGEC_H
22455 +
22456 +#include "std_ext.h"
22457 +#include "error_ext.h"
22458 +#include "list_ext.h"
22459 +#include "enet_ext.h"
22460 +
22461 +#include "tgec_mii_acc.h"
22462 +#include "fm_mac.h"
22463 +
22464 +
22465 +#define DEFAULT_exceptions \
22466 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22467 + TGEC_IMASK_REM_FAULT | \
22468 + TGEC_IMASK_LOC_FAULT | \
22469 + TGEC_IMASK_TX_ECC_ER | \
22470 + TGEC_IMASK_TX_FIFO_UNFL | \
22471 + TGEC_IMASK_TX_FIFO_OVFL | \
22472 + TGEC_IMASK_TX_ER | \
22473 + TGEC_IMASK_RX_FIFO_OVFL | \
22474 + TGEC_IMASK_RX_ECC_ER | \
22475 + TGEC_IMASK_RX_JAB_FRM | \
22476 + TGEC_IMASK_RX_OVRSZ_FRM | \
22477 + TGEC_IMASK_RX_RUNT_FRM | \
22478 + TGEC_IMASK_RX_FRAG_FRM | \
22479 + TGEC_IMASK_RX_CRC_ER | \
22480 + TGEC_IMASK_RX_ALIGN_ER))
22481 +
22482 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22483 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22484 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22485 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22486 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22487 + case e_FM_MAC_EX_10G_REM_FAULT: \
22488 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22489 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22490 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22491 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22492 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22493 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22494 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22495 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22496 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22497 + case e_FM_MAC_EX_10G_TX_ER: \
22498 + bitMask = TGEC_IMASK_TX_ER ; break; \
22499 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22500 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22501 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22502 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22503 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22504 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22505 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22506 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22507 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22508 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22509 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22510 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22511 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22512 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22513 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22514 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22515 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22516 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22517 + default: bitMask = 0;break;}
22518 +
22519 +#define MAX_PACKET_ALIGNMENT 31
22520 +#define MAX_INTER_PACKET_GAP 0x7f
22521 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22522 +#define MAX_RETRANSMISSION 0x0f
22523 +#define MAX_COLLISION_WINDOW 0x03ff
22524 +
22525 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22526 +
22527 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22528 +
22529 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22530 +
22531 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22532 +
22533 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22534 +#define TGEC_ID_ID 0xffff0000
22535 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22536 +#define TGEC_ID_MAC_REV 0x000000ff
22537 +
22538 +
22539 +typedef struct {
22540 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22541 + t_Handle h_App; /**< Handle to the upper layer application */
22542 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22543 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22544 + uint64_t addr; /**< MAC address of device; */
22545 + e_EnetMode enetMode; /**< Ethernet physical interface */
22546 + t_FmMacExceptionCallback *f_Exception;
22547 + int mdioIrq;
22548 + t_FmMacExceptionCallback *f_Event;
22549 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22550 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22551 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22552 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22553 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22554 + bool debugMode;
22555 + uint8_t macId;
22556 + uint32_t exceptions;
22557 + struct tgec_cfg *p_TgecDriverParam;
22558 +} t_Tgec;
22559 +
22560 +
22561 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22562 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22563 +
22564 +
22565 +#endif /* __TGEC_H */
22566 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22567 new file mode 100644
22568 index 00000000..e0fafd1d
22569 --- /dev/null
22570 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22571 @@ -0,0 +1,139 @@
22572 +/*
22573 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22574 + *
22575 + * Redistribution and use in source and binary forms, with or without
22576 + * modification, are permitted provided that the following conditions are met:
22577 + * * Redistributions of source code must retain the above copyright
22578 + * notice, this list of conditions and the following disclaimer.
22579 + * * Redistributions in binary form must reproduce the above copyright
22580 + * notice, this list of conditions and the following disclaimer in the
22581 + * documentation and/or other materials provided with the distribution.
22582 + * * Neither the name of Freescale Semiconductor nor the
22583 + * names of its contributors may be used to endorse or promote products
22584 + * derived from this software without specific prior written permission.
22585 + *
22586 + *
22587 + * ALTERNATIVELY, this software may be distributed under the terms of the
22588 + * GNU General Public License ("GPL") as published by the Free Software
22589 + * Foundation, either version 2 of that License or (at your option) any
22590 + * later version.
22591 + *
22592 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22593 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22594 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22595 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22596 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22597 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22598 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22599 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22600 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22601 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22602 + */
22603 +
22604 +
22605 +
22606 +#include "error_ext.h"
22607 +#include "std_ext.h"
22608 +#include "fm_mac.h"
22609 +#include "tgec.h"
22610 +#include "xx_ext.h"
22611 +
22612 +#include "fm_common.h"
22613 +
22614 +
22615 +/*****************************************************************************/
22616 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22617 + uint8_t phyAddr,
22618 + uint8_t reg,
22619 + uint16_t data)
22620 +{
22621 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22622 + t_TgecMiiAccessMemMap *p_MiiAccess;
22623 + uint32_t cfgStatusReg;
22624 +
22625 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22626 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22627 +
22628 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22629 +
22630 + /* Configure MII */
22631 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22632 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22633 + /* (one half of fm clock => 2.5Mhz) */
22634 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22635 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22636 +
22637 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22638 + XX_UDelay (1);
22639 +
22640 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22641 +
22642 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22643 +
22644 + CORE_MemoryBarrier();
22645 +
22646 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22647 + XX_UDelay (1);
22648 +
22649 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22650 +
22651 + CORE_MemoryBarrier();
22652 +
22653 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22654 + XX_UDelay (1);
22655 +
22656 + return E_OK;
22657 +}
22658 +
22659 +/*****************************************************************************/
22660 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22661 + uint8_t phyAddr,
22662 + uint8_t reg,
22663 + uint16_t *p_Data)
22664 +{
22665 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22666 + t_TgecMiiAccessMemMap *p_MiiAccess;
22667 + uint32_t cfgStatusReg;
22668 +
22669 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22670 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22671 +
22672 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22673 +
22674 + /* Configure MII */
22675 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22676 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22677 + /* (one half of fm clock => 2.5Mhz) */
22678 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22679 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22680 +
22681 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22682 + XX_UDelay (1);
22683 +
22684 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22685 +
22686 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22687 +
22688 + CORE_MemoryBarrier();
22689 +
22690 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22691 + XX_UDelay (1);
22692 +
22693 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22694 +
22695 + CORE_MemoryBarrier();
22696 +
22697 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22698 + XX_UDelay (1);
22699 +
22700 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22701 +
22702 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22703 +
22704 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22705 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22706 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22707 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22708 +
22709 + return E_OK;
22710 +}
22711 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22712 new file mode 100644
22713 index 00000000..645cdde5
22714 --- /dev/null
22715 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22716 @@ -0,0 +1,80 @@
22717 +/*
22718 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22719 + *
22720 + * Redistribution and use in source and binary forms, with or without
22721 + * modification, are permitted provided that the following conditions are met:
22722 + * * Redistributions of source code must retain the above copyright
22723 + * notice, this list of conditions and the following disclaimer.
22724 + * * Redistributions in binary form must reproduce the above copyright
22725 + * notice, this list of conditions and the following disclaimer in the
22726 + * documentation and/or other materials provided with the distribution.
22727 + * * Neither the name of Freescale Semiconductor nor the
22728 + * names of its contributors may be used to endorse or promote products
22729 + * derived from this software without specific prior written permission.
22730 + *
22731 + *
22732 + * ALTERNATIVELY, this software may be distributed under the terms of the
22733 + * GNU General Public License ("GPL") as published by the Free Software
22734 + * Foundation, either version 2 of that License or (at your option) any
22735 + * later version.
22736 + *
22737 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22738 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22739 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22740 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22741 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22742 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22743 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22744 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22745 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22746 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22747 + */
22748 +
22749 +
22750 +#ifndef __TGEC_MII_ACC_H
22751 +#define __TGEC_MII_ACC_H
22752 +
22753 +#include "std_ext.h"
22754 +
22755 +
22756 +/* MII Management Command Register */
22757 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22758 +#define MIIMCOM_READ_CYCLE 0x00008000
22759 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22760 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22761 +
22762 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22763 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22764 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22765 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22766 +
22767 +#define MIIMCOM_DIV_MASK 0x0000ff00
22768 +#define MIIMCOM_DIV_SHIFT 8
22769 +
22770 +/* MII Management Indicator Register */
22771 +#define MIIMIND_BUSY 0x00000001
22772 +#define MIIMIND_READ_ERROR 0x00000002
22773 +
22774 +#define MIIDATA_BUSY 0x80000000
22775 +
22776 +#if defined(__MWERKS__) && !defined(__GNUC__)
22777 +#pragma pack(push,1)
22778 +#endif /* defined(__MWERKS__) && ... */
22779 +
22780 +/*----------------------------------------------------*/
22781 +/* MII Configuration Control Memory Map Registers */
22782 +/*----------------------------------------------------*/
22783 +typedef _Packed struct t_TgecMiiAccessMemMap
22784 +{
22785 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22786 + volatile uint32_t mdio_command; /* 0x034 */
22787 + volatile uint32_t mdio_data; /* 0x038 */
22788 + volatile uint32_t mdio_regaddr; /* 0x03c */
22789 +} _PackedType t_TgecMiiAccessMemMap ;
22790 +
22791 +#if defined(__MWERKS__) && !defined(__GNUC__)
22792 +#pragma pack(pop)
22793 +#endif /* defined(__MWERKS__) && ... */
22794 +
22795 +
22796 +#endif /* __TGEC_MII_ACC_H */
22797 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22798 new file mode 100644
22799 index 00000000..bfa02f5e
22800 --- /dev/null
22801 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22802 @@ -0,0 +1,15 @@
22803 +#
22804 +# Makefile for the Freescale Ethernet controllers
22805 +#
22806 +ccflags-y += -DVERSION=\"\"
22807 +#
22808 +#Include netcomm SW specific definitions
22809 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
22810 +
22811 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
22812 +
22813 +ccflags-y += -I$(NCSW_FM_INC)
22814 +
22815 +obj-y += fsl-ncsw-macsec.o
22816 +
22817 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
22818 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22819 new file mode 100644
22820 index 00000000..0a1b31f1
22821 --- /dev/null
22822 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22823 @@ -0,0 +1,237 @@
22824 +/*
22825 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22826 + *
22827 + * Redistribution and use in source and binary forms, with or without
22828 + * modification, are permitted provided that the following conditions are met:
22829 + * * Redistributions of source code must retain the above copyright
22830 + * notice, this list of conditions and the following disclaimer.
22831 + * * Redistributions in binary form must reproduce the above copyright
22832 + * notice, this list of conditions and the following disclaimer in the
22833 + * documentation and/or other materials provided with the distribution.
22834 + * * Neither the name of Freescale Semiconductor nor the
22835 + * names of its contributors may be used to endorse or promote products
22836 + * derived from this software without specific prior written permission.
22837 + *
22838 + *
22839 + * ALTERNATIVELY, this software may be distributed under the terms of the
22840 + * GNU General Public License ("GPL") as published by the Free Software
22841 + * Foundation, either version 2 of that License or (at your option) any
22842 + * later version.
22843 + *
22844 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22845 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22846 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22847 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22848 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22849 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22850 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22851 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22852 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22853 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22854 + */
22855 +/******************************************************************************
22856 +
22857 + @File fm_macsec.c
22858 +
22859 + @Description FM MACSEC driver routines implementation.
22860 +*//***************************************************************************/
22861 +
22862 +#include "std_ext.h"
22863 +#include "error_ext.h"
22864 +#include "xx_ext.h"
22865 +#include "string_ext.h"
22866 +#include "sprint_ext.h"
22867 +#include "debug_ext.h"
22868 +
22869 +#include "fm_macsec.h"
22870 +
22871 +
22872 +/****************************************/
22873 +/* API Init unit functions */
22874 +/****************************************/
22875 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
22876 +{
22877 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
22878 +
22879 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
22880 +
22881 + if (p_FmMacsecParam->guestMode)
22882 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
22883 + else
22884 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
22885 +
22886 + if (!p_FmMacsecControllerDriver)
22887 + return NULL;
22888 +
22889 + return (t_Handle)p_FmMacsecControllerDriver;
22890 +}
22891 +
22892 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
22893 +{
22894 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22895 +
22896 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22897 +
22898 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
22899 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
22900 +
22901 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22902 +}
22903 +
22904 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
22905 +{
22906 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22907 +
22908 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22909 +
22910 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
22911 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
22912 +
22913 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22914 +}
22915 +
22916 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
22917 +{
22918 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22919 +
22920 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22921 +
22922 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
22923 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
22924 +
22925 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22926 +}
22927 +
22928 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
22929 +{
22930 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22931 +
22932 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22933 +
22934 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
22935 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
22936 +
22937 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22938 +}
22939 +
22940 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
22941 +{
22942 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22943 +
22944 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22945 +
22946 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
22947 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
22948 +
22949 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22950 +}
22951 +
22952 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
22953 +{
22954 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22955 +
22956 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22957 +
22958 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
22959 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
22960 +
22961 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22962 +}
22963 +
22964 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
22965 +{
22966 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22967 +
22968 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22969 +
22970 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
22971 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
22972 +
22973 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22974 +}
22975 +
22976 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
22977 +{
22978 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22979 +
22980 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22981 +
22982 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
22983 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
22984 +
22985 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22986 +}
22987 +
22988 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
22989 +{
22990 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22991 +
22992 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22993 +
22994 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
22995 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
22996 +
22997 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22998 +}
22999 +
23000 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23001 +{
23002 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23003 +
23004 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23005 +
23006 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
23007 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
23008 +
23009 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23010 +}
23011 +
23012 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23013 +{
23014 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23015 +
23016 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23017 +
23018 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
23019 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
23020 +
23021 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23022 +}
23023 +
23024 +
23025 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
23026 +{
23027 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23028 +
23029 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23030 +
23031 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
23032 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
23033 +
23034 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23035 +}
23036 +
23037 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
23038 +{
23039 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23040 +
23041 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23042 +
23043 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
23044 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
23045 +
23046 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23047 +}
23048 +
23049 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23050 +{
23051 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23052 +
23053 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23054 +
23055 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
23056 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
23057 +
23058 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23059 +}
23060 +
23061 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23062 new file mode 100644
23063 index 00000000..fbe51875
23064 --- /dev/null
23065 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23066 @@ -0,0 +1,203 @@
23067 +/*
23068 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23069 + *
23070 + * Redistribution and use in source and binary forms, with or without
23071 + * modification, are permitted provided that the following conditions are met:
23072 + * * Redistributions of source code must retain the above copyright
23073 + * notice, this list of conditions and the following disclaimer.
23074 + * * Redistributions in binary form must reproduce the above copyright
23075 + * notice, this list of conditions and the following disclaimer in the
23076 + * documentation and/or other materials provided with the distribution.
23077 + * * Neither the name of Freescale Semiconductor nor the
23078 + * names of its contributors may be used to endorse or promote products
23079 + * derived from this software without specific prior written permission.
23080 + *
23081 + *
23082 + * ALTERNATIVELY, this software may be distributed under the terms of the
23083 + * GNU General Public License ("GPL") as published by the Free Software
23084 + * Foundation, either version 2 of that License or (at your option) any
23085 + * later version.
23086 + *
23087 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23088 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23089 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23090 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23091 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23092 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23093 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23094 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23095 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23096 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23097 + */
23098 +
23099 +/******************************************************************************
23100 + @File fm_macsec.h
23101 +
23102 + @Description FM MACSEC internal structures and definitions.
23103 +*//***************************************************************************/
23104 +#ifndef __FM_MACSEC_H
23105 +#define __FM_MACSEC_H
23106 +
23107 +#include "error_ext.h"
23108 +#include "std_ext.h"
23109 +#include "fm_macsec_ext.h"
23110 +
23111 +#include "fm_common.h"
23112 +
23113 +
23114 +#define __ERR_MODULE__ MODULE_FM_MACSEC
23115 +
23116 +
23117 +typedef struct
23118 +{
23119 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
23120 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
23121 +
23122 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
23123 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23124 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
23125 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23126 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
23127 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23128 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
23129 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
23130 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
23131 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23132 +
23133 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
23134 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
23135 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
23136 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23137 +
23138 +} t_FmMacsecControllerDriver;
23139 +
23140 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
23141 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
23142 +
23143 +/***********************************************************************/
23144 +/* MACSEC internal routines */
23145 +/***********************************************************************/
23146 +
23147 +/**************************************************************************//**
23148 +
23149 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
23150 +
23151 + @Description FM MACSEC Inter Module functions -
23152 + These are not User API routines but routines that may be called
23153 + from other modules. This will be the case in a single core environment,
23154 + where instead of using the XX messaging mechanism, the routines may be
23155 + called from other modules. In a multicore environment, the other modules may
23156 + be run by other cores and therefore these routines may not be called directly.
23157 +
23158 + @{
23159 +*//***************************************************************************/
23160 +
23161 +#define MAX_NUM_OF_SA_PER_SC 4
23162 +
23163 +typedef enum
23164 +{
23165 + e_SC_RX = 0,
23166 + e_SC_TX
23167 +} e_ScType;
23168 +
23169 +typedef enum
23170 +{
23171 + e_SC_SA_A = 0,
23172 + e_SC_SA_B ,
23173 + e_SC_SA_C ,
23174 + e_SC_SA_D
23175 +} e_ScSaId;
23176 +
23177 +typedef struct
23178 +{
23179 + uint32_t scId;
23180 + macsecSCI_t sci;
23181 + bool replayProtect;
23182 + uint32_t replayWindow;
23183 + e_FmMacsecValidFrameBehavior validateFrames;
23184 + uint16_t confidentialityOffset;
23185 + e_FmMacsecSecYCipherSuite cipherSuite;
23186 +} t_RxScParams;
23187 +
23188 +typedef struct
23189 +{
23190 + uint32_t scId;
23191 + macsecSCI_t sci;
23192 + bool protectFrames;
23193 + e_FmMacsecSciInsertionMode sciInsertionMode;
23194 + bool confidentialityEnable;
23195 + uint16_t confidentialityOffset;
23196 + e_FmMacsecSecYCipherSuite cipherSuite;
23197 +} t_TxScParams;
23198 +
23199 +typedef enum e_FmMacsecGlobalExceptions {
23200 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23201 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23202 +} e_FmMacsecGlobalExceptions;
23203 +
23204 +typedef enum e_FmMacsecGlobalEvents {
23205 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23206 +} e_FmMacsecGlobalEvents;
23207 +
23208 +/**************************************************************************//**
23209 + @Description Enum for inter-module interrupts registration
23210 +*//***************************************************************************/
23211 +typedef enum e_FmMacsecEventModules{
23212 + e_FM_MACSEC_MOD_SC_TX,
23213 + e_FM_MACSEC_MOD_DUMMY_LAST
23214 +} e_FmMacsecEventModules;
23215 +
23216 +typedef enum e_FmMacsecInterModuleEvent {
23217 + e_FM_MACSEC_EV_SC_TX,
23218 + e_FM_MACSEC_EV_ERR_SC_TX,
23219 + e_FM_MACSEC_EV_DUMMY_LAST
23220 +} e_FmMacsecInterModuleEvent;
23221 +
23222 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23223 +
23224 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23225 + switch(mod){ \
23226 + case e_FM_MACSEC_MOD_SC_TX: \
23227 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23228 + e_FM_MACSEC_EV_ERR_SC_TX: \
23229 + e_FM_MACSEC_EV_SC_TX; \
23230 + event += (uint8_t)(2 * id);break; \
23231 + break; \
23232 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23233 + break;}
23234 +
23235 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23236 + e_FmMacsecEventModules module,
23237 + uint8_t modId,
23238 + e_FmIntrType intrType,
23239 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23240 + t_Handle h_Arg);
23241 +
23242 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23243 + e_FmMacsecEventModules module,
23244 + uint8_t modId,
23245 + e_FmIntrType intrType);
23246 +
23247 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23248 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23249 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23250 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23251 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23252 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23253 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23254 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23255 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23256 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23257 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23258 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23259 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23260 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23261 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23262 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23263 +
23264 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23265 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23266 +
23267 +
23268 +
23269 +#endif /* __FM_MACSEC_H */
23270 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23271 new file mode 100644
23272 index 00000000..31d789d0
23273 --- /dev/null
23274 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23275 @@ -0,0 +1,59 @@
23276 +/*
23277 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23278 + *
23279 + * Redistribution and use in source and binary forms, with or without
23280 + * modification, are permitted provided that the following conditions are met:
23281 + * * Redistributions of source code must retain the above copyright
23282 + * notice, this list of conditions and the following disclaimer.
23283 + * * Redistributions in binary form must reproduce the above copyright
23284 + * notice, this list of conditions and the following disclaimer in the
23285 + * documentation and/or other materials provided with the distribution.
23286 + * * Neither the name of Freescale Semiconductor nor the
23287 + * names of its contributors may be used to endorse or promote products
23288 + * derived from this software without specific prior written permission.
23289 + *
23290 + *
23291 + * ALTERNATIVELY, this software may be distributed under the terms of the
23292 + * GNU General Public License ("GPL") as published by the Free Software
23293 + * Foundation, either version 2 of that License or (at your option) any
23294 + * later version.
23295 + *
23296 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23297 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23298 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23299 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23300 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23301 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23302 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23303 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23304 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23305 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23306 + */
23307 +
23308 +/******************************************************************************
23309 + @File fm_macsec.c
23310 +
23311 + @Description FM MACSEC driver routines implementation.
23312 +*//***************************************************************************/
23313 +
23314 +#include "std_ext.h"
23315 +#include "error_ext.h"
23316 +#include "xx_ext.h"
23317 +#include "string_ext.h"
23318 +#include "sprint_ext.h"
23319 +#include "debug_ext.h"
23320 +#include "fm_macsec.h"
23321 +
23322 +
23323 +/****************************************/
23324 +/* static functions */
23325 +/****************************************/
23326 +
23327 +/****************************************/
23328 +/* API Init unit functions */
23329 +/****************************************/
23330 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23331 +{
23332 + UNUSED(p_FmMacsecParam);
23333 + return NULL;
23334 +}
23335 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23336 new file mode 100644
23337 index 00000000..623612ac
23338 --- /dev/null
23339 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23340 @@ -0,0 +1,1031 @@
23341 +/*
23342 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23343 + *
23344 + * Redistribution and use in source and binary forms, with or without
23345 + * modification, are permitted provided that the following conditions are met:
23346 + * * Redistributions of source code must retain the above copyright
23347 + * notice, this list of conditions and the following disclaimer.
23348 + * * Redistributions in binary form must reproduce the above copyright
23349 + * notice, this list of conditions and the following disclaimer in the
23350 + * documentation and/or other materials provided with the distribution.
23351 + * * Neither the name of Freescale Semiconductor nor the
23352 + * names of its contributors may be used to endorse or promote products
23353 + * derived from this software without specific prior written permission.
23354 + *
23355 + *
23356 + * ALTERNATIVELY, this software may be distributed under the terms of the
23357 + * GNU General Public License ("GPL") as published by the Free Software
23358 + * Foundation, either version 2 of that License or (at your option) any
23359 + * later version.
23360 + *
23361 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23362 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23363 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23364 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23365 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23366 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23367 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23368 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23369 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23370 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23371 + */
23372 +
23373 +/******************************************************************************
23374 + @File fm_macsec.c
23375 +
23376 + @Description FM MACSEC driver routines implementation.
23377 +*//***************************************************************************/
23378 +
23379 +#include "std_ext.h"
23380 +#include "error_ext.h"
23381 +#include "xx_ext.h"
23382 +#include "string_ext.h"
23383 +#include "sprint_ext.h"
23384 +#include "fm_mac_ext.h"
23385 +
23386 +#include "fm_macsec_master.h"
23387 +
23388 +
23389 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23390 +
23391 +
23392 +/****************************************/
23393 +/* static functions */
23394 +/****************************************/
23395 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23396 +{
23397 + if (!p_FmMacsec->f_Exception)
23398 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23399 +
23400 + return E_OK;
23401 +}
23402 +
23403 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23404 +{
23405 + UNUSED(h_Arg); UNUSED(id);
23406 +
23407 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23408 +}
23409 +
23410 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23411 +{
23412 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23413 + uint32_t events,event,i;
23414 +
23415 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23416 +
23417 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23418 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23419 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23420 +
23421 + for (i=0; i<NUM_OF_TX_SC; i++)
23422 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23423 + {
23424 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23425 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23426 + }
23427 +}
23428 +
23429 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23430 +{
23431 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23432 + uint32_t errors,error,i;
23433 +
23434 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23435 +
23436 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23437 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23438 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23439 +
23440 + for (i=0; i<NUM_OF_TX_SC; i++)
23441 + if (errors & FM_MACSEC_EX_TX_SC(i))
23442 + {
23443 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23444 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23445 + }
23446 +
23447 + if (errors & FM_MACSEC_EX_ECC)
23448 + {
23449 + uint8_t eccType;
23450 + uint32_t tmpReg;
23451 +
23452 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23453 + ASSERT_COND(tmpReg & MECC_CAP);
23454 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23455 +
23456 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23457 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23458 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23459 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23460 + else
23461 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23462 + }
23463 +}
23464 +
23465 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23466 +{
23467 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23468 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23469 + uint32_t tmpReg,i,macId;
23470 +
23471 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23472 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23473 +
23474 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23475 +
23476 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23477 +
23478 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23479 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23480 +
23481 + tmpReg = 0;
23482 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23483 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23484 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23485 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23486 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23487 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23488 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23489 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23490 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23491 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23492 +
23493 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23494 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23495 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23496 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23497 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23498 +
23499 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23500 +
23501 + if (!p_FmMacsec->userExceptions)
23502 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23503 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23504 +
23505 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23506 + if (p_FmMacsecDriverParam->reservedSc0)
23507 + p_FmMacsec->numRxScAvailable --;
23508 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23509 +
23510 + XX_Free(p_FmMacsecDriverParam);
23511 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23512 +
23513 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23514 + FmRegisterIntr(p_FmMacsec->h_Fm,
23515 + e_FM_MOD_MACSEC,
23516 + (uint8_t)macId,
23517 + e_FM_INTR_TYPE_NORMAL,
23518 + MacsecEventIsr,
23519 + p_FmMacsec);
23520 +
23521 + FmRegisterIntr(p_FmMacsec->h_Fm,
23522 + e_FM_MOD_MACSEC,
23523 + 0,
23524 + e_FM_INTR_TYPE_ERR,
23525 + MacsecErrorIsr,
23526 + p_FmMacsec);
23527 +
23528 + return E_OK;
23529 +}
23530 +
23531 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23532 +{
23533 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23534 + uint32_t macId;
23535 +
23536 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23537 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23538 +
23539 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23540 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23541 + e_FM_MOD_MACSEC,
23542 + (uint8_t)macId,
23543 + e_FM_INTR_TYPE_NORMAL);
23544 +
23545 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23546 + e_FM_MOD_MACSEC,
23547 + 0,
23548 + e_FM_INTR_TYPE_ERR);
23549 +
23550 + if (p_FmMacsec->rxScSpinLock)
23551 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23552 + if (p_FmMacsec->txScSpinLock)
23553 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23554 +
23555 + XX_Free(p_FmMacsec);
23556 +
23557 + return E_OK;
23558 +}
23559 +
23560 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23561 +{
23562 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23563 +
23564 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23565 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23566 +
23567 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23568 +
23569 + return E_OK;
23570 +}
23571 +
23572 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23573 +{
23574 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23575 +
23576 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23577 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23578 +
23579 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23580 +
23581 + return E_OK;
23582 +}
23583 +
23584 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23585 +{
23586 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23587 +
23588 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23589 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23590 +
23591 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23592 +
23593 + return E_OK;
23594 +}
23595 +
23596 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23597 +{
23598 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23599 +
23600 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23601 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23602 +
23603 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23604 +
23605 + return E_OK;
23606 +}
23607 +
23608 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23609 +{
23610 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23611 +
23612 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23613 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23614 +
23615 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23616 +
23617 + return E_OK;
23618 +}
23619 +
23620 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23621 +{
23622 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23623 +
23624 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23625 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23626 +
23627 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23628 +
23629 + return E_OK;
23630 +}
23631 +
23632 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23633 +{
23634 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23635 +
23636 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23637 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23638 +
23639 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23640 +
23641 + return E_OK;
23642 +}
23643 +
23644 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23645 +{
23646 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23647 +
23648 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23649 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23650 +
23651 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23652 +
23653 + return E_OK;
23654 +}
23655 +
23656 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23657 +{
23658 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23659 +
23660 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23661 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23662 +
23663 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23664 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23665 +
23666 + return E_OK;
23667 +}
23668 +
23669 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23670 +{
23671 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23672 + uint32_t bitMask = 0;
23673 +
23674 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23675 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23676 +
23677 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23678 + if (bitMask)
23679 + {
23680 + if (enable)
23681 + p_FmMacsec->userExceptions |= bitMask;
23682 + else
23683 + p_FmMacsec->userExceptions &= ~bitMask;
23684 + }
23685 + else
23686 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23687 +
23688 + return E_OK;
23689 +}
23690 +
23691 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23692 +{
23693 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23694 +
23695 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23696 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23697 +
23698 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23699 +
23700 + return E_OK;
23701 +}
23702 +
23703 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23704 +{
23705 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23706 + uint32_t tmpReg;
23707 +
23708 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23709 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23710 +
23711 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23712 + tmpReg |= CFG_BYPN;
23713 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23714 +
23715 + return E_OK;
23716 +}
23717 +
23718 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23719 +{
23720 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23721 + uint32_t tmpReg;
23722 +
23723 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23724 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23725 +
23726 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23727 + tmpReg &= ~CFG_BYPN;
23728 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23729 +
23730 + return E_OK;
23731 +}
23732 +
23733 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23734 +{
23735 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23736 + uint32_t bitMask;
23737 +
23738 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23739 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23740 +
23741 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23742 + if (bitMask)
23743 + {
23744 + if (enable)
23745 + p_FmMacsec->userExceptions |= bitMask;
23746 + else
23747 + p_FmMacsec->userExceptions &= ~bitMask;
23748 + }
23749 + else
23750 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23751 +
23752 + if (!p_FmMacsec->userExceptions)
23753 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23754 + else
23755 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23756 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23757 +
23758 + return E_OK;
23759 +}
23760 +
23761 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23762 +{
23763 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23764 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23765 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23766 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23767 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23768 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23769 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23770 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23771 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23772 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23773 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23774 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23775 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23776 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23777 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23778 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23779 +}
23780 +
23781 +/****************************************/
23782 +/* Inter-Module functions */
23783 +/****************************************/
23784 +
23785 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23786 + e_FmMacsecEventModules module,
23787 + uint8_t modId,
23788 + e_FmIntrType intrType,
23789 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23790 + t_Handle h_Arg)
23791 +{
23792 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23793 + uint8_t event= 0;
23794 +
23795 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23796 +
23797 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23798 +
23799 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23800 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23801 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23802 +}
23803 +
23804 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23805 + e_FmMacsecEventModules module,
23806 + uint8_t modId,
23807 + e_FmIntrType intrType)
23808 +{
23809 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23810 + uint8_t event= 0;
23811 +
23812 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23813 +
23814 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
23815 +
23816 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23817 + p_FmMacsec->intrMng[event].f_Isr = NULL;
23818 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
23819 +}
23820 +
23821 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
23822 +{
23823 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23824 + t_Error err = E_OK;
23825 + bool *p_ScTable;
23826 + uint32_t *p_ScAvailable,i;
23827 +
23828 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23829 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23830 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23831 +
23832 + if (type == e_SC_RX)
23833 + {
23834 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23835 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23836 + i = (NUM_OF_RX_SC - 1);
23837 + }
23838 + else
23839 + {
23840 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23841 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23842 + i = (NUM_OF_TX_SC - 1);
23843 +
23844 + }
23845 + if (*p_ScAvailable < numOfScs)
23846 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
23847 +
23848 + if (isPtp)
23849 + {
23850 + i = 0;
23851 + if (p_ScTable[i])
23852 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
23853 + }
23854 +
23855 + for (;numOfScs;i--)
23856 + {
23857 + if (p_ScTable[i])
23858 + continue;
23859 + numOfScs --;
23860 + (*p_ScAvailable)--;
23861 + p_ScIds[numOfScs] = i;
23862 + p_ScTable[i] = TRUE;
23863 + }
23864 +
23865 + return err;
23866 +}
23867 +
23868 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
23869 +{
23870 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23871 + t_Error err = E_OK;
23872 + bool *p_ScTable;
23873 + uint32_t *p_ScAvailable,maxNumOfSc,i;
23874 +
23875 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23876 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23877 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23878 +
23879 + if (type == e_SC_RX)
23880 + {
23881 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23882 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23883 + maxNumOfSc = NUM_OF_RX_SC;
23884 + }
23885 + else
23886 + {
23887 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23888 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23889 + maxNumOfSc = NUM_OF_TX_SC;
23890 + }
23891 +
23892 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
23893 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
23894 +
23895 + for (i=0;i<numOfScs;i++)
23896 + {
23897 + p_ScTable[p_ScIds[i]] = FALSE;
23898 + (*p_ScAvailable)++;
23899 + }
23900 +
23901 + return err;
23902 +
23903 +}
23904 +
23905 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
23906 +{
23907 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23908 + uint32_t tmpReg = 0;
23909 +
23910 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23911 +
23912 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23913 + if (enable && (tmpReg & CFG_S0I))
23914 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
23915 +
23916 + if (enable)
23917 + tmpReg |= CFG_S0I;
23918 + else
23919 + tmpReg &= ~CFG_S0I;
23920 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23921 +
23922 + return E_OK;
23923 +}
23924 +
23925 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
23926 +{
23927 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23928 + t_Error err = E_OK;
23929 + uint32_t tmpReg = 0, intFlags;
23930 +
23931 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23932 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
23933 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23934 +
23935 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23936 +
23937 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
23938 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
23939 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
23940 + {
23941 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23942 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
23943 + }
23944 +
23945 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
23946 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
23947 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
23948 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
23949 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
23950 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
23951 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
23952 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23953 +
23954 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
23955 +
23956 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23957 +
23958 + return err;
23959 +}
23960 +
23961 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
23962 +{
23963 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23964 + t_Error err = E_OK;
23965 + uint32_t tmpReg = 0, intFlags;
23966 +
23967 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23968 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23969 +
23970 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23971 +
23972 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
23973 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23974 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23975 +
23976 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23977 +
23978 + return err;
23979 +}
23980 +
23981 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
23982 +{
23983 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23984 + t_Error err = E_OK;
23985 + uint32_t tmpReg = 0, intFlags;
23986 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
23987 +
23988 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23989 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
23990 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23991 +
23992 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23993 +
23994 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
23995 +
23996 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
23997 + if (tmpReg & TX_SCCFG_SCE_MASK)
23998 + {
23999 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24000 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
24001 + }
24002 +
24003 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
24004 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
24005 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
24006 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
24007 +
24008 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
24009 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
24010 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
24011 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
24012 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
24013 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
24014 + tmpReg |= TX_SCCFG_SCE_MASK;
24015 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
24016 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24017 +
24018 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24019 +
24020 + return err;
24021 +}
24022 +
24023 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
24024 +{
24025 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24026 + t_Error err = E_OK;
24027 + uint32_t tmpReg = 0, intFlags;
24028 +
24029 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24030 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24031 +
24032 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24033 +
24034 + tmpReg &= ~TX_SCCFG_SCE_MASK;
24035 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24036 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24037 +
24038 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24039 +
24040 + return err;
24041 +}
24042 +
24043 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
24044 +{
24045 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24046 + t_Error err = E_OK;
24047 + uint32_t tmpReg = 0, intFlags;
24048 +
24049 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24050 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24051 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24052 +
24053 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24054 +
24055 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24056 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
24057 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
24058 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
24059 +
24060 + tmpReg |= RX_SACFG_ACTIVE;
24061 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
24062 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24063 +
24064 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24065 +
24066 + return err;
24067 +}
24068 +
24069 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
24070 +{
24071 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24072 + t_Error err = E_OK;
24073 + uint32_t tmpReg = 0, intFlags;
24074 +
24075 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24076 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24077 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24078 +
24079 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24080 +
24081 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24082 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
24083 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
24084 +
24085 + tmpReg |= TX_SACFG_ACTIVE;
24086 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24087 +
24088 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24089 +
24090 + return err;
24091 +}
24092 +
24093 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24094 +{
24095 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24096 + t_Error err = E_OK;
24097 + uint32_t tmpReg = 0, i, intFlags;
24098 +
24099 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24100 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24101 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24102 +
24103 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24104 +
24105 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24106 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
24107 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
24108 + for (i=0; i<4; i++)
24109 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
24110 +
24111 + tmpReg |= RX_SACFG_ACTIVE;
24112 + tmpReg &= ~RX_SACFG_EN_MASK;
24113 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24114 +
24115 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24116 +
24117 + return err;
24118 +}
24119 +
24120 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24121 +{
24122 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24123 + t_Error err = E_OK;
24124 + uint32_t tmpReg = 0, i, intFlags;
24125 +
24126 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24127 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24128 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24129 +
24130 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24131 +
24132 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24133 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
24134 + for (i=0; i<4; i++)
24135 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
24136 +
24137 + tmpReg |= TX_SACFG_ACTIVE;
24138 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24139 +
24140 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24141 +
24142 + return err;
24143 +}
24144 +
24145 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
24146 +{
24147 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24148 + t_Error err = E_OK;
24149 + uint32_t tmpReg = 0, intFlags;
24150 +
24151 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24152 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24153 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24154 +
24155 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24156 +
24157 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24158 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
24159 + if (enableReceive)
24160 + tmpReg |= RX_SACFG_EN_MASK;
24161 + else
24162 + tmpReg &= ~RX_SACFG_EN_MASK;
24163 +
24164 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24165 +
24166 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24167 +
24168 + return err;
24169 +}
24170 +
24171 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24172 +{
24173 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24174 + t_Error err = E_OK;
24175 + uint32_t intFlags;
24176 +
24177 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24178 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24179 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24180 +
24181 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24182 +
24183 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24184 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24185 +
24186 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24187 +
24188 + return err;
24189 +}
24190 +
24191 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24192 +{
24193 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24194 + t_Error err = E_OK;
24195 + uint32_t intFlags;
24196 +
24197 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24198 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24199 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24200 +
24201 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24202 +
24203 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24204 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24205 +
24206 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24207 +
24208 + return err;
24209 +}
24210 +
24211 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
24212 +{
24213 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24214 + t_Error err = E_OK;
24215 + uint32_t tmpReg = 0, intFlags;
24216 +
24217 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24218 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24219 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24220 +
24221 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24222 +
24223 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24224 +
24225 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24226 +
24227 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24228 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24229 +
24230 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24231 +
24232 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24233 +
24234 + return err;
24235 +}
24236 +
24237 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
24238 +{
24239 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24240 + t_Error err = E_OK;
24241 + uint32_t tmpReg = 0, intFlags;
24242 +
24243 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24244 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24245 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
24246 +
24247 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24248 +
24249 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24250 +
24251 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24252 +
24253 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24254 +
24255 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24256 +
24257 + return err;
24258 +}
24259 +
24260 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24261 +{
24262 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24263 + uint32_t bitMask;
24264 +
24265 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24266 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24267 +
24268 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24269 + if (bitMask)
24270 + {
24271 + if (enable)
24272 + p_FmMacsec->exceptions |= bitMask;
24273 + else
24274 + p_FmMacsec->exceptions &= ~bitMask;
24275 + }
24276 + else
24277 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24278 +
24279 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24280 +
24281 + return E_OK;
24282 +}
24283 +
24284 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24285 +{
24286 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24287 + uint32_t bitMask;
24288 +
24289 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24290 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24291 +
24292 + GET_EVENT_FLAG(bitMask, event, scId);
24293 + if (bitMask)
24294 + {
24295 + if (enable)
24296 + p_FmMacsec->events |= bitMask;
24297 + else
24298 + p_FmMacsec->events &= ~bitMask;
24299 + }
24300 + else
24301 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24302 +
24303 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24304 +
24305 + return E_OK;
24306 +}
24307 +
24308 +/****************************************/
24309 +/* API Init unit functions */
24310 +/****************************************/
24311 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24312 +{
24313 + t_FmMacsec *p_FmMacsec;
24314 + uint32_t macId;
24315 +
24316 + /* Allocate FM MACSEC structure */
24317 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24318 + if (!p_FmMacsec)
24319 + {
24320 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24321 + return NULL;
24322 + }
24323 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24324 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24325 +
24326 + /* Allocate the FM MACSEC driver's parameters structure */
24327 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24328 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24329 + {
24330 + XX_Free(p_FmMacsec);
24331 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24332 + return NULL;
24333 + }
24334 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24335 +
24336 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24337 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24338 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24339 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24340 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24341 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24342 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24343 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24344 + p_FmMacsec->events = DEFAULT_events;
24345 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24346 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24347 +
24348 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24349 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24350 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24351 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24352 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24353 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24354 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24355 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24356 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24357 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24358 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24359 + /* build the FM MACSEC master IPC address */
24360 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24361 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24362 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24363 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24364 + {
24365 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24366 + XX_Free(p_FmMacsec);
24367 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24368 + return NULL;
24369 + }
24370 + return p_FmMacsec;
24371 +}
24372 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24373 new file mode 100644
24374 index 00000000..2296a0f1
24375 --- /dev/null
24376 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24377 @@ -0,0 +1,479 @@
24378 +/*
24379 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24380 + *
24381 + * Redistribution and use in source and binary forms, with or without
24382 + * modification, are permitted provided that the following conditions are met:
24383 + * * Redistributions of source code must retain the above copyright
24384 + * notice, this list of conditions and the following disclaimer.
24385 + * * Redistributions in binary form must reproduce the above copyright
24386 + * notice, this list of conditions and the following disclaimer in the
24387 + * documentation and/or other materials provided with the distribution.
24388 + * * Neither the name of Freescale Semiconductor nor the
24389 + * names of its contributors may be used to endorse or promote products
24390 + * derived from this software without specific prior written permission.
24391 + *
24392 + *
24393 + * ALTERNATIVELY, this software may be distributed under the terms of the
24394 + * GNU General Public License ("GPL") as published by the Free Software
24395 + * Foundation, either version 2 of that License or (at your option) any
24396 + * later version.
24397 + *
24398 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24399 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24400 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24401 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24402 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24403 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24404 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24405 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24406 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24407 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24408 + */
24409 +
24410 +/******************************************************************************
24411 + @File fm_macsec_master.h
24412 +
24413 + @Description FM MACSEC internal structures and definitions.
24414 +*//***************************************************************************/
24415 +#ifndef __FM_MACSEC_MASTER_H
24416 +#define __FM_MACSEC_MASTER_H
24417 +
24418 +#include "error_ext.h"
24419 +#include "std_ext.h"
24420 +
24421 +#include "fm_macsec.h"
24422 +
24423 +
24424 +#define MACSEC_ICV_SIZE 16
24425 +#define MACSEC_SECTAG_SIZE 16
24426 +#define MACSEC_SCI_SIZE 8
24427 +#define MACSEC_FCS_SIZE 4
24428 +
24429 +/**************************************************************************//**
24430 + @Description Exceptions
24431 +*//***************************************************************************/
24432 +
24433 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24434 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24435 +#define FM_MACSEC_EX_ECC 0x00000001
24436 +
24437 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24438 + case e_FM_MACSEC_EX_TX_SC: \
24439 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24440 + case e_FM_MACSEC_EX_ECC: \
24441 + bitMask = FM_MACSEC_EX_ECC; break; \
24442 + default: bitMask = 0;break;}
24443 +
24444 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24445 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24446 +
24447 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24448 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24449 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24450 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24451 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24452 + default: bitMask = 0;break;}
24453 +
24454 +/**************************************************************************//**
24455 + @Description Events
24456 +*//***************************************************************************/
24457 +
24458 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24459 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24460 +
24461 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24462 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24463 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24464 + default: bitMask = 0;break;}
24465 +
24466 +/**************************************************************************//**
24467 + @Description Defaults
24468 +*//***************************************************************************/
24469 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24470 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24471 +
24472 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24473 + FM_MACSEC_EX_TX_SC(1) |\
24474 + FM_MACSEC_EX_TX_SC(2) |\
24475 + FM_MACSEC_EX_TX_SC(3) |\
24476 + FM_MACSEC_EX_TX_SC(4) |\
24477 + FM_MACSEC_EX_TX_SC(5) |\
24478 + FM_MACSEC_EX_TX_SC(6) |\
24479 + FM_MACSEC_EX_TX_SC(7) |\
24480 + FM_MACSEC_EX_TX_SC(8) |\
24481 + FM_MACSEC_EX_TX_SC(9) |\
24482 + FM_MACSEC_EX_TX_SC(10) |\
24483 + FM_MACSEC_EX_TX_SC(11) |\
24484 + FM_MACSEC_EX_TX_SC(12) |\
24485 + FM_MACSEC_EX_TX_SC(13) |\
24486 + FM_MACSEC_EX_TX_SC(14) |\
24487 + FM_MACSEC_EX_TX_SC(15) |\
24488 + FM_MACSEC_EX_ECC )
24489 +
24490 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24491 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24492 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24493 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24494 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24495 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24496 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24497 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24498 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24499 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24500 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24501 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24502 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24503 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24504 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24505 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24506 +
24507 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24508 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24509 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24510 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24511 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24512 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24513 +#define DEFAULT_keysUnreadable FALSE
24514 +#define DEFAULT_normalMode TRUE
24515 +#define DEFAULT_sc0ReservedForPTP FALSE
24516 +#define DEFAULT_initNextPn 1
24517 +#define DEFAULT_pnExhThr 0xffffffff
24518 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24519 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24520 +
24521 +
24522 +/**************************************************************************//**
24523 + @Description Memory Mapped Registers
24524 +*//***************************************************************************/
24525 +
24526 +#if defined(__MWERKS__) && !defined(__GNUC__)
24527 +#pragma pack(push,1)
24528 +#endif /* defined(__MWERKS__) && ... */
24529 +
24530 +typedef _Packed struct
24531 +{
24532 + /* MACsec configuration */
24533 + volatile uint32_t cfg; /**< MACsec configuration */
24534 + volatile uint32_t et; /**< MACsec EtherType */
24535 + volatile uint8_t res1[56]; /**< reserved */
24536 + volatile uint32_t mfl; /**< Maximum Frame Length */
24537 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24538 + volatile uint8_t res2[56]; /**< reserved */
24539 + volatile uint32_t rxsca; /**< RX SC access select */
24540 + volatile uint8_t res3[60]; /**< reserved */
24541 + volatile uint32_t txsca; /**< TX SC access select */
24542 + volatile uint8_t res4[60]; /**< reserved */
24543 +
24544 + /* RX configuration, status and statistic */
24545 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24546 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24547 + volatile uint8_t res5[8]; /**< reserved */
24548 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24549 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24550 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24551 + volatile uint8_t res6[4]; /**< reserved */
24552 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24553 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24554 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24555 + volatile uint32_t rpw; /**< replayWindow */
24556 + volatile uint8_t res7[16]; /**< reserved */
24557 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24558 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24559 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24560 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24561 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24562 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24563 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24564 + volatile uint8_t res8[4]; /**< reserved */
24565 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24566 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24567 + _Packed struct
24568 + {
24569 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24570 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24571 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24572 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24573 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24574 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24575 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24576 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24577 + volatile uint8_t res9[8]; /**< reserved */
24578 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24579 +
24580 + /* TX configuration, status and statistic */
24581 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24582 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24583 + volatile uint8_t res10[8]; /**< reserved */
24584 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24585 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24586 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24587 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24588 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24589 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24590 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24591 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24592 + volatile uint8_t res11[16]; /**< reserved */
24593 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24594 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24595 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24596 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24597 + volatile uint8_t res12[48]; /**< reserved */
24598 + _Packed struct
24599 + {
24600 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24601 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24602 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24603 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24604 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24605 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24606 + volatile uint8_t res13[16]; /**< reserved */
24607 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24608 + volatile uint8_t res14[248]; /**< reserved */
24609 +
24610 + /* Global configuration and status */
24611 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24612 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24613 + volatile uint32_t evr; /**< MACsec Event Register */
24614 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24615 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24616 + volatile uint32_t err; /**< MACsec Error Register */
24617 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24618 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24619 + volatile uint8_t res15[40]; /**< reserved */
24620 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24621 + volatile uint32_t idle; /**< MACsec Idle status Register */
24622 + volatile uint8_t res16[184]; /**< reserved */
24623 + /* DEBUG */
24624 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24625 + volatile uint8_t res17[28]; /**< reserved */
24626 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24627 + volatile uint8_t res18[220]; /**< reserved */
24628 +
24629 + /* Macsec Rx global statistic */
24630 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24631 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24632 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24633 + volatile uint8_t res19[4]; /**< reserved */
24634 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24635 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24636 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24637 + volatile uint8_t res20[4]; /**< reserved */
24638 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24639 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24640 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24641 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24642 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24643 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24644 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24645 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24646 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24647 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24648 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24649 + volatile uint8_t res21[52]; /**< reserved */
24650 +
24651 + /* Macsec Tx global statistic */
24652 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24653 +#if (DPAA_VERSION >= 11)
24654 + volatile uint8_t res22[124]; /**< reserved */
24655 + _Packed struct
24656 + {
24657 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24658 + volatile uint8_t res23[32]; /**< reserved */
24659 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24660 + _Packed struct
24661 + {
24662 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24663 + volatile uint8_t res24[32]; /**< reserved */
24664 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24665 +#endif /* (DPAA_VERSION >= 11) */
24666 +} _PackedType t_FmMacsecRegs;
24667 +
24668 +#if defined(__MWERKS__) && !defined(__GNUC__)
24669 +#pragma pack(pop)
24670 +#endif /* defined(__MWERKS__) && ... */
24671 +
24672 +
24673 +/**************************************************************************//**
24674 + @Description General defines
24675 +*//***************************************************************************/
24676 +
24677 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24678 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24679 +
24680 +#define LONG_SHIFT 32
24681 +
24682 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24683 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24684 +
24685 +/**************************************************************************//**
24686 + @Description Configuration defines
24687 +*//***************************************************************************/
24688 +
24689 +/* masks */
24690 +#define CFG_UECT 0x00000800
24691 +#define CFG_ESCBT 0x00000400
24692 +#define CFG_USFT 0x00000300
24693 +#define CFG_ITT 0x00000080
24694 +#define CFG_KFT 0x00000040
24695 +#define CFG_UFT 0x00000030
24696 +#define CFG_KSS 0x00000004
24697 +#define CFG_BYPN 0x00000002
24698 +#define CFG_S0I 0x00000001
24699 +
24700 +#define ET_TYPE 0x0000ffff
24701 +
24702 +#define MFL_MAX_LEN 0x0000ffff
24703 +
24704 +#define RXSCA_SC_SEL 0x0000000f
24705 +
24706 +#define TXSCA_SC_SEL 0x0000000f
24707 +
24708 +#define IP_REV_1_IP_ID 0xffff0000
24709 +#define IP_REV_1_IP_MJ 0x0000ff00
24710 +#define IP_REV_1_IP_MM 0x000000ff
24711 +
24712 +#define IP_REV_2_IP_INT 0x00ff0000
24713 +#define IP_REV_2_IP_ERR 0x0000ff00
24714 +#define IP_REV_2_IP_CFG 0x000000ff
24715 +
24716 +#define MECC_CAP 0x80000000
24717 +#define MECC_CET 0x40000000
24718 +#define MECC_SERCNT 0x00ff0000
24719 +#define MECC_MEMADDR 0x000001ff
24720 +
24721 +/* shifts */
24722 +#define CFG_UECT_SHIFT (31-20)
24723 +#define CFG_ESCBT_SHIFT (31-21)
24724 +#define CFG_USFT_SHIFT (31-23)
24725 +#define CFG_ITT_SHIFT (31-24)
24726 +#define CFG_KFT_SHIFT (31-25)
24727 +#define CFG_UFT_SHIFT (31-27)
24728 +#define CFG_KSS_SHIFT (31-29)
24729 +#define CFG_BYPN_SHIFT (31-30)
24730 +#define CFG_S0I_SHIFT (31-31)
24731 +
24732 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24733 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24734 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24735 +
24736 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24737 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24738 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24739 +
24740 +#define MECC_CAP_SHIFT (31-0)
24741 +#define MECC_CET_SHIFT (31-1)
24742 +#define MECC_SERCNT_SHIFT (31-15)
24743 +#define MECC_MEMADDR_SHIFT (31-31)
24744 +
24745 +/**************************************************************************//**
24746 + @Description RX SC defines
24747 +*//***************************************************************************/
24748 +
24749 +/* masks */
24750 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24751 +#define RX_SCCFG_RP_MASK 0x00000400
24752 +#define RX_SCCFG_VF_MASK 0x00000300
24753 +#define RX_SCCFG_CO_MASK 0x0000003f
24754 +
24755 +/* shifts */
24756 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24757 +#define RX_SCCFG_RP_SHIFT (31-21)
24758 +#define RX_SCCFG_VF_SHIFT (31-23)
24759 +#define RX_SCCFG_CO_SHIFT (31-31)
24760 +#define RX_SCCFG_CS_SHIFT (31-7)
24761 +
24762 +/**************************************************************************//**
24763 + @Description RX SA defines
24764 +*//***************************************************************************/
24765 +
24766 +/* masks */
24767 +#define RX_SACFG_ACTIVE 0x80000000
24768 +#define RX_SACFG_AN_MASK 0x00000006
24769 +#define RX_SACFG_EN_MASK 0x00000001
24770 +
24771 +/* shifts */
24772 +#define RX_SACFG_AN_SHIFT (31-30)
24773 +#define RX_SACFG_EN_SHIFT (31-31)
24774 +
24775 +/**************************************************************************//**
24776 + @Description TX SC defines
24777 +*//***************************************************************************/
24778 +
24779 +/* masks */
24780 +#define TX_SCCFG_AN_MASK 0x000c0000
24781 +#define TX_SCCFG_ASA_MASK 0x00020000
24782 +#define TX_SCCFG_SCE_MASK 0x00010000
24783 +#define TX_SCCFG_CO_MASK 0x00003f00
24784 +#define TX_SCCFG_CE_MASK 0x00000010
24785 +#define TX_SCCFG_PF_MASK 0x00000008
24786 +#define TX_SCCFG_AIS_MASK 0x00000004
24787 +#define TX_SCCFG_UES_MASK 0x00000002
24788 +#define TX_SCCFG_USCB_MASK 0x00000001
24789 +
24790 +/* shifts */
24791 +#define TX_SCCFG_AN_SHIFT (31-13)
24792 +#define TX_SCCFG_ASA_SHIFT (31-14)
24793 +#define TX_SCCFG_SCE_SHIFT (31-15)
24794 +#define TX_SCCFG_CO_SHIFT (31-23)
24795 +#define TX_SCCFG_CE_SHIFT (31-27)
24796 +#define TX_SCCFG_PF_SHIFT (31-28)
24797 +#define TX_SCCFG_AIS_SHIFT (31-29)
24798 +#define TX_SCCFG_UES_SHIFT (31-30)
24799 +#define TX_SCCFG_USCB_SHIFT (31-31)
24800 +#define TX_SCCFG_CS_SHIFT (31-7)
24801 +
24802 +/**************************************************************************//**
24803 + @Description TX SA defines
24804 +*//***************************************************************************/
24805 +
24806 +/* masks */
24807 +#define TX_SACFG_ACTIVE 0x80000000
24808 +
24809 +
24810 +typedef struct
24811 +{
24812 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24813 + t_Handle h_SrcHandle;
24814 +} t_FmMacsecIntrSrc;
24815 +
24816 +typedef struct
24817 +{
24818 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
24819 + bool invalidTagsDeliverUncontrolled;
24820 + bool changedTextWithNoEncryptDeliverUncontrolled;
24821 + bool onlyScbIsSetDeliverUncontrolled;
24822 + bool encryptWithNoChangedTextDiscardUncontrolled;
24823 + e_FmMacsecUntagFrameTreatment untagTreatMode;
24824 + uint32_t pnExhThr;
24825 + bool keysUnreadable;
24826 + bool byPassMode;
24827 + bool reservedSc0;
24828 + uint32_t sectagOverhead;
24829 + uint32_t mflSubtract;
24830 +} t_FmMacsecDriverParam;
24831 +
24832 +typedef struct
24833 +{
24834 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
24835 + t_Handle h_Fm;
24836 + t_FmMacsecRegs *p_FmMacsecRegs;
24837 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
24838 + char fmMacsecModuleName[MODULE_NAME_SIZE];
24839 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
24840 + uint32_t events;
24841 + uint32_t exceptions;
24842 + uint32_t userExceptions;
24843 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
24844 + t_Handle h_App; /**< A handle to an application layer object; This handle will
24845 + be passed by the driver upon calling the above callbacks */
24846 + bool rxScTable[NUM_OF_RX_SC];
24847 + uint32_t numRxScAvailable;
24848 + bool txScTable[NUM_OF_TX_SC];
24849 + uint32_t numTxScAvailable;
24850 + t_Handle rxScSpinLock;
24851 + t_Handle txScSpinLock;
24852 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
24853 +} t_FmMacsec;
24854 +
24855 +
24856 +#endif /* __FM_MACSEC_MASTER_H */
24857 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24858 new file mode 100644
24859 index 00000000..7c72dc98
24860 --- /dev/null
24861 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24862 @@ -0,0 +1,883 @@
24863 +/*
24864 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24865 + *
24866 + * Redistribution and use in source and binary forms, with or without
24867 + * modification, are permitted provided that the following conditions are met:
24868 + * * Redistributions of source code must retain the above copyright
24869 + * notice, this list of conditions and the following disclaimer.
24870 + * * Redistributions in binary form must reproduce the above copyright
24871 + * notice, this list of conditions and the following disclaimer in the
24872 + * documentation and/or other materials provided with the distribution.
24873 + * * Neither the name of Freescale Semiconductor nor the
24874 + * names of its contributors may be used to endorse or promote products
24875 + * derived from this software without specific prior written permission.
24876 + *
24877 + *
24878 + * ALTERNATIVELY, this software may be distributed under the terms of the
24879 + * GNU General Public License ("GPL") as published by the Free Software
24880 + * Foundation, either version 2 of that License or (at your option) any
24881 + * later version.
24882 + *
24883 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24884 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24885 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24886 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24887 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24888 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24889 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24890 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24891 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24892 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24893 + */
24894 +
24895 +/******************************************************************************
24896 + @File fm_macsec_secy.c
24897 +
24898 + @Description FM MACSEC SECY driver routines implementation.
24899 +*//***************************************************************************/
24900 +
24901 +#include "std_ext.h"
24902 +#include "error_ext.h"
24903 +#include "xx_ext.h"
24904 +#include "string_ext.h"
24905 +#include "sprint_ext.h"
24906 +
24907 +#include "fm_macsec_secy.h"
24908 +
24909 +
24910 +/****************************************/
24911 +/* static functions */
24912 +/****************************************/
24913 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24914 +{
24915 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24916 +
24917 + UNUSED(id);
24918 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24919 +
24920 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
24921 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
24922 +}
24923 +
24924 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24925 +{
24926 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24927 +
24928 + UNUSED(id);
24929 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24930 +
24931 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
24932 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
24933 +}
24934 +
24935 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
24936 +{
24937 + if (!p_FmMacsecSecY->f_Exception)
24938 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
24939 +
24940 + if (!p_FmMacsecSecY->f_Event)
24941 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
24942 +
24943 + if (!p_FmMacsecSecY->numOfRxSc)
24944 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
24945 +
24946 +
24947 + return E_OK;
24948 +}
24949 +
24950 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
24951 + macsecSCI_t sci,
24952 + e_FmMacsecSecYCipherSuite cipherSuite,
24953 + e_ScType type)
24954 +{
24955 + t_SecYSc *p_ScTable;
24956 + void *p_Params;
24957 + uint32_t numOfSc,i;
24958 + t_Error err = E_OK;
24959 + t_RxScParams rxScParams;
24960 + t_TxScParams txScParams;
24961 +
24962 + ASSERT_COND(p_FmMacsecSecY);
24963 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24964 +
24965 + if (type == e_SC_RX)
24966 + {
24967 + memset(&rxScParams, 0, sizeof(rxScParams));
24968 + i = (NUM_OF_RX_SC - 1);
24969 + p_ScTable = p_FmMacsecSecY->p_RxSc;
24970 + numOfSc = p_FmMacsecSecY->numOfRxSc;
24971 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24972 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
24973 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
24974 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
24975 + rxScParams.cipherSuite = cipherSuite;
24976 + p_Params = &rxScParams;
24977 + }
24978 + else
24979 + {
24980 + memset(&txScParams, 0, sizeof(txScParams));
24981 + i = (NUM_OF_TX_SC - 1);
24982 + p_ScTable = p_FmMacsecSecY->p_TxSc;
24983 + numOfSc = p_FmMacsecSecY->numOfTxSc;
24984 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
24985 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
24986 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
24987 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24988 + txScParams.cipherSuite = cipherSuite;
24989 + p_Params = &txScParams;
24990 + }
24991 +
24992 + for (i=0;i<numOfSc;i++)
24993 + if (!p_ScTable[i].inUse)
24994 + break;
24995 + if (i == numOfSc)
24996 + {
24997 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
24998 + return NULL;
24999 + }
25000 +
25001 + if (type == e_SC_RX)
25002 + {
25003 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
25004 + ((t_RxScParams *)p_Params)->sci = sci;
25005 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
25006 + {
25007 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25008 + return NULL;
25009 + }
25010 + }
25011 + else
25012 + {
25013 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
25014 + ((t_TxScParams *)p_Params)->sci = sci;
25015 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
25016 + {
25017 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25018 + return NULL;
25019 + }
25020 + }
25021 +
25022 + p_ScTable[i].inUse = TRUE;
25023 + return &p_ScTable[i];
25024 +}
25025 +
25026 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
25027 +{
25028 + t_Error err = E_OK;
25029 +
25030 + ASSERT_COND(p_FmMacsecSecY);
25031 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25032 + ASSERT_COND(p_FmSecYSc);
25033 +
25034 + if (type == e_SC_RX)
25035 + {
25036 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25037 + RETURN_ERROR(MINOR, err, NO_MSG);
25038 + }
25039 + else
25040 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25041 + RETURN_ERROR(MINOR, err, NO_MSG);
25042 +
25043 + p_FmSecYSc->inUse = FALSE;
25044 +
25045 + return err;
25046 +}
25047 +
25048 +/****************************************/
25049 +/* API Init unit functions */
25050 +/****************************************/
25051 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
25052 +{
25053 + t_FmMacsecSecY *p_FmMacsecSecY;
25054 +
25055 + /* Allocate FM MACSEC structure */
25056 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
25057 + if (!p_FmMacsecSecY)
25058 + {
25059 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
25060 + return NULL;
25061 + }
25062 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
25063 +
25064 + /* Allocate the FM MACSEC driver's parameters structure */
25065 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
25066 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
25067 + {
25068 + XX_Free(p_FmMacsecSecY);
25069 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
25070 + return NULL;
25071 + }
25072 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
25073 +
25074 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
25075 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
25076 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
25077 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
25078 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
25079 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
25080 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
25081 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
25082 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
25083 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
25084 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
25085 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
25086 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
25087 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
25088 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
25089 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
25090 + p_FmMacsecSecY->events = DEFAULT_events;
25091 +
25092 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
25093 + &p_FmMacsecSecYParam->txScParams,
25094 + sizeof(t_FmMacsecSecYSCParams));
25095 + return p_FmMacsecSecY;
25096 +}
25097 +
25098 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
25099 +{
25100 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25101 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
25102 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
25103 + t_Error err;
25104 +
25105 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25106 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
25107 +
25108 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
25109 +
25110 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
25111 +
25112 + if ((p_FmMacsecSecY->isPointToPoint) &&
25113 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
25114 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
25115 +
25116 + /* Rx Sc Allocation */
25117 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25118 + if (!p_FmMacsecSecY->p_RxSc)
25119 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25120 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25121 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25122 + {
25123 + if (p_FmMacsecSecY->p_TxSc)
25124 + XX_Free(p_FmMacsecSecY->p_TxSc);
25125 + if (p_FmMacsecSecY->p_RxSc)
25126 + XX_Free(p_FmMacsecSecY->p_RxSc);
25127 + return ERROR_CODE(err);
25128 + }
25129 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25130 + {
25131 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
25132 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
25133 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25134 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25135 + }
25136 +
25137 + /* Tx Sc Allocation */
25138 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25139 + if (!p_FmMacsecSecY->p_TxSc)
25140 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25141 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25142 +
25143 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25144 + {
25145 + if (p_FmMacsecSecY->p_TxSc)
25146 + XX_Free(p_FmMacsecSecY->p_TxSc);
25147 + if (p_FmMacsecSecY->p_RxSc)
25148 + XX_Free(p_FmMacsecSecY->p_RxSc);
25149 + return ERROR_CODE(err);
25150 + }
25151 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
25152 + {
25153 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
25154 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
25155 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25156 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25157 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25158 + e_FM_MACSEC_MOD_SC_TX,
25159 + (uint8_t)txScIds[i],
25160 + e_FM_INTR_TYPE_ERR,
25161 + FmMacsecSecYExceptionsIsr,
25162 + p_FmMacsecSecY);
25163 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25164 + e_FM_MACSEC_MOD_SC_TX,
25165 + (uint8_t)txScIds[i],
25166 + e_FM_INTR_TYPE_NORMAL,
25167 + FmMacsecSecYEventsIsr,
25168 + p_FmMacsecSecY);
25169 +
25170 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25171 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
25172 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25173 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25174 + }
25175 +
25176 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25177 + p_FmMacsecSecYDriverParam->txScParams.sci,
25178 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25179 + e_SC_TX);
25180 + XX_Free(p_FmMacsecSecYDriverParam);
25181 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25182 +
25183 + return E_OK;
25184 +}
25185 +
25186 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25187 +{
25188 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25189 + t_Error err = E_OK;
25190 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25191 +
25192 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25193 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25194 +
25195 + if (p_FmMacsecSecY->isPointToPoint)
25196 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25197 + if (p_FmMacsecSecY->p_RxSc)
25198 + {
25199 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25200 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25201 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25202 + return ERROR_CODE(err);
25203 + XX_Free(p_FmMacsecSecY->p_RxSc);
25204 + }
25205 + if (p_FmMacsecSecY->p_TxSc)
25206 + {
25207 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25208 +
25209 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25210 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25211 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25212 + e_FM_MACSEC_MOD_SC_TX,
25213 + (uint8_t)txScIds[i],
25214 + e_FM_INTR_TYPE_ERR);
25215 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25216 + e_FM_MACSEC_MOD_SC_TX,
25217 + (uint8_t)txScIds[i],
25218 + e_FM_INTR_TYPE_NORMAL);
25219 +
25220 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25221 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25222 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25223 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25224 + }
25225 +
25226 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25227 + return ERROR_CODE(err);
25228 + XX_Free(p_FmMacsecSecY->p_TxSc);
25229 + }
25230 +
25231 + XX_Free(p_FmMacsecSecY);
25232 +
25233 + return err;
25234 +}
25235 +
25236 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25237 +{
25238 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25239 +
25240 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25241 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25242 +
25243 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25244 +
25245 + return E_OK;
25246 +}
25247 +
25248 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25249 +{
25250 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25251 +
25252 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25253 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25254 +
25255 + p_FmMacsecSecY->protectFrames = protectFrames;
25256 +
25257 + return E_OK;
25258 +}
25259 +
25260 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25261 +{
25262 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25263 +
25264 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25265 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25266 +
25267 + p_FmMacsecSecY->replayProtect = replayProtect;
25268 + p_FmMacsecSecY->replayWindow = replayWindow;
25269 +
25270 + return E_OK;
25271 +}
25272 +
25273 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25274 +{
25275 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25276 +
25277 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25278 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25279 +
25280 + p_FmMacsecSecY->validateFrames = validateFrames;
25281 +
25282 + return E_OK;
25283 +}
25284 +
25285 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25286 +{
25287 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25288 +
25289 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25290 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25291 +
25292 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25293 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25294 +
25295 + return E_OK;
25296 +}
25297 +
25298 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25299 +{
25300 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25301 +
25302 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25303 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25304 +
25305 + p_FmMacsecSecY->numOfRxSc = 1;
25306 + p_FmMacsecSecY->isPointToPoint = TRUE;
25307 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25308 +
25309 + return E_OK;
25310 +}
25311 +
25312 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25313 +{
25314 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25315 + uint32_t bitMask = 0;
25316 +
25317 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25318 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25319 +
25320 + GET_EXCEPTION_FLAG(bitMask, exception);
25321 + if (bitMask)
25322 + {
25323 + if (enable)
25324 + p_FmMacsecSecY->exceptions |= bitMask;
25325 + else
25326 + p_FmMacsecSecY->exceptions &= ~bitMask;
25327 + }
25328 + else
25329 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25330 +
25331 + return E_OK;
25332 +}
25333 +
25334 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25335 +{
25336 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25337 + uint32_t bitMask = 0;
25338 +
25339 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25340 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25341 +
25342 + GET_EVENT_FLAG(bitMask, event);
25343 + if (bitMask)
25344 + {
25345 + if (enable)
25346 + p_FmMacsecSecY->events |= bitMask;
25347 + else
25348 + p_FmMacsecSecY->events &= ~bitMask;
25349 + }
25350 + else
25351 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25352 +
25353 + return E_OK;
25354 +}
25355 +
25356 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25357 +{
25358 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25359 +
25360 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25361 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25362 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25363 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25364 +
25365 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25366 +}
25367 +
25368 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25369 +{
25370 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25371 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25372 +
25373 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25374 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25375 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25376 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25377 +
25378 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25379 +}
25380 +
25381 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25382 +{
25383 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25384 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25385 + t_Error err = E_OK;
25386 +
25387 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25388 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25389 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25390 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25391 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25392 +
25393 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25394 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25395 +
25396 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25397 + RETURN_ERROR(MINOR, err, NO_MSG);
25398 +
25399 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25400 + return err;
25401 +}
25402 +
25403 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25404 +{
25405 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25406 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25407 + t_Error err = E_OK;
25408 +
25409 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25410 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25411 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25412 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25413 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25414 +
25415 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25416 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25417 +
25418 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25419 + RETURN_ERROR(MINOR, err, NO_MSG);
25420 +
25421 + p_FmSecYSc->numOfSa--;
25422 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25423 + /* TODO - check if statistics need to be read*/
25424 + return err;
25425 +}
25426 +
25427 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25428 +{
25429 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25430 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25431 + t_Error err = E_OK;
25432 +
25433 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25434 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25435 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25436 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25437 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25438 +
25439 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25440 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25441 +
25442 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25443 + RETURN_ERROR(MINOR, err, NO_MSG);
25444 +
25445 + p_FmSecYSc->sa[an].active = TRUE;
25446 + return err;
25447 +}
25448 +
25449 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25450 +{
25451 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25452 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25453 + t_Error err = E_OK;
25454 +
25455 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25456 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25457 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25458 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25459 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25460 +
25461 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25462 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25463 +
25464 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25465 + RETURN_ERROR(MINOR, err, NO_MSG);
25466 +
25467 + p_FmSecYSc->sa[an].active = FALSE;
25468 + return err;
25469 +}
25470 +
25471 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25472 +{
25473 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25474 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25475 + t_Error err = E_OK;
25476 +
25477 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25478 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25479 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25480 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25481 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25482 +
25483 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25484 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25485 +
25486 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25487 + RETURN_ERROR(MINOR, err, NO_MSG);
25488 +
25489 + return err;
25490 +}
25491 +
25492 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25493 +{
25494 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25495 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25496 + t_Error err = E_OK;
25497 +
25498 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25499 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25500 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25501 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25502 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25503 +
25504 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25505 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25506 +
25507 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25508 + RETURN_ERROR(MINOR, err, NO_MSG);
25509 +
25510 + return err;
25511 +}
25512 +
25513 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25514 +{
25515 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25516 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25517 + t_Error err = E_OK;
25518 +
25519 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25520 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25521 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25522 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25523 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25524 +
25525 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25526 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25527 +
25528 + if (p_FmSecYSc->sa[an].active)
25529 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25530 + RETURN_ERROR(MINOR, err, NO_MSG);
25531 +
25532 + /* TODO - statistics should be read */
25533 +
25534 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25535 + RETURN_ERROR(MINOR, err, NO_MSG);
25536 +
25537 + if (p_FmSecYSc->sa[an].active)
25538 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25539 + RETURN_ERROR(MINOR, err, NO_MSG);
25540 + return err;
25541 +}
25542 +
25543 +
25544 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25545 +{
25546 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25547 + t_SecYSc *p_FmSecYSc;
25548 + t_Error err = E_OK;
25549 +
25550 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25551 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25552 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25553 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25554 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25555 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25556 +
25557 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25558 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25559 +
25560 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25561 + RETURN_ERROR(MINOR, err, NO_MSG);
25562 +
25563 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25564 + return err;
25565 +}
25566 +
25567 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25568 +{
25569 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25570 + t_SecYSc *p_FmSecYSc;
25571 + t_Error err = E_OK;
25572 +
25573 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25574 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25575 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25576 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25577 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25578 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25579 +
25580 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25581 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25582 +
25583 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25584 + RETURN_ERROR(MINOR, err, NO_MSG);
25585 +
25586 + p_FmSecYSc->numOfSa--;
25587 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25588 + /* TODO - check if statistics need to be read*/
25589 + return err;
25590 +}
25591 +
25592 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25593 +{
25594 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25595 + t_SecYSc *p_FmSecYSc;
25596 + macsecAN_t currentAn;
25597 + t_Error err = E_OK;
25598 +
25599 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25600 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25601 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25602 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25603 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25604 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25605 +
25606 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25607 + p_FmSecYSc->scId,
25608 + &currentAn)) != E_OK)
25609 + RETURN_ERROR(MINOR, err, NO_MSG);
25610 +
25611 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25612 + p_FmSecYSc->scId,
25613 + p_FmSecYSc->sa[nextActiveAn].saId,
25614 + nextActiveAn)) != E_OK)
25615 + RETURN_ERROR(MINOR, err, NO_MSG);
25616 +
25617 + /* TODO - statistics should be read */
25618 +
25619 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25620 + RETURN_ERROR(MINOR, err, NO_MSG);
25621 +
25622 + return err;
25623 +}
25624 +
25625 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25626 +{
25627 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25628 + t_SecYSc *p_FmSecYSc;
25629 + t_Error err = E_OK;
25630 +
25631 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25632 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25633 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25634 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25635 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25636 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25637 +
25638 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25639 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25640 +
25641 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25642 + p_FmSecYSc->scId,
25643 + p_FmSecYSc->sa[an].saId,
25644 + an)) != E_OK)
25645 + RETURN_ERROR(MINOR, err, NO_MSG);
25646 +
25647 + return err;
25648 +}
25649 +
25650 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25651 +{
25652 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25653 + t_SecYSc *p_FmSecYSc;
25654 + t_Error err = E_OK;
25655 +
25656 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25657 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25658 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25659 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25660 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25661 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25662 +
25663 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25664 + p_FmSecYSc->scId,
25665 + p_An)) != E_OK)
25666 + RETURN_ERROR(MINOR, err, NO_MSG);
25667 +
25668 + return err;
25669 +}
25670 +
25671 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25672 +{
25673 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25674 + t_Error err = E_OK;
25675 +
25676 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25677 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25678 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25679 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25680 +#ifdef DISABLE_SANITY_CHECKS
25681 + UNUSED(h_FmMacsecSecY);
25682 +#endif /* DISABLE_SANITY_CHECKS */
25683 +
25684 + *p_ScPhysId = p_FmSecYSc->scId;
25685 + return err;
25686 +}
25687 +
25688 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25689 +{
25690 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25691 + t_SecYSc *p_FmSecYSc;
25692 + t_Error err = E_OK;
25693 +
25694 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25695 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25696 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25697 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25698 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25699 +
25700 + *p_ScPhysId = p_FmSecYSc->scId;
25701 + return err;
25702 +}
25703 +
25704 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25705 +{
25706 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25707 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25708 +}
25709 +
25710 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25711 +{
25712 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25713 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25714 +}
25715 +
25716 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25717 +{
25718 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25719 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25720 +}
25721 +
25722 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25723 +{
25724 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25725 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25726 +}
25727 +
25728 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25729 +{
25730 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25731 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25732 +}
25733 +
25734 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25735 +{
25736 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25737 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25738 +}
25739 +
25740 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25741 +{
25742 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25743 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25744 +}
25745 +
25746 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25747 new file mode 100644
25748 index 00000000..0cf624e6
25749 --- /dev/null
25750 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25751 @@ -0,0 +1,144 @@
25752 +/*
25753 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25754 + *
25755 + * Redistribution and use in source and binary forms, with or without
25756 + * modification, are permitted provided that the following conditions are met:
25757 + * * Redistributions of source code must retain the above copyright
25758 + * notice, this list of conditions and the following disclaimer.
25759 + * * Redistributions in binary form must reproduce the above copyright
25760 + * notice, this list of conditions and the following disclaimer in the
25761 + * documentation and/or other materials provided with the distribution.
25762 + * * Neither the name of Freescale Semiconductor nor the
25763 + * names of its contributors may be used to endorse or promote products
25764 + * derived from this software without specific prior written permission.
25765 + *
25766 + *
25767 + * ALTERNATIVELY, this software may be distributed under the terms of the
25768 + * GNU General Public License ("GPL") as published by the Free Software
25769 + * Foundation, either version 2 of that License or (at your option) any
25770 + * later version.
25771 + *
25772 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25773 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25774 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25775 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25776 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25777 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25778 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25779 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25780 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25781 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25782 + */
25783 +
25784 +/******************************************************************************
25785 + @File fm_macsec_secy.h
25786 +
25787 + @Description FM MACSEC SecY internal structures and definitions.
25788 +*//***************************************************************************/
25789 +#ifndef __FM_MACSEC_SECY_H
25790 +#define __FM_MACSEC_SECY_H
25791 +
25792 +#include "error_ext.h"
25793 +#include "std_ext.h"
25794 +
25795 +#include "fm_macsec.h"
25796 +
25797 +
25798 +/**************************************************************************//**
25799 + @Description Exceptions
25800 +*//***************************************************************************/
25801 +
25802 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25803 +
25804 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25805 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25806 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25807 + default: bitMask = 0;break;}
25808 +
25809 +/**************************************************************************//**
25810 + @Description Events
25811 +*//***************************************************************************/
25812 +
25813 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25814 +
25815 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25816 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25817 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25818 + default: bitMask = 0;break;}
25819 +
25820 +/**************************************************************************//**
25821 + @Description Defaults
25822 +*//***************************************************************************/
25823 +
25824 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25825 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
25826 +#define DEFAULT_numOfTxSc 1
25827 +#define DEFAULT_confidentialityEnable FALSE
25828 +#define DEFAULT_confidentialityOffset 0
25829 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
25830 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
25831 +#define DEFAULT_replayEnable FALSE
25832 +#define DEFAULT_replayWindow 0
25833 +#define DEFAULT_protectFrames TRUE
25834 +#define DEFAULT_ptp FALSE
25835 +
25836 +/**************************************************************************//**
25837 + @Description General defines
25838 +*//***************************************************************************/
25839 +
25840 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
25841 +
25842 +
25843 +typedef struct {
25844 + e_ScSaId saId;
25845 + bool active;
25846 + union {
25847 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
25848 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
25849 + };
25850 +} t_SecYSa;
25851 +
25852 +typedef struct {
25853 + bool inUse;
25854 + uint32_t scId;
25855 + e_ScType type;
25856 + uint8_t numOfSa;
25857 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
25858 + union {
25859 + t_FmMacsecSecYRxScStatistics rxScStatistics;
25860 + t_FmMacsecSecYTxScStatistics txScStatistics;
25861 + };
25862 +} t_SecYSc;
25863 +
25864 +typedef struct {
25865 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
25866 +} t_FmMacsecSecYDriverParam;
25867 +
25868 +typedef struct {
25869 + t_Handle h_FmMacsec;
25870 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
25871 + FALSE - no confidentiality protection, only integrity protection*/
25872 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
25873 + common values are 0, 30, and 50 */
25874 + bool replayProtect; /**< replay protection function mode */
25875 + uint32_t replayWindow; /**< the size of the replay window */
25876 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
25877 + e_FmMacsecSciInsertionMode sciInsertionMode;
25878 + bool protectFrames;
25879 + bool isPointToPoint;
25880 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
25881 + uint32_t numOfRxSc; /**< Number of receive channels */
25882 + uint32_t numOfTxSc; /**< Number of transmit channels */
25883 + t_SecYSc *p_RxSc;
25884 + t_SecYSc *p_TxSc;
25885 + uint32_t events;
25886 + uint32_t exceptions;
25887 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
25888 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
25889 + t_Handle h_App;
25890 + t_FmMacsecSecYStatistics statistics;
25891 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
25892 +} t_FmMacsecSecY;
25893 +
25894 +
25895 +#endif /* __FM_MACSEC_SECY_H */
25896 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
25897 new file mode 100644
25898 index 00000000..619f6608
25899 --- /dev/null
25900 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
25901 @@ -0,0 +1,23 @@
25902 +#
25903 +# Makefile for the Freescale Ethernet controllers
25904 +#
25905 +ccflags-y += -DVERSION=\"\"
25906 +#
25907 +#Include netcomm SW specific definitions
25908 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25909 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25910 +
25911 +ccflags-y += -I$(NCSW_FM_INC)
25912 +
25913 +
25914 +obj-y += fsl-ncsw-PFM1.o
25915 +
25916 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
25917 +
25918 +obj-y += MAC/
25919 +obj-y += Pcd/
25920 +obj-y += SP/
25921 +obj-y += Port/
25922 +obj-y += HC/
25923 +obj-y += Rtc/
25924 +obj-y += MACSEC/
25925 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
25926 new file mode 100644
25927 index 00000000..62fbd73c
25928 --- /dev/null
25929 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
25930 @@ -0,0 +1,26 @@
25931 +#
25932 +# Makefile for the Freescale Ethernet controllers
25933 +#
25934 +ccflags-y += -DVERSION=\"\"
25935 +#
25936 +#Include netcomm SW specific definitions
25937 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25938 +
25939 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25940 +
25941 +ccflags-y += -I$(NCSW_FM_INC)
25942 +
25943 +obj-y += fsl-ncsw-Pcd.o
25944 +
25945 +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
25946 +
25947 +ifeq ($(CONFIG_FMAN_V3H),y)
25948 +fsl-ncsw-Pcd-objs += fm_replic.o
25949 +endif
25950 +ifeq ($(CONFIG_FMAN_V3L),y)
25951 +fsl-ncsw-Pcd-objs += fm_replic.o
25952 +endif
25953 +ifeq ($(CONFIG_FMAN_ARM),y)
25954 +fsl-ncsw-Pcd-objs += fm_replic.o
25955 +endif
25956 +
25957 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
25958 new file mode 100644
25959 index 00000000..335ee681
25960 --- /dev/null
25961 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
25962 @@ -0,0 +1,360 @@
25963 +/*
25964 + * Copyright 2008-2012 Freescale Semiconductor Inc.
25965 + *
25966 + * Redistribution and use in source and binary forms, with or without
25967 + * modification, are permitted provided that the following conditions are met:
25968 + * * Redistributions of source code must retain the above copyright
25969 + * notice, this list of conditions and the following disclaimer.
25970 + * * Redistributions in binary form must reproduce the above copyright
25971 + * notice, this list of conditions and the following disclaimer in the
25972 + * documentation and/or other materials provided with the distribution.
25973 + * * Neither the name of Freescale Semiconductor nor the
25974 + * names of its contributors may be used to endorse or promote products
25975 + * derived from this software without specific prior written permission.
25976 + *
25977 + *
25978 + * ALTERNATIVELY, this software may be distributed under the terms of the
25979 + * GNU General Public License ("GPL") as published by the Free Software
25980 + * Foundation, either version 2 of that License or (at your option) any
25981 + * later version.
25982 + *
25983 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25984 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25985 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25986 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25987 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25988 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25989 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25990 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25991 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25992 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25993 + */
25994 +
25995 +
25996 + /**************************************************************************//**
25997 + @File crc64.h
25998 +
25999 + @Description brief This file contains the CRC64 Table, and __inline__
26000 + functions used for calculating crc.
26001 +*//***************************************************************************/
26002 +#ifndef __CRC64_H
26003 +#define __CRC64_H
26004 +
26005 +#include "std_ext.h"
26006 +
26007 +
26008 +#define BITS_PER_BYTE 8
26009 +
26010 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
26011 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
26012 +
26013 +#define CRC64_BYTE_MASK 0xFF
26014 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
26015 +#define CRC64_ODD_MASK 1
26016 +
26017 +
26018 +/**
26019 + \brief '64 bit crc' Table
26020 + */
26021 +struct crc64_t {
26022 + uint64_t initial; /**< Initial seed */
26023 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
26024 +};
26025 +
26026 +
26027 +static struct crc64_t CRC64_ECMA_182 = {
26028 + CRC64_DEFAULT_INITVAL,
26029 + {
26030 + 0x0000000000000000ULL,
26031 + 0xb32e4cbe03a75f6fULL,
26032 + 0xf4843657a840a05bULL,
26033 + 0x47aa7ae9abe7ff34ULL,
26034 + 0x7bd0c384ff8f5e33ULL,
26035 + 0xc8fe8f3afc28015cULL,
26036 + 0x8f54f5d357cffe68ULL,
26037 + 0x3c7ab96d5468a107ULL,
26038 + 0xf7a18709ff1ebc66ULL,
26039 + 0x448fcbb7fcb9e309ULL,
26040 + 0x0325b15e575e1c3dULL,
26041 + 0xb00bfde054f94352ULL,
26042 + 0x8c71448d0091e255ULL,
26043 + 0x3f5f08330336bd3aULL,
26044 + 0x78f572daa8d1420eULL,
26045 + 0xcbdb3e64ab761d61ULL,
26046 + 0x7d9ba13851336649ULL,
26047 + 0xceb5ed8652943926ULL,
26048 + 0x891f976ff973c612ULL,
26049 + 0x3a31dbd1fad4997dULL,
26050 + 0x064b62bcaebc387aULL,
26051 + 0xb5652e02ad1b6715ULL,
26052 + 0xf2cf54eb06fc9821ULL,
26053 + 0x41e11855055bc74eULL,
26054 + 0x8a3a2631ae2dda2fULL,
26055 + 0x39146a8fad8a8540ULL,
26056 + 0x7ebe1066066d7a74ULL,
26057 + 0xcd905cd805ca251bULL,
26058 + 0xf1eae5b551a2841cULL,
26059 + 0x42c4a90b5205db73ULL,
26060 + 0x056ed3e2f9e22447ULL,
26061 + 0xb6409f5cfa457b28ULL,
26062 + 0xfb374270a266cc92ULL,
26063 + 0x48190ecea1c193fdULL,
26064 + 0x0fb374270a266cc9ULL,
26065 + 0xbc9d3899098133a6ULL,
26066 + 0x80e781f45de992a1ULL,
26067 + 0x33c9cd4a5e4ecdceULL,
26068 + 0x7463b7a3f5a932faULL,
26069 + 0xc74dfb1df60e6d95ULL,
26070 + 0x0c96c5795d7870f4ULL,
26071 + 0xbfb889c75edf2f9bULL,
26072 + 0xf812f32ef538d0afULL,
26073 + 0x4b3cbf90f69f8fc0ULL,
26074 + 0x774606fda2f72ec7ULL,
26075 + 0xc4684a43a15071a8ULL,
26076 + 0x83c230aa0ab78e9cULL,
26077 + 0x30ec7c140910d1f3ULL,
26078 + 0x86ace348f355aadbULL,
26079 + 0x3582aff6f0f2f5b4ULL,
26080 + 0x7228d51f5b150a80ULL,
26081 + 0xc10699a158b255efULL,
26082 + 0xfd7c20cc0cdaf4e8ULL,
26083 + 0x4e526c720f7dab87ULL,
26084 + 0x09f8169ba49a54b3ULL,
26085 + 0xbad65a25a73d0bdcULL,
26086 + 0x710d64410c4b16bdULL,
26087 + 0xc22328ff0fec49d2ULL,
26088 + 0x85895216a40bb6e6ULL,
26089 + 0x36a71ea8a7ace989ULL,
26090 + 0x0adda7c5f3c4488eULL,
26091 + 0xb9f3eb7bf06317e1ULL,
26092 + 0xfe5991925b84e8d5ULL,
26093 + 0x4d77dd2c5823b7baULL,
26094 + 0x64b62bcaebc387a1ULL,
26095 + 0xd7986774e864d8ceULL,
26096 + 0x90321d9d438327faULL,
26097 + 0x231c512340247895ULL,
26098 + 0x1f66e84e144cd992ULL,
26099 + 0xac48a4f017eb86fdULL,
26100 + 0xebe2de19bc0c79c9ULL,
26101 + 0x58cc92a7bfab26a6ULL,
26102 + 0x9317acc314dd3bc7ULL,
26103 + 0x2039e07d177a64a8ULL,
26104 + 0x67939a94bc9d9b9cULL,
26105 + 0xd4bdd62abf3ac4f3ULL,
26106 + 0xe8c76f47eb5265f4ULL,
26107 + 0x5be923f9e8f53a9bULL,
26108 + 0x1c4359104312c5afULL,
26109 + 0xaf6d15ae40b59ac0ULL,
26110 + 0x192d8af2baf0e1e8ULL,
26111 + 0xaa03c64cb957be87ULL,
26112 + 0xeda9bca512b041b3ULL,
26113 + 0x5e87f01b11171edcULL,
26114 + 0x62fd4976457fbfdbULL,
26115 + 0xd1d305c846d8e0b4ULL,
26116 + 0x96797f21ed3f1f80ULL,
26117 + 0x2557339fee9840efULL,
26118 + 0xee8c0dfb45ee5d8eULL,
26119 + 0x5da24145464902e1ULL,
26120 + 0x1a083bacedaefdd5ULL,
26121 + 0xa9267712ee09a2baULL,
26122 + 0x955cce7fba6103bdULL,
26123 + 0x267282c1b9c65cd2ULL,
26124 + 0x61d8f8281221a3e6ULL,
26125 + 0xd2f6b4961186fc89ULL,
26126 + 0x9f8169ba49a54b33ULL,
26127 + 0x2caf25044a02145cULL,
26128 + 0x6b055fede1e5eb68ULL,
26129 + 0xd82b1353e242b407ULL,
26130 + 0xe451aa3eb62a1500ULL,
26131 + 0x577fe680b58d4a6fULL,
26132 + 0x10d59c691e6ab55bULL,
26133 + 0xa3fbd0d71dcdea34ULL,
26134 + 0x6820eeb3b6bbf755ULL,
26135 + 0xdb0ea20db51ca83aULL,
26136 + 0x9ca4d8e41efb570eULL,
26137 + 0x2f8a945a1d5c0861ULL,
26138 + 0x13f02d374934a966ULL,
26139 + 0xa0de61894a93f609ULL,
26140 + 0xe7741b60e174093dULL,
26141 + 0x545a57dee2d35652ULL,
26142 + 0xe21ac88218962d7aULL,
26143 + 0x5134843c1b317215ULL,
26144 + 0x169efed5b0d68d21ULL,
26145 + 0xa5b0b26bb371d24eULL,
26146 + 0x99ca0b06e7197349ULL,
26147 + 0x2ae447b8e4be2c26ULL,
26148 + 0x6d4e3d514f59d312ULL,
26149 + 0xde6071ef4cfe8c7dULL,
26150 + 0x15bb4f8be788911cULL,
26151 + 0xa6950335e42fce73ULL,
26152 + 0xe13f79dc4fc83147ULL,
26153 + 0x521135624c6f6e28ULL,
26154 + 0x6e6b8c0f1807cf2fULL,
26155 + 0xdd45c0b11ba09040ULL,
26156 + 0x9aefba58b0476f74ULL,
26157 + 0x29c1f6e6b3e0301bULL,
26158 + 0xc96c5795d7870f42ULL,
26159 + 0x7a421b2bd420502dULL,
26160 + 0x3de861c27fc7af19ULL,
26161 + 0x8ec62d7c7c60f076ULL,
26162 + 0xb2bc941128085171ULL,
26163 + 0x0192d8af2baf0e1eULL,
26164 + 0x4638a2468048f12aULL,
26165 + 0xf516eef883efae45ULL,
26166 + 0x3ecdd09c2899b324ULL,
26167 + 0x8de39c222b3eec4bULL,
26168 + 0xca49e6cb80d9137fULL,
26169 + 0x7967aa75837e4c10ULL,
26170 + 0x451d1318d716ed17ULL,
26171 + 0xf6335fa6d4b1b278ULL,
26172 + 0xb199254f7f564d4cULL,
26173 + 0x02b769f17cf11223ULL,
26174 + 0xb4f7f6ad86b4690bULL,
26175 + 0x07d9ba1385133664ULL,
26176 + 0x4073c0fa2ef4c950ULL,
26177 + 0xf35d8c442d53963fULL,
26178 + 0xcf273529793b3738ULL,
26179 + 0x7c0979977a9c6857ULL,
26180 + 0x3ba3037ed17b9763ULL,
26181 + 0x888d4fc0d2dcc80cULL,
26182 + 0x435671a479aad56dULL,
26183 + 0xf0783d1a7a0d8a02ULL,
26184 + 0xb7d247f3d1ea7536ULL,
26185 + 0x04fc0b4dd24d2a59ULL,
26186 + 0x3886b22086258b5eULL,
26187 + 0x8ba8fe9e8582d431ULL,
26188 + 0xcc0284772e652b05ULL,
26189 + 0x7f2cc8c92dc2746aULL,
26190 + 0x325b15e575e1c3d0ULL,
26191 + 0x8175595b76469cbfULL,
26192 + 0xc6df23b2dda1638bULL,
26193 + 0x75f16f0cde063ce4ULL,
26194 + 0x498bd6618a6e9de3ULL,
26195 + 0xfaa59adf89c9c28cULL,
26196 + 0xbd0fe036222e3db8ULL,
26197 + 0x0e21ac88218962d7ULL,
26198 + 0xc5fa92ec8aff7fb6ULL,
26199 + 0x76d4de52895820d9ULL,
26200 + 0x317ea4bb22bfdfedULL,
26201 + 0x8250e80521188082ULL,
26202 + 0xbe2a516875702185ULL,
26203 + 0x0d041dd676d77eeaULL,
26204 + 0x4aae673fdd3081deULL,
26205 + 0xf9802b81de97deb1ULL,
26206 + 0x4fc0b4dd24d2a599ULL,
26207 + 0xfceef8632775faf6ULL,
26208 + 0xbb44828a8c9205c2ULL,
26209 + 0x086ace348f355aadULL,
26210 + 0x34107759db5dfbaaULL,
26211 + 0x873e3be7d8faa4c5ULL,
26212 + 0xc094410e731d5bf1ULL,
26213 + 0x73ba0db070ba049eULL,
26214 + 0xb86133d4dbcc19ffULL,
26215 + 0x0b4f7f6ad86b4690ULL,
26216 + 0x4ce50583738cb9a4ULL,
26217 + 0xffcb493d702be6cbULL,
26218 + 0xc3b1f050244347ccULL,
26219 + 0x709fbcee27e418a3ULL,
26220 + 0x3735c6078c03e797ULL,
26221 + 0x841b8ab98fa4b8f8ULL,
26222 + 0xadda7c5f3c4488e3ULL,
26223 + 0x1ef430e13fe3d78cULL,
26224 + 0x595e4a08940428b8ULL,
26225 + 0xea7006b697a377d7ULL,
26226 + 0xd60abfdbc3cbd6d0ULL,
26227 + 0x6524f365c06c89bfULL,
26228 + 0x228e898c6b8b768bULL,
26229 + 0x91a0c532682c29e4ULL,
26230 + 0x5a7bfb56c35a3485ULL,
26231 + 0xe955b7e8c0fd6beaULL,
26232 + 0xaeffcd016b1a94deULL,
26233 + 0x1dd181bf68bdcbb1ULL,
26234 + 0x21ab38d23cd56ab6ULL,
26235 + 0x9285746c3f7235d9ULL,
26236 + 0xd52f0e859495caedULL,
26237 + 0x6601423b97329582ULL,
26238 + 0xd041dd676d77eeaaULL,
26239 + 0x636f91d96ed0b1c5ULL,
26240 + 0x24c5eb30c5374ef1ULL,
26241 + 0x97eba78ec690119eULL,
26242 + 0xab911ee392f8b099ULL,
26243 + 0x18bf525d915feff6ULL,
26244 + 0x5f1528b43ab810c2ULL,
26245 + 0xec3b640a391f4fadULL,
26246 + 0x27e05a6e926952ccULL,
26247 + 0x94ce16d091ce0da3ULL,
26248 + 0xd3646c393a29f297ULL,
26249 + 0x604a2087398eadf8ULL,
26250 + 0x5c3099ea6de60cffULL,
26251 + 0xef1ed5546e415390ULL,
26252 + 0xa8b4afbdc5a6aca4ULL,
26253 + 0x1b9ae303c601f3cbULL,
26254 + 0x56ed3e2f9e224471ULL,
26255 + 0xe5c372919d851b1eULL,
26256 + 0xa26908783662e42aULL,
26257 + 0x114744c635c5bb45ULL,
26258 + 0x2d3dfdab61ad1a42ULL,
26259 + 0x9e13b115620a452dULL,
26260 + 0xd9b9cbfcc9edba19ULL,
26261 + 0x6a978742ca4ae576ULL,
26262 + 0xa14cb926613cf817ULL,
26263 + 0x1262f598629ba778ULL,
26264 + 0x55c88f71c97c584cULL,
26265 + 0xe6e6c3cfcadb0723ULL,
26266 + 0xda9c7aa29eb3a624ULL,
26267 + 0x69b2361c9d14f94bULL,
26268 + 0x2e184cf536f3067fULL,
26269 + 0x9d36004b35545910ULL,
26270 + 0x2b769f17cf112238ULL,
26271 + 0x9858d3a9ccb67d57ULL,
26272 + 0xdff2a94067518263ULL,
26273 + 0x6cdce5fe64f6dd0cULL,
26274 + 0x50a65c93309e7c0bULL,
26275 + 0xe388102d33392364ULL,
26276 + 0xa4226ac498dedc50ULL,
26277 + 0x170c267a9b79833fULL,
26278 + 0xdcd7181e300f9e5eULL,
26279 + 0x6ff954a033a8c131ULL,
26280 + 0x28532e49984f3e05ULL,
26281 + 0x9b7d62f79be8616aULL,
26282 + 0xa707db9acf80c06dULL,
26283 + 0x14299724cc279f02ULL,
26284 + 0x5383edcd67c06036ULL,
26285 + 0xe0ada17364673f59ULL
26286 + }
26287 +};
26288 +
26289 +
26290 +/**
26291 + \brief Initializes the crc seed
26292 + */
26293 +static __inline__ uint64_t crc64_init(void)
26294 +{
26295 + return CRC64_ECMA_182.initial;
26296 +}
26297 +
26298 +/**
26299 + \brief Computes 64 bit the crc
26300 + \param[in] data Pointer to the Data in the frame
26301 + \param[in] len Length of the Data
26302 + \param[in] crc seed
26303 + \return calculated crc
26304 + */
26305 +static __inline__ uint64_t crc64_compute(void const *data,
26306 + uint32_t len,
26307 + uint64_t seed)
26308 +{
26309 + uint32_t i;
26310 + uint64_t crc = seed;
26311 + uint8_t *bdata = (uint8_t *) data;
26312 +
26313 + for (i = 0; i < len; i++)
26314 + crc =
26315 + CRC64_ECMA_182.
26316 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26317 +
26318 + return crc;
26319 +}
26320 +
26321 +
26322 +#endif /* __CRC64_H */
26323 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26324 new file mode 100644
26325 index 00000000..17c933b4
26326 --- /dev/null
26327 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26328 @@ -0,0 +1,7582 @@
26329 +/*
26330 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26331 + *
26332 + * Redistribution and use in source and binary forms, with or without
26333 + * modification, are permitted provided that the following conditions are met:
26334 + * * Redistributions of source code must retain the above copyright
26335 + * notice, this list of conditions and the following disclaimer.
26336 + * * Redistributions in binary form must reproduce the above copyright
26337 + * notice, this list of conditions and the following disclaimer in the
26338 + * documentation and/or other materials provided with the distribution.
26339 + * * Neither the name of Freescale Semiconductor nor the
26340 + * names of its contributors may be used to endorse or promote products
26341 + * derived from this software without specific prior written permission.
26342 + *
26343 + *
26344 + * ALTERNATIVELY, this software may be distributed under the terms of the
26345 + * GNU General Public License ("GPL") as published by the Free Software
26346 + * Foundation, either version 2 of that License or (at your option) any
26347 + * later version.
26348 + *
26349 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26350 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26351 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26352 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26353 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26354 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26355 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26356 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26357 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26358 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26359 + */
26360 +
26361 +
26362 +/******************************************************************************
26363 + @File fm_cc.c
26364 +
26365 + @Description FM Coarse Classifier implementation
26366 + *//***************************************************************************/
26367 +#include <linux/math64.h>
26368 +#include "std_ext.h"
26369 +#include "error_ext.h"
26370 +#include "string_ext.h"
26371 +#include "debug_ext.h"
26372 +#include "fm_pcd_ext.h"
26373 +#include "fm_muram_ext.h"
26374 +
26375 +#include "fm_common.h"
26376 +#include "fm_pcd.h"
26377 +#include "fm_hc.h"
26378 +#include "fm_cc.h"
26379 +#include "crc64.h"
26380 +
26381 +/****************************************/
26382 +/* static functions */
26383 +/****************************************/
26384 +
26385 +
26386 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26387 +{
26388 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26389 +
26390 + ASSERT_COND(h_FmPcdCcTree);
26391 +
26392 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26393 + return E_OK;
26394 +
26395 + return ERROR_CODE(E_BUSY);
26396 +}
26397 +
26398 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26399 +{
26400 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26401 +
26402 + ASSERT_COND(h_FmPcdCcTree);
26403 +
26404 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26405 +}
26406 +
26407 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26408 +{
26409 + uint32_t intFlags;
26410 +
26411 + ASSERT_COND(p_CcNode);
26412 +
26413 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26414 +
26415 + if (add)
26416 + p_CcNode->owners++;
26417 + else
26418 + {
26419 + ASSERT_COND(p_CcNode->owners);
26420 + p_CcNode->owners--;
26421 + }
26422 +
26423 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26424 +}
26425 +
26426 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26427 +{
26428 + t_FmPcdStatsObj *p_StatsObj = NULL;
26429 + t_List *p_Next;
26430 +
26431 + if (!LIST_IsEmpty(p_List))
26432 + {
26433 + p_Next = LIST_FIRST(p_List);
26434 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26435 + ASSERT_COND(p_StatsObj);
26436 + LIST_DelAndInit(p_Next);
26437 + }
26438 +
26439 + return p_StatsObj;
26440 +}
26441 +
26442 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26443 + t_FmPcdStatsObj *p_StatsObj)
26444 +{
26445 + LIST_AddToTail(&p_StatsObj->node, p_List);
26446 +}
26447 +
26448 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26449 +{
26450 + t_FmPcdStatsObj *p_StatsObj;
26451 +
26452 + while (!LIST_IsEmpty(p_List))
26453 + {
26454 + p_StatsObj = DequeueStatsObj(p_List);
26455 + ASSERT_COND(p_StatsObj);
26456 +
26457 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26458 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26459 +
26460 + XX_Free(p_StatsObj);
26461 + }
26462 +}
26463 +
26464 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26465 +{
26466 + t_FmPcdStatsObj* p_StatsObj;
26467 + t_Handle h_FmMuram;
26468 +
26469 + ASSERT_COND(p_CcNode);
26470 +
26471 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26472 + upon node initialization */
26473 + if (p_CcNode->maxNumOfKeys)
26474 + {
26475 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26476 +
26477 + /* Clean statistics counters & ADs */
26478 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26479 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26480 + }
26481 + else
26482 + {
26483 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26484 + ASSERT_COND(h_FmMuram);
26485 +
26486 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26487 + if (!p_StatsObj)
26488 + {
26489 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26490 + return NULL;
26491 + }
26492 +
26493 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26494 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26495 + if (!p_StatsObj->h_StatsAd)
26496 + {
26497 + XX_Free(p_StatsObj);
26498 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26499 + return NULL;
26500 + }
26501 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26502 +
26503 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26504 + h_FmMuram, p_CcNode->countersArraySize,
26505 + FM_PCD_CC_AD_TABLE_ALIGN);
26506 + if (!p_StatsObj->h_StatsCounters)
26507 + {
26508 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26509 + XX_Free(p_StatsObj);
26510 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26511 + return NULL;
26512 + }
26513 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26514 + }
26515 +
26516 + return p_StatsObj;
26517 +}
26518 +
26519 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26520 +{
26521 + t_Handle h_FmMuram;
26522 +
26523 + ASSERT_COND(p_CcNode);
26524 + ASSERT_COND(p_StatsObj);
26525 +
26526 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26527 + upon node initialization and now will be enqueued back to the list */
26528 + if (p_CcNode->maxNumOfKeys)
26529 + {
26530 + /* Clean statistics counters */
26531 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26532 +
26533 + /* Clean statistics ADs */
26534 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26535 +
26536 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26537 + }
26538 + else
26539 + {
26540 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26541 + ASSERT_COND(h_FmMuram);
26542 +
26543 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26544 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26545 +
26546 + XX_Free(p_StatsObj);
26547 + }
26548 +}
26549 +
26550 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26551 + uint32_t statsCountersAddr)
26552 +{
26553 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26554 +
26555 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26556 +}
26557 +
26558 +
26559 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26560 + t_Handle h_Ad, uint64_t physicalMuramBase)
26561 +{
26562 + t_AdOfTypeStats *p_StatsAd;
26563 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26564 +#if (DPAA_VERSION >= 11)
26565 + uint32_t frameLengthRangesAddr;
26566 +#endif /* (DPAA_VERSION >= 11) */
26567 +
26568 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26569 +
26570 + tmp = FM_PCD_AD_STATS_TYPE;
26571 +
26572 +#if (DPAA_VERSION >= 11)
26573 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26574 + {
26575 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26576 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26577 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26578 + }
26579 +#endif /* (DPAA_VERSION >= 11) */
26580 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26581 +
26582 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26583 + tmp = 0;
26584 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26585 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26586 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26587 +
26588 +#if (DPAA_VERSION >= 11)
26589 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26590 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26591 +#endif /* (DPAA_VERSION >= 11) */
26592 +
26593 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26594 +
26595 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26596 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26597 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26598 +}
26599 +
26600 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26601 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26602 + t_Handle h_FmPcd, t_Handle p_CcNode,
26603 + t_Handle h_Manip, t_Handle h_FrmReplic)
26604 +{
26605 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26606 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26607 + t_Handle h_TmpAd;
26608 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26609 + uint32_t tmpReg32;
26610 + t_Handle p_AdNewPtr = NULL;
26611 +
26612 + UNUSED(h_Manip);
26613 + UNUSED(h_FrmReplic);
26614 +
26615 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26616 + * Case 1: No Manip. The action descriptor is built within the match table.
26617 + * p_AdResult = p_AdNewPtr;
26618 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26619 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26620 + * initialized and returned here.
26621 + * p_AdResult (within the match table) will be initialized after
26622 + * this routine returns and point to the existing AD.
26623 + * Case 3: Manip exists. The action descriptor is built within the match table.
26624 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26625 + */
26626 +
26627 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26628 + * AD will be written into the match table itself (case (1))*/
26629 + p_AdNewPtr = p_AdContLookup;
26630 +
26631 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26632 + if (p_FmPcdCcStatsParams)
26633 + {
26634 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26635 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26636 +
26637 + /* Swapping addresses between statistics Ad and the current lookup AD */
26638 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26639 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26640 + h_Ad = h_TmpAd;
26641 +
26642 + p_AdNewPtr = h_Ad;
26643 + p_AdContLookup = h_Ad;
26644 +
26645 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26646 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26647 + }
26648 +
26649 +#if DPAA_VERSION >= 11
26650 + if (h_Manip && h_FrmReplic)
26651 + FmPcdManipUpdateAdContLookupForCc(
26652 + h_Manip,
26653 + h_Ad,
26654 + &p_AdNewPtr,
26655 + (uint32_t)((XX_VirtToPhys(
26656 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26657 + - p_FmPcd->physicalMuramBase)));
26658 + else
26659 + if (h_FrmReplic)
26660 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26661 + else
26662 +#endif /* (DPAA_VERSION >= 11) */
26663 + if (h_Manip)
26664 + FmPcdManipUpdateAdContLookupForCc(
26665 + h_Manip,
26666 + h_Ad,
26667 + &p_AdNewPtr,
26668 +
26669 +#ifdef FM_CAPWAP_SUPPORT
26670 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26671 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26672 +#else /* not FM_CAPWAP_SUPPORT */
26673 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26674 + - p_FmPcd->physicalMuramBase))
26675 +#endif /* not FM_CAPWAP_SUPPORT */
26676 + );
26677 +
26678 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26679 + if (p_AdNewPtr)
26680 + {
26681 + /* cases (1) & (2) */
26682 + tmpReg32 = 0;
26683 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26684 + tmpReg32 |=
26685 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26686 + 0;
26687 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26688 + - p_FmPcd->physicalMuramBase);
26689 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26690 +
26691 + tmpReg32 = 0;
26692 + tmpReg32 |= p_Node->numOfKeys << 24;
26693 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26694 + tmpReg32 |=
26695 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26696 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26697 + 0;
26698 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26699 +
26700 + tmpReg32 = 0;
26701 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26702 + tmpReg32 |= p_Node->offset << 16;
26703 + tmpReg32 |= p_Node->parseCode;
26704 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26705 +
26706 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26707 + CC_GLBL_MASK_SIZE);
26708 + }
26709 +}
26710 +
26711 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26712 +{
26713 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26714 + uint32_t intFlags;
26715 +
26716 + ASSERT_COND(p_CcNode);
26717 +
26718 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26719 +
26720 + if (!p_CcNode->h_Ad)
26721 + {
26722 + if (p_CcNode->maxNumOfKeys)
26723 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26724 + else
26725 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26726 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26727 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26728 +
26729 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26730 +
26731 + if (!p_CcNode->h_Ad)
26732 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26733 + ("MURAM allocation for CC action descriptor"));
26734 +
26735 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26736 +
26737 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26738 + p_CcNode, NULL, NULL);
26739 + }
26740 + else
26741 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26742 +
26743 + return E_OK;
26744 +}
26745 +
26746 +static t_Error SetRequiredAction1(
26747 + t_Handle h_FmPcd, uint32_t requiredAction,
26748 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26749 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26750 +{
26751 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26752 + uint32_t tmpReg32;
26753 + t_Error err;
26754 + t_FmPcdCcNode *p_CcNode;
26755 + int i = 0;
26756 + uint16_t tmp = 0;
26757 + uint16_t profileId;
26758 + uint8_t relativeSchemeId, physicalSchemeId;
26759 + t_CcNodeInformation ccNodeInfo;
26760 +
26761 + for (i = 0; i < numOfEntries; i++)
26762 + {
26763 + if (i == 0)
26764 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26765 + else
26766 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26767 +
26768 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26769 + {
26770 + case (e_FM_PCD_CC):
26771 + if (requiredAction)
26772 + {
26773 + p_CcNode =
26774 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26775 + ASSERT_COND(p_CcNode);
26776 + if (p_CcNode->shadowAction == requiredAction)
26777 + break;
26778 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26779 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26780 + {
26781 +
26782 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26783 + ccNodeInfo.h_CcNode = h_Tree;
26784 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26785 + &ccNodeInfo, NULL);
26786 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26787 + UPDATE_CC_WITH_TREE;
26788 + }
26789 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26790 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26791 + {
26792 +
26793 + p_CcNode->shadowAction = 0;
26794 + }
26795 +
26796 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26797 + && !(p_CcNode->shadowAction
26798 + & UPDATE_CC_WITH_DELETE_TREE))
26799 + {
26800 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26801 + h_Tree, NULL);
26802 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26803 + UPDATE_CC_WITH_DELETE_TREE;
26804 + }
26805 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26806 + != e_FM_PCD_INVALID)
26807 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26808 + else
26809 + tmp = p_CcNode->numOfKeys;
26810 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26811 + p_CcNode->keyAndNextEngineParams,
26812 + p_CcNode->h_AdTable, tmp, h_Tree);
26813 + if (err != E_OK)
26814 + return err;
26815 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26816 + p_CcNode->shadowAction |= requiredAction;
26817 + }
26818 + break;
26819 +
26820 + case (e_FM_PCD_KG):
26821 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26822 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26823 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26824 + {
26825 + physicalSchemeId =
26826 + FmPcdKgGetSchemeId(
26827 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26828 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26829 + h_FmPcd, physicalSchemeId);
26830 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26831 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26832 + if (!FmPcdKgIsSchemeValidSw(
26833 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
26834 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
26835 + ("Invalid direct scheme."));
26836 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
26837 + RETURN_ERROR(
26838 + MAJOR, E_INVALID_STATE,
26839 + ("For this action scheme has to be direct."));
26840 + err =
26841 + FmPcdKgCcGetSetParams(
26842 + h_FmPcd,
26843 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
26844 + requiredAction, 0);
26845 + if (err != E_OK)
26846 + RETURN_ERROR(MAJOR, err, NO_MSG);
26847 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26848 + requiredAction;
26849 + }
26850 + break;
26851 +
26852 + case (e_FM_PCD_PLCR):
26853 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26854 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26855 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26856 + {
26857 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
26858 + RETURN_ERROR(
26859 + MAJOR,
26860 + E_NOT_SUPPORTED,
26861 + ("In this initialization only overrideFqid can be initialized"));
26862 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
26863 + RETURN_ERROR(
26864 + MAJOR,
26865 + E_NOT_SUPPORTED,
26866 + ("In this initialization only overrideFqid can be initialized"));
26867 + err =
26868 + FmPcdPlcrGetAbsoluteIdByProfileParams(
26869 + h_FmPcd,
26870 + e_FM_PCD_PLCR_SHARED,
26871 + NULL,
26872 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
26873 + &profileId);
26874 + if (err != E_OK)
26875 + RETURN_ERROR(MAJOR, err, NO_MSG);
26876 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
26877 + requiredAction);
26878 + if (err != E_OK)
26879 + RETURN_ERROR(MAJOR, err, NO_MSG);
26880 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26881 + requiredAction;
26882 + }
26883 + break;
26884 +
26885 + case (e_FM_PCD_DONE):
26886 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26887 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26888 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26889 + {
26890 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
26891 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26892 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26893 + RETURN_ERROR(
26894 + MAJOR,
26895 + E_INVALID_STATE,
26896 + ("Next engine was previously assigned not as PCD_DONE"));
26897 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
26898 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
26899 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26900 + requiredAction;
26901 + }
26902 + break;
26903 +
26904 + default:
26905 + break;
26906 + }
26907 + }
26908 +
26909 + return E_OK;
26910 +}
26911 +
26912 +static t_Error SetRequiredAction(
26913 + t_Handle h_FmPcd, uint32_t requiredAction,
26914 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26915 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26916 +{
26917 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
26918 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26919 + numOfEntries, h_Tree);
26920 + if (err != E_OK)
26921 + return err;
26922 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
26923 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26924 + numOfEntries, h_Tree);
26925 +}
26926 +
26927 +static t_Error ReleaseModifiedDataStructure(
26928 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
26929 + t_List *h_FmPcdNewPointersLst,
26930 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
26931 + bool useShadowStructs)
26932 +{
26933 + t_List *p_Pos;
26934 + t_Error err = E_OK;
26935 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
26936 + t_Handle h_Muram;
26937 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
26938 + t_List *p_UpdateLst;
26939 + uint32_t intFlags;
26940 +
26941 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
26942 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
26943 + E_INVALID_HANDLE);
26944 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
26945 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
26946 +
26947 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
26948 + if (p_AdditionalParams->h_NodeForAdd)
26949 + {
26950 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
26951 +
26952 + if (!p_AdditionalParams->tree)
26953 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26954 + else
26955 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26956 +
26957 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26958 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26959 + p_FmPcdCcNextNode->h_Spinlock);
26960 +
26961 + if (p_CcNodeInformation)
26962 + p_CcNodeInformation->index++;
26963 + else
26964 + {
26965 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26966 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
26967 + ccNodeInfo.index = 1;
26968 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
26969 + p_FmPcdCcNextNode->h_Spinlock);
26970 + }
26971 + if (p_AdditionalParams->h_ManipForAdd)
26972 + {
26973 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26974 + FmPcdManipGetNodeLstPointedOnThisManip(
26975 + p_AdditionalParams->h_ManipForAdd),
26976 + p_AdditionalParams->h_CurrentNode,
26977 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
26978 +
26979 + if (p_CcNodeInformation)
26980 + p_CcNodeInformation->index++;
26981 + else
26982 + {
26983 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26984 + ccNodeInfo.h_CcNode =
26985 + (t_Handle)p_AdditionalParams->h_CurrentNode;
26986 + ccNodeInfo.index = 1;
26987 + EnqueueNodeInfoToRelevantLst(
26988 + FmPcdManipGetNodeLstPointedOnThisManip(
26989 + p_AdditionalParams->h_ManipForAdd),
26990 + &ccNodeInfo,
26991 + FmPcdManipGetSpinlock(
26992 + p_AdditionalParams->h_ManipForAdd));
26993 + }
26994 + }
26995 + }
26996 +
26997 + if (p_AdditionalParams->h_NodeForRmv)
26998 + {
26999 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
27000 +
27001 + if (!p_AdditionalParams->tree)
27002 + {
27003 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
27004 + p_FmPcdCcWorkingOnNode =
27005 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27006 +
27007 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
27008 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
27009 + LIST_NEXT(p_Pos))
27010 + {
27011 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27012 +
27013 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27014 +
27015 + err =
27016 + SetRequiredAction(
27017 + h_FmPcd,
27018 + UPDATE_CC_WITH_DELETE_TREE,
27019 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27020 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27021 + 1, p_CcNodeInformation->h_CcNode);
27022 + }
27023 + }
27024 + else
27025 + {
27026 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27027 +
27028 + err =
27029 + SetRequiredAction(
27030 + h_FmPcd,
27031 + UPDATE_CC_WITH_DELETE_TREE,
27032 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27033 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27034 + 1, p_AdditionalParams->h_CurrentNode);
27035 + }
27036 + if (err)
27037 + return err;
27038 +
27039 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
27040 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
27041 + Update of the node owner */
27042 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27043 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27044 + p_FmPcdCcNextNode->h_Spinlock);
27045 +
27046 + ASSERT_COND(p_CcNodeInformation);
27047 + ASSERT_COND(p_CcNodeInformation->index);
27048 +
27049 + p_CcNodeInformation->index--;
27050 +
27051 + if (p_CcNodeInformation->index == 0)
27052 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
27053 + p_AdditionalParams->h_CurrentNode,
27054 + p_FmPcdCcNextNode->h_Spinlock);
27055 +
27056 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
27057 +
27058 + if (p_AdditionalParams->h_ManipForRmv)
27059 + {
27060 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27061 + FmPcdManipGetNodeLstPointedOnThisManip(
27062 + p_AdditionalParams->h_ManipForRmv),
27063 + p_AdditionalParams->h_CurrentNode,
27064 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
27065 +
27066 + ASSERT_COND(p_CcNodeInformation);
27067 + ASSERT_COND(p_CcNodeInformation->index);
27068 +
27069 + p_CcNodeInformation->index--;
27070 +
27071 + if (p_CcNodeInformation->index == 0)
27072 + DequeueNodeInfoFromRelevantLst(
27073 + FmPcdManipGetNodeLstPointedOnThisManip(
27074 + p_AdditionalParams->h_ManipForRmv),
27075 + p_AdditionalParams->h_CurrentNode,
27076 + FmPcdManipGetSpinlock(
27077 + p_AdditionalParams->h_ManipForRmv));
27078 + }
27079 + }
27080 +
27081 + if (p_AdditionalParams->h_ManipForRmv)
27082 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
27083 +
27084 + if (p_AdditionalParams->p_StatsObjForRmv)
27085 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
27086 + p_AdditionalParams->p_StatsObjForRmv);
27087 +
27088 +#if (DPAA_VERSION >= 11)
27089 + if (p_AdditionalParams->h_FrmReplicForRmv)
27090 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
27091 + FALSE/* remove */);
27092 +#endif /* (DPAA_VERSION >= 11) */
27093 +
27094 + if (!useShadowStructs)
27095 + {
27096 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
27097 + ASSERT_COND(h_Muram);
27098 +
27099 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
27100 + || (!p_AdditionalParams->tree
27101 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
27102 + {
27103 + /* We release new AD which was allocated and updated for copy from to actual AD */
27104 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
27105 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
27106 + {
27107 +
27108 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27109 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27110 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
27111 + }
27112 + }
27113 +
27114 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
27115 + if (p_AdditionalParams->p_AdTableOld)
27116 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
27117 +
27118 + if (p_AdditionalParams->p_KeysMatchTableOld)
27119 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
27120 + }
27121 +
27122 + /* Update current modified node with changed fields if it's required*/
27123 + if (!p_AdditionalParams->tree)
27124 + {
27125 + if (p_AdditionalParams->p_AdTableNew)
27126 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
27127 + p_AdditionalParams->p_AdTableNew;
27128 +
27129 + if (p_AdditionalParams->p_KeysMatchTableNew)
27130 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
27131 + p_AdditionalParams->p_KeysMatchTableNew;
27132 +
27133 + /* Locking node's spinlock before updating 'keys and next engine' structure,
27134 + as it maybe used to retrieve keys statistics */
27135 + intFlags =
27136 + XX_LockIntrSpinlock(
27137 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
27138 +
27139 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
27140 + p_AdditionalParams->numOfKeys;
27141 +
27142 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27143 + &p_AdditionalParams->keyAndNextEngineParams,
27144 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
27145 +
27146 + XX_UnlockIntrSpinlock(
27147 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
27148 + intFlags);
27149 + }
27150 + else
27151 + {
27152 + uint8_t numEntries =
27153 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
27154 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
27155 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27156 + &p_AdditionalParams->keyAndNextEngineParams,
27157 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
27158 + }
27159 +
27160 + ReleaseLst(h_FmPcdOldPointersLst);
27161 + ReleaseLst(h_FmPcdNewPointersLst);
27162 +
27163 + XX_Free(p_AdditionalParams);
27164 +
27165 + return E_OK;
27166 +}
27167 +
27168 +static t_Handle BuildNewAd(
27169 + t_Handle h_Ad,
27170 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
27171 + t_FmPcdCcNode *p_CcNode,
27172 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
27173 +{
27174 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
27175 + t_Handle h_OrigAd = NULL;
27176 +
27177 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
27178 + if (!p_FmPcdCcNodeTmp)
27179 + {
27180 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
27181 + return NULL;
27182 + }
27183 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
27184 +
27185 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
27186 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
27187 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
27188 + p_FmPcdCcNodeTmp->h_AdTable =
27189 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27190 +
27191 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27192 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27193 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27194 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27195 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27196 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27197 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27198 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27199 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27200 +
27201 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27202 + {
27203 + if (p_FmPcdCcNextEngineParams->h_Manip)
27204 + {
27205 + h_OrigAd = p_CcNode->h_Ad;
27206 + if (AllocAndFillAdForContLookupManip(
27207 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27208 + != E_OK)
27209 + {
27210 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27211 + XX_Free(p_FmPcdCcNodeTmp);
27212 + return NULL;
27213 + }
27214 + }
27215 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27216 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27217 + }
27218 +
27219 +#if (DPAA_VERSION >= 11)
27220 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27221 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27222 + {
27223 + FillAdOfTypeContLookup(
27224 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27225 + p_FmPcdCcNextEngineParams->h_Manip,
27226 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27227 + }
27228 +#endif /* (DPAA_VERSION >= 11) */
27229 +
27230 + XX_Free(p_FmPcdCcNodeTmp);
27231 +
27232 + return E_OK;
27233 +}
27234 +
27235 +static t_Error DynamicChangeHc(
27236 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27237 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27238 + bool useShadowStructs)
27239 +{
27240 + t_List *p_PosOld, *p_PosNew;
27241 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27242 + uint16_t i = 0;
27243 + t_Error err = E_OK;
27244 + uint8_t numOfModifiedPtr;
27245 +
27246 + ASSERT_COND(h_FmPcd);
27247 + ASSERT_COND(h_OldPointersLst);
27248 + ASSERT_COND(h_NewPointersLst);
27249 +
27250 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27251 +
27252 + if (numOfModifiedPtr)
27253 + {
27254 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27255 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27256 +
27257 + /* Retrieve address of new AD */
27258 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27259 + p_PosNew);
27260 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27261 + {
27262 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27263 + h_NewPointersLst,
27264 + p_AdditionalParams, useShadowStructs);
27265 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27266 + }
27267 +
27268 + for (i = 0; i < numOfModifiedPtr; i++)
27269 + {
27270 + /* Retrieve address of current AD */
27271 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27272 + p_PosOld);
27273 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27274 + {
27275 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27276 + h_NewPointersLst,
27277 + p_AdditionalParams,
27278 + useShadowStructs);
27279 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27280 + }
27281 +
27282 + /* Invoke host command to copy from new AD to old AD */
27283 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27284 + oldAdAddrOffset, newAdAddrOffset);
27285 + if (err)
27286 + {
27287 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27288 + h_NewPointersLst,
27289 + p_AdditionalParams,
27290 + useShadowStructs);
27291 + RETURN_ERROR(
27292 + MAJOR,
27293 + err,
27294 + ("For part of nodes changes are done - situation is danger"));
27295 + }
27296 +
27297 + p_PosOld = LIST_NEXT(p_PosOld);
27298 + }
27299 + }
27300 + return E_OK;
27301 +}
27302 +
27303 +static t_Error DoDynamicChange(
27304 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27305 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27306 + bool useShadowStructs)
27307 +{
27308 + t_FmPcdCcNode *p_CcNode =
27309 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27310 + t_List *p_PosNew;
27311 + t_CcNodeInformation *p_CcNodeInfo;
27312 + t_FmPcdCcNextEngineParams nextEngineParams;
27313 + t_Handle h_Ad;
27314 + uint32_t keySize;
27315 + t_Error err = E_OK;
27316 + uint8_t numOfModifiedPtr;
27317 +
27318 + ASSERT_COND(h_FmPcd);
27319 +
27320 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27321 +
27322 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27323 +
27324 + if (numOfModifiedPtr)
27325 + {
27326 +
27327 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27328 +
27329 + /* Invoke host-command to copy from the new Ad to existing Ads */
27330 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27331 + p_AdditionalParams, useShadowStructs);
27332 + if (err)
27333 + RETURN_ERROR(MAJOR, err, NO_MSG);
27334 +
27335 + if (useShadowStructs)
27336 + {
27337 + /* When the host-command above has ended, the old structures are 'free'and we can update
27338 + them by copying from the new shadow structures. */
27339 + if (p_CcNode->lclMask)
27340 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27341 + else
27342 + keySize = p_CcNode->ccKeySizeAccExtraction;
27343 +
27344 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27345 + p_AdditionalParams->p_KeysMatchTableNew,
27346 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27347 +
27348 + MemCpy8(
27349 + p_AdditionalParams->p_AdTableOld,
27350 + p_AdditionalParams->p_AdTableNew,
27351 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27352 + * FM_PCD_CC_AD_ENTRY_SIZE));
27353 +
27354 + /* Retrieve the address of the allocated Ad */
27355 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27356 + h_Ad = p_CcNodeInfo->h_CcNode;
27357 +
27358 + /* Build a new Ad that holds the old (now updated) structures */
27359 + p_AdditionalParams->p_KeysMatchTableNew =
27360 + p_AdditionalParams->p_KeysMatchTableOld;
27361 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27362 +
27363 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27364 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27365 +
27366 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27367 +
27368 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27369 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27370 + p_AdditionalParams, useShadowStructs);
27371 + if (err)
27372 + RETURN_ERROR(MAJOR, err, NO_MSG);
27373 + }
27374 + }
27375 +
27376 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27377 + h_NewPointersLst,
27378 + p_AdditionalParams, useShadowStructs);
27379 + if (err)
27380 + RETURN_ERROR(MAJOR, err, NO_MSG);
27381 +
27382 + return E_OK;
27383 +}
27384 +
27385 +#ifdef FM_CAPWAP_SUPPORT
27386 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27387 +{
27388 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27389 + bool isManipForCapwapApplSpecificBuild = FALSE;
27390 + int i = 0;
27391 +
27392 + ASSERT_COND(h_Node);
27393 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27394 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27395 + {
27396 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27397 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27398 + {
27399 + isManipForCapwapApplSpecificBuild = TRUE;
27400 + break;
27401 + }
27402 + }
27403 + return isManipForCapwapApplSpecificBuild;
27404 +
27405 +}
27406 +#endif /* FM_CAPWAP_SUPPORT */
27407 +
27408 +static t_Error CcUpdateParam(
27409 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27410 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27411 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27412 + t_Handle h_FmTree, bool modify)
27413 +{
27414 + t_FmPcdCcNode *p_CcNode;
27415 + t_Error err;
27416 + uint16_t tmp = 0;
27417 + int i = 0;
27418 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27419 +
27420 + level++;
27421 +
27422 + if (p_CcTree->h_IpReassemblyManip)
27423 + {
27424 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27425 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27426 + level, h_FmTree, modify);
27427 + if (err)
27428 + RETURN_ERROR(MAJOR, err, NO_MSG);
27429 + }
27430 +
27431 + if (p_CcTree->h_CapwapReassemblyManip)
27432 + {
27433 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27434 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27435 + level, h_FmTree, modify);
27436 + if (err)
27437 + RETURN_ERROR(MAJOR, err, NO_MSG);
27438 + }
27439 +
27440 + if (numOfEntries)
27441 + {
27442 + for (i = 0; i < numOfEntries; i++)
27443 + {
27444 + if (i == 0)
27445 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27446 + else
27447 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27448 +
27449 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27450 + == e_FM_PCD_CC)
27451 + {
27452 + p_CcNode =
27453 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27454 + ASSERT_COND(p_CcNode);
27455 +
27456 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27457 + {
27458 + err =
27459 + FmPcdManipUpdate(
27460 + h_FmPcd,
27461 + NULL,
27462 + h_FmPort,
27463 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27464 + h_Ad, validate, level, h_FmTree, modify);
27465 + if (err)
27466 + RETURN_ERROR(MAJOR, err, NO_MSG);
27467 + }
27468 +
27469 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27470 + != e_FM_PCD_INVALID)
27471 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27472 + else
27473 + tmp = p_CcNode->numOfKeys;
27474 +
27475 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27476 + p_CcNode->keyAndNextEngineParams, tmp,
27477 + p_CcNode->h_AdTable, validate, level,
27478 + h_FmTree, modify);
27479 + if (err)
27480 + RETURN_ERROR(MAJOR, err, NO_MSG);
27481 + }
27482 + else
27483 + {
27484 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27485 + {
27486 + err =
27487 + FmPcdManipUpdate(
27488 + h_FmPcd,
27489 + NULL,
27490 + h_FmPort,
27491 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27492 + h_Ad, validate, level, h_FmTree, modify);
27493 + if (err)
27494 + RETURN_ERROR(MAJOR, err, NO_MSG);
27495 + }
27496 + }
27497 + }
27498 + }
27499 +
27500 + return E_OK;
27501 +}
27502 +
27503 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27504 +{
27505 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27506 + {
27507 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27508 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27509 + {
27510 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27511 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27512 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27513 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27514 + default:
27515 + return CC_PRIVATE_INFO_NONE;
27516 + }
27517 +
27518 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27519 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27520 + {
27521 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27522 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27523 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27524 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27525 + default:
27526 + return CC_PRIVATE_INFO_NONE;
27527 + }
27528 +
27529 + default:
27530 + break;
27531 + }
27532 +
27533 + return CC_PRIVATE_INFO_NONE;
27534 +}
27535 +
27536 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27537 + t_List *p_List)
27538 +{
27539 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27540 +
27541 + if (!LIST_IsEmpty(p_List))
27542 + {
27543 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27544 + LIST_DelAndInit(&p_CcNodeInfo->node);
27545 + }
27546 +
27547 + return p_CcNodeInfo;
27548 +}
27549 +
27550 +void ReleaseLst(t_List *p_List)
27551 +{
27552 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27553 +
27554 + if (!LIST_IsEmpty(p_List))
27555 + {
27556 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27557 + while (p_CcNodeInfo)
27558 + {
27559 + XX_Free(p_CcNodeInfo);
27560 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27561 + }
27562 + }
27563 +
27564 + LIST_Del(p_List);
27565 +}
27566 +
27567 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27568 +{
27569 + uint32_t i;
27570 +
27571 + if (!p_CcNode)
27572 + return;
27573 +
27574 + if (p_CcNode->p_GlblMask)
27575 + {
27576 + XX_Free(p_CcNode->p_GlblMask);
27577 + p_CcNode->p_GlblMask = NULL;
27578 + }
27579 +
27580 + if (p_CcNode->h_KeysMatchTable)
27581 + {
27582 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27583 + p_CcNode->h_KeysMatchTable);
27584 + p_CcNode->h_KeysMatchTable = NULL;
27585 + }
27586 +
27587 + if (p_CcNode->h_AdTable)
27588 + {
27589 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27590 + p_CcNode->h_AdTable);
27591 + p_CcNode->h_AdTable = NULL;
27592 + }
27593 +
27594 + if (p_CcNode->h_Ad)
27595 + {
27596 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27597 + p_CcNode->h_Ad);
27598 + p_CcNode->h_Ad = NULL;
27599 + p_CcNode->h_TmpAd = NULL;
27600 + }
27601 +
27602 + if (p_CcNode->h_StatsFLRs)
27603 + {
27604 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27605 + p_CcNode->h_StatsFLRs);
27606 + p_CcNode->h_StatsFLRs = NULL;
27607 + }
27608 +
27609 + if (p_CcNode->h_Spinlock)
27610 + {
27611 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27612 + p_CcNode->h_Spinlock = NULL;
27613 + }
27614 +
27615 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27616 + if (p_CcNode->isHashBucket
27617 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27618 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27619 + p_CcNode->h_PrivMissStatsCounters;
27620 +
27621 + /* Releasing all currently used statistics objects, including 'miss' entry */
27622 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27623 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27624 + PutStatsObj(p_CcNode,
27625 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27626 +
27627 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27628 + {
27629 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27630 + ASSERT_COND(h_FmMuram);
27631 +
27632 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27633 + }
27634 +
27635 + LIST_Del(&p_CcNode->availableStatsLst);
27636 +
27637 + ReleaseLst(&p_CcNode->availableStatsLst);
27638 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27639 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27640 + ReleaseLst(&p_CcNode->ccTreesLst);
27641 +
27642 + XX_Free(p_CcNode);
27643 +}
27644 +
27645 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27646 +{
27647 + if (p_FmPcdTree)
27648 + {
27649 + if (p_FmPcdTree->ccTreeBaseAddr)
27650 + {
27651 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27652 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27653 + p_FmPcdTree->ccTreeBaseAddr = 0;
27654 + }
27655 +
27656 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27657 +
27658 + XX_Free(p_FmPcdTree);
27659 + }
27660 +}
27661 +
27662 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27663 + uint8_t *parseCodeCcSize)
27664 +{
27665 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27666 + *parseCodeCcSize = 1;
27667 + else
27668 + if (parseCodeRealSize == 2)
27669 + *parseCodeCcSize = 2;
27670 + else
27671 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27672 + *parseCodeCcSize = 4;
27673 + else
27674 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27675 + *parseCodeCcSize = 8;
27676 + else
27677 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27678 + *parseCodeCcSize = 16;
27679 + else
27680 + if ((parseCodeRealSize > 16)
27681 + && (parseCodeRealSize <= 24))
27682 + *parseCodeCcSize = 24;
27683 + else
27684 + if ((parseCodeRealSize > 24)
27685 + && (parseCodeRealSize <= 32))
27686 + *parseCodeCcSize = 32;
27687 + else
27688 + if ((parseCodeRealSize > 32)
27689 + && (parseCodeRealSize <= 40))
27690 + *parseCodeCcSize = 40;
27691 + else
27692 + if ((parseCodeRealSize > 40)
27693 + && (parseCodeRealSize <= 48))
27694 + *parseCodeCcSize = 48;
27695 + else
27696 + if ((parseCodeRealSize > 48)
27697 + && (parseCodeRealSize <= 56))
27698 + *parseCodeCcSize = 56;
27699 + else
27700 + *parseCodeCcSize = 0;
27701 +}
27702 +
27703 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27704 + uint8_t *parseCodeRealSize)
27705 +{
27706 + switch (hdr)
27707 + {
27708 + case (HEADER_TYPE_ETH):
27709 + switch (field.eth)
27710 + {
27711 + case (NET_HEADER_FIELD_ETH_DA):
27712 + *parseCodeRealSize = 6;
27713 + break;
27714 +
27715 + case (NET_HEADER_FIELD_ETH_SA):
27716 + *parseCodeRealSize = 6;
27717 + break;
27718 +
27719 + case (NET_HEADER_FIELD_ETH_TYPE):
27720 + *parseCodeRealSize = 2;
27721 + break;
27722 +
27723 + default:
27724 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27725 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27726 + break;
27727 + }
27728 + break;
27729 +
27730 + case (HEADER_TYPE_PPPoE):
27731 + switch (field.pppoe)
27732 + {
27733 + case (NET_HEADER_FIELD_PPPoE_PID):
27734 + *parseCodeRealSize = 2;
27735 + break;
27736 +
27737 + default:
27738 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27739 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27740 + break;
27741 + }
27742 + break;
27743 +
27744 + case (HEADER_TYPE_VLAN):
27745 + switch (field.vlan)
27746 + {
27747 + case (NET_HEADER_FIELD_VLAN_TCI):
27748 + *parseCodeRealSize = 2;
27749 + break;
27750 +
27751 + default:
27752 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27753 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27754 + break;
27755 + }
27756 + break;
27757 +
27758 + case (HEADER_TYPE_MPLS):
27759 + switch (field.mpls)
27760 + {
27761 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27762 + *parseCodeRealSize = 4;
27763 + break;
27764 +
27765 + default:
27766 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27767 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27768 + break;
27769 + }
27770 + break;
27771 +
27772 + case (HEADER_TYPE_IPv4):
27773 + switch (field.ipv4)
27774 + {
27775 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27776 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27777 + *parseCodeRealSize = 4;
27778 + break;
27779 +
27780 + case (NET_HEADER_FIELD_IPv4_TOS):
27781 + case (NET_HEADER_FIELD_IPv4_PROTO):
27782 + *parseCodeRealSize = 1;
27783 + break;
27784 +
27785 + case (NET_HEADER_FIELD_IPv4_DST_IP
27786 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27787 + *parseCodeRealSize = 8;
27788 + break;
27789 +
27790 + case (NET_HEADER_FIELD_IPv4_TTL):
27791 + *parseCodeRealSize = 1;
27792 + break;
27793 +
27794 + default:
27795 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27796 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27797 + break;
27798 + }
27799 + break;
27800 +
27801 + case (HEADER_TYPE_IPv6):
27802 + switch (field.ipv6)
27803 + {
27804 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27805 + | NET_HEADER_FIELD_IPv6_TC):
27806 + *parseCodeRealSize = 4;
27807 + break;
27808 +
27809 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27810 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27811 + *parseCodeRealSize = 1;
27812 + break;
27813 +
27814 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27815 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27816 + *parseCodeRealSize = 16;
27817 + break;
27818 +
27819 + default:
27820 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27821 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27822 + break;
27823 + }
27824 + break;
27825 +
27826 + case (HEADER_TYPE_IP):
27827 + switch (field.ip)
27828 + {
27829 + case (NET_HEADER_FIELD_IP_DSCP):
27830 + case (NET_HEADER_FIELD_IP_PROTO):
27831 + *parseCodeRealSize = 1;
27832 + break;
27833 +
27834 + default:
27835 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27836 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27837 + break;
27838 + }
27839 + break;
27840 +
27841 + case (HEADER_TYPE_GRE):
27842 + switch (field.gre)
27843 + {
27844 + case (NET_HEADER_FIELD_GRE_TYPE):
27845 + *parseCodeRealSize = 2;
27846 + break;
27847 +
27848 + default:
27849 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
27850 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27851 + break;
27852 + }
27853 + break;
27854 +
27855 + case (HEADER_TYPE_MINENCAP):
27856 + switch (field.minencap)
27857 + {
27858 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
27859 + *parseCodeRealSize = 1;
27860 + break;
27861 +
27862 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
27863 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
27864 + *parseCodeRealSize = 4;
27865 + break;
27866 +
27867 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
27868 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
27869 + *parseCodeRealSize = 8;
27870 + break;
27871 +
27872 + default:
27873 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
27874 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27875 + break;
27876 + }
27877 + break;
27878 +
27879 + case (HEADER_TYPE_TCP):
27880 + switch (field.tcp)
27881 + {
27882 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
27883 + case (NET_HEADER_FIELD_TCP_PORT_DST):
27884 + *parseCodeRealSize = 2;
27885 + break;
27886 +
27887 + case (NET_HEADER_FIELD_TCP_PORT_SRC
27888 + | NET_HEADER_FIELD_TCP_PORT_DST):
27889 + *parseCodeRealSize = 4;
27890 + break;
27891 +
27892 + default:
27893 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
27894 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27895 + break;
27896 + }
27897 + break;
27898 +
27899 + case (HEADER_TYPE_UDP):
27900 + switch (field.udp)
27901 + {
27902 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
27903 + case (NET_HEADER_FIELD_UDP_PORT_DST):
27904 + *parseCodeRealSize = 2;
27905 + break;
27906 +
27907 + case (NET_HEADER_FIELD_UDP_PORT_SRC
27908 + | NET_HEADER_FIELD_UDP_PORT_DST):
27909 + *parseCodeRealSize = 4;
27910 + break;
27911 +
27912 + default:
27913 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
27914 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27915 + break;
27916 + }
27917 + break;
27918 +
27919 + default:
27920 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
27921 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27922 + break;
27923 + }
27924 +}
27925 +
27926 +t_Error ValidateNextEngineParams(
27927 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
27928 + e_FmPcdCcStatsMode statsMode)
27929 +{
27930 + uint16_t absoluteProfileId;
27931 + t_Error err = E_OK;
27932 + uint8_t relativeSchemeId;
27933 +
27934 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
27935 + && (p_FmPcdCcNextEngineParams->statisticsEn))
27936 + RETURN_ERROR(
27937 + MAJOR,
27938 + E_CONFLICT,
27939 + ("Statistics are requested for a key, but statistics mode was set"
27940 + "to 'NONE' upon initialization"));
27941 +
27942 + switch (p_FmPcdCcNextEngineParams->nextEngine)
27943 + {
27944 + case (e_FM_PCD_INVALID):
27945 + err = E_NOT_SUPPORTED;
27946 + break;
27947 +
27948 + case (e_FM_PCD_DONE):
27949 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
27950 + == e_FM_PCD_ENQ_FRAME)
27951 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
27952 + {
27953 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
27954 + RETURN_ERROR(
27955 + MAJOR,
27956 + E_CONFLICT,
27957 + ("When overrideFqid is set, newFqid must not be zero"));
27958 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
27959 + & ~0x00FFFFFF)
27960 + RETURN_ERROR(
27961 + MAJOR, E_INVALID_VALUE,
27962 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
27963 + }
27964 + break;
27965 +
27966 + case (e_FM_PCD_KG):
27967 + relativeSchemeId =
27968 + FmPcdKgGetRelativeSchemeId(
27969 + h_FmPcd,
27970 + FmPcdKgGetSchemeId(
27971 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
27972 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
27973 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
27974 + if (!FmPcdKgIsSchemeValidSw(
27975 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
27976 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27977 + ("not valid schemeIndex in KG next engine param"));
27978 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
27979 + RETURN_ERROR(
27980 + MAJOR,
27981 + E_INVALID_STATE,
27982 + ("CC Node may point only to a scheme that is always direct."));
27983 + break;
27984 +
27985 + case (e_FM_PCD_PLCR):
27986 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
27987 + {
27988 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
27989 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
27990 + {
27991 + err =
27992 + FmPcdPlcrGetAbsoluteIdByProfileParams(
27993 + h_FmPcd,
27994 + e_FM_PCD_PLCR_SHARED,
27995 + NULL,
27996 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
27997 + &absoluteProfileId);
27998 + if (err)
27999 + RETURN_ERROR(MAJOR, err,
28000 + ("Shared profile offset is out of range"));
28001 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
28002 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28003 + ("Invalid profile"));
28004 + }
28005 + }
28006 + break;
28007 +
28008 + case (e_FM_PCD_HASH):
28009 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
28010 + case (e_FM_PCD_CC):
28011 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
28012 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
28013 + ("handler to next Node is NULL"));
28014 + break;
28015 +
28016 +#if (DPAA_VERSION >= 11)
28017 + case (e_FM_PCD_FR):
28018 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
28019 + err = E_NOT_SUPPORTED;
28020 + break;
28021 +#endif /* (DPAA_VERSION >= 11) */
28022 +
28023 + default:
28024 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28025 + ("Next engine is not correct"));
28026 + }
28027 +
28028 +
28029 + return err;
28030 +}
28031 +
28032 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
28033 + uint32_t offset, bool glblMask,
28034 + uint8_t *parseArrayOffset, bool fromIc,
28035 + ccPrivateInfo_t icCode)
28036 +{
28037 + if (!fromIc)
28038 + {
28039 + switch (src)
28040 + {
28041 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
28042 + if (glblMask)
28043 + return CC_PC_GENERIC_WITH_MASK;
28044 + else
28045 + return CC_PC_GENERIC_WITHOUT_MASK;
28046 +
28047 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
28048 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
28049 + if (offset)
28050 + return CC_PR_OFFSET;
28051 + else
28052 + return CC_PR_WITHOUT_OFFSET;
28053 +
28054 + default:
28055 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28056 + return CC_PC_ILLEGAL;
28057 + }
28058 + }
28059 + else
28060 + {
28061 + switch (icCode)
28062 + {
28063 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
28064 + *parseArrayOffset = 0x50;
28065 + return CC_PC_GENERIC_IC_GMASK;
28066 +
28067 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
28068 + *parseArrayOffset = 0x48;
28069 + return CC_PC_GENERIC_IC_GMASK;
28070 +
28071 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
28072 + *parseArrayOffset = 0x48;
28073 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28074 +
28075 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
28076 + *parseArrayOffset = 0x16;
28077 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28078 +
28079 + default:
28080 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28081 + break;
28082 + }
28083 + }
28084 +
28085 + return CC_PC_ILLEGAL;
28086 +}
28087 +
28088 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
28089 + t_FmPcdFields field)
28090 +{
28091 + switch (hdr)
28092 + {
28093 + case (HEADER_TYPE_NONE):
28094 + ASSERT_COND(FALSE);
28095 + return CC_PC_ILLEGAL;
28096 +
28097 + case (HEADER_TYPE_ETH):
28098 + switch (field.eth)
28099 + {
28100 + case (NET_HEADER_FIELD_ETH_DA):
28101 + return CC_PC_FF_MACDST;
28102 + case (NET_HEADER_FIELD_ETH_SA):
28103 + return CC_PC_FF_MACSRC;
28104 + case (NET_HEADER_FIELD_ETH_TYPE):
28105 + return CC_PC_FF_ETYPE;
28106 + default:
28107 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28108 + return CC_PC_ILLEGAL;
28109 + }
28110 +
28111 + case (HEADER_TYPE_VLAN):
28112 + switch (field.vlan)
28113 + {
28114 + case (NET_HEADER_FIELD_VLAN_TCI):
28115 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28116 + || (index == e_FM_PCD_HDR_INDEX_1))
28117 + return CC_PC_FF_TCI1;
28118 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28119 + return CC_PC_FF_TCI2;
28120 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28121 + return CC_PC_ILLEGAL;
28122 + default:
28123 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28124 + return CC_PC_ILLEGAL;
28125 + }
28126 +
28127 + case (HEADER_TYPE_MPLS):
28128 + switch (field.mpls)
28129 + {
28130 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
28131 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28132 + || (index == e_FM_PCD_HDR_INDEX_1))
28133 + return CC_PC_FF_MPLS1;
28134 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28135 + return CC_PC_FF_MPLS_LAST;
28136 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
28137 + return CC_PC_ILLEGAL;
28138 + default:
28139 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28140 + return CC_PC_ILLEGAL;
28141 + }
28142 +
28143 + case (HEADER_TYPE_IPv4):
28144 + switch (field.ipv4)
28145 + {
28146 + case (NET_HEADER_FIELD_IPv4_DST_IP):
28147 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28148 + || (index == e_FM_PCD_HDR_INDEX_1))
28149 + return CC_PC_FF_IPV4DST1;
28150 + if (index == e_FM_PCD_HDR_INDEX_2)
28151 + return CC_PC_FF_IPV4DST2;
28152 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28153 + return CC_PC_ILLEGAL;
28154 + case (NET_HEADER_FIELD_IPv4_TOS):
28155 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28156 + || (index == e_FM_PCD_HDR_INDEX_1))
28157 + return CC_PC_FF_IPV4IPTOS_TC1;
28158 + if (index == e_FM_PCD_HDR_INDEX_2)
28159 + return CC_PC_FF_IPV4IPTOS_TC2;
28160 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28161 + return CC_PC_ILLEGAL;
28162 + case (NET_HEADER_FIELD_IPv4_PROTO):
28163 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28164 + || (index == e_FM_PCD_HDR_INDEX_1))
28165 + return CC_PC_FF_IPV4PTYPE1;
28166 + if (index == e_FM_PCD_HDR_INDEX_2)
28167 + return CC_PC_FF_IPV4PTYPE2;
28168 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28169 + return CC_PC_ILLEGAL;
28170 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
28171 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28172 + || (index == e_FM_PCD_HDR_INDEX_1))
28173 + return CC_PC_FF_IPV4SRC1;
28174 + if (index == e_FM_PCD_HDR_INDEX_2)
28175 + return CC_PC_FF_IPV4SRC2;
28176 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28177 + return CC_PC_ILLEGAL;
28178 + case (NET_HEADER_FIELD_IPv4_SRC_IP
28179 + | NET_HEADER_FIELD_IPv4_DST_IP):
28180 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28181 + || (index == e_FM_PCD_HDR_INDEX_1))
28182 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
28183 + if (index == e_FM_PCD_HDR_INDEX_2)
28184 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
28185 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28186 + return CC_PC_ILLEGAL;
28187 + case (NET_HEADER_FIELD_IPv4_TTL):
28188 + return CC_PC_FF_IPV4TTL;
28189 + default:
28190 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28191 + return CC_PC_ILLEGAL;
28192 + }
28193 +
28194 + case (HEADER_TYPE_IPv6):
28195 + switch (field.ipv6)
28196 + {
28197 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28198 + | NET_HEADER_FIELD_IPv6_TC):
28199 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28200 + || (index == e_FM_PCD_HDR_INDEX_1))
28201 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28202 + if (index == e_FM_PCD_HDR_INDEX_2)
28203 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28204 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28205 + return CC_PC_ILLEGAL;
28206 +
28207 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28208 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28209 + || (index == e_FM_PCD_HDR_INDEX_1))
28210 + return CC_PC_FF_IPV6PTYPE1;
28211 + if (index == e_FM_PCD_HDR_INDEX_2)
28212 + return CC_PC_FF_IPV6PTYPE2;
28213 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28214 + return CC_PC_FF_IPPID;
28215 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28216 + return CC_PC_ILLEGAL;
28217 +
28218 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28219 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28220 + || (index == e_FM_PCD_HDR_INDEX_1))
28221 + return CC_PC_FF_IPV6DST1;
28222 + if (index == e_FM_PCD_HDR_INDEX_2)
28223 + return CC_PC_FF_IPV6DST2;
28224 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28225 + return CC_PC_ILLEGAL;
28226 +
28227 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28228 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28229 + || (index == e_FM_PCD_HDR_INDEX_1))
28230 + return CC_PC_FF_IPV6SRC1;
28231 + if (index == e_FM_PCD_HDR_INDEX_2)
28232 + return CC_PC_FF_IPV6SRC2;
28233 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28234 + return CC_PC_ILLEGAL;
28235 +
28236 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28237 + return CC_PC_FF_IPV6HOP_LIMIT;
28238 +
28239 + default:
28240 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28241 + return CC_PC_ILLEGAL;
28242 + }
28243 +
28244 + case (HEADER_TYPE_IP):
28245 + switch (field.ip)
28246 + {
28247 + case (NET_HEADER_FIELD_IP_DSCP):
28248 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28249 + || (index == e_FM_PCD_HDR_INDEX_1))
28250 + return CC_PC_FF_IPDSCP;
28251 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28252 + return CC_PC_ILLEGAL;
28253 +
28254 + case (NET_HEADER_FIELD_IP_PROTO):
28255 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28256 + return CC_PC_FF_IPPID;
28257 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28258 + return CC_PC_ILLEGAL;
28259 +
28260 + default:
28261 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28262 + return CC_PC_ILLEGAL;
28263 + }
28264 +
28265 + case (HEADER_TYPE_GRE):
28266 + switch (field.gre)
28267 + {
28268 + case (NET_HEADER_FIELD_GRE_TYPE):
28269 + return CC_PC_FF_GREPTYPE;
28270 +
28271 + default:
28272 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28273 + return CC_PC_ILLEGAL;
28274 + }
28275 +
28276 + case (HEADER_TYPE_MINENCAP):
28277 + switch (field.minencap)
28278 + {
28279 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28280 + return CC_PC_FF_MINENCAP_PTYPE;
28281 +
28282 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28283 + return CC_PC_FF_MINENCAP_IPDST;
28284 +
28285 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28286 + return CC_PC_FF_MINENCAP_IPSRC;
28287 +
28288 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28289 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28290 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28291 +
28292 + default:
28293 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28294 + return CC_PC_ILLEGAL;
28295 + }
28296 +
28297 + case (HEADER_TYPE_TCP):
28298 + switch (field.tcp)
28299 + {
28300 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28301 + return CC_PC_FF_L4PSRC;
28302 +
28303 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28304 + return CC_PC_FF_L4PDST;
28305 +
28306 + case (NET_HEADER_FIELD_TCP_PORT_DST
28307 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28308 + return CC_PC_FF_L4PSRC_L4PDST;
28309 +
28310 + default:
28311 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28312 + return CC_PC_ILLEGAL;
28313 + }
28314 +
28315 + case (HEADER_TYPE_PPPoE):
28316 + switch (field.pppoe)
28317 + {
28318 + case (NET_HEADER_FIELD_PPPoE_PID):
28319 + return CC_PC_FF_PPPPID;
28320 +
28321 + default:
28322 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28323 + return CC_PC_ILLEGAL;
28324 + }
28325 +
28326 + case (HEADER_TYPE_UDP):
28327 + switch (field.udp)
28328 + {
28329 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28330 + return CC_PC_FF_L4PSRC;
28331 +
28332 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28333 + return CC_PC_FF_L4PDST;
28334 +
28335 + case (NET_HEADER_FIELD_UDP_PORT_DST
28336 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28337 + return CC_PC_FF_L4PSRC_L4PDST;
28338 +
28339 + default:
28340 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28341 + return CC_PC_ILLEGAL;
28342 + }
28343 +
28344 + default:
28345 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28346 + return CC_PC_ILLEGAL;
28347 + }
28348 +}
28349 +
28350 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28351 + uint32_t offset, bool glblMask,
28352 + uint8_t *parseArrayOffset)
28353 +{
28354 + bool offsetRelevant = FALSE;
28355 +
28356 + if (offset)
28357 + offsetRelevant = TRUE;
28358 +
28359 + switch (hdr)
28360 + {
28361 + case (HEADER_TYPE_NONE):
28362 + ASSERT_COND(FALSE);
28363 + return CC_PC_ILLEGAL;
28364 +
28365 + case (HEADER_TYPE_ETH):
28366 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28367 + break;
28368 +
28369 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28370 + if (offset || glblMask)
28371 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28372 + else
28373 + return CC_PC_PR_SHIM1;
28374 + break;
28375 +
28376 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28377 + if (offset || glblMask)
28378 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28379 + else
28380 + return CC_PC_PR_SHIM2;
28381 + break;
28382 +
28383 + case (HEADER_TYPE_LLC_SNAP):
28384 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28385 + break;
28386 +
28387 + case (HEADER_TYPE_PPPoE):
28388 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28389 + break;
28390 +
28391 + case (HEADER_TYPE_MPLS):
28392 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28393 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28394 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28395 + else
28396 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28397 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28398 + else
28399 + {
28400 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28401 + return CC_PC_ILLEGAL;
28402 + }
28403 + break;
28404 +
28405 + case (HEADER_TYPE_IPv4):
28406 + case (HEADER_TYPE_IPv6):
28407 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28408 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28409 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28410 + else
28411 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28412 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28413 + else
28414 + {
28415 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28416 + return CC_PC_ILLEGAL;
28417 + }
28418 + break;
28419 +
28420 + case (HEADER_TYPE_MINENCAP):
28421 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28422 + break;
28423 +
28424 + case (HEADER_TYPE_GRE):
28425 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28426 + break;
28427 +
28428 + case (HEADER_TYPE_TCP):
28429 + case (HEADER_TYPE_UDP):
28430 + case (HEADER_TYPE_IPSEC_AH):
28431 + case (HEADER_TYPE_IPSEC_ESP):
28432 + case (HEADER_TYPE_DCCP):
28433 + case (HEADER_TYPE_SCTP):
28434 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28435 + break;
28436 +
28437 + default:
28438 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28439 + return CC_PC_ILLEGAL;
28440 + }
28441 +
28442 + if (offsetRelevant)
28443 + return CC_PR_OFFSET;
28444 + else
28445 + return CC_PR_WITHOUT_OFFSET;
28446 +}
28447 +
28448 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28449 + uint32_t offset, uint8_t *parseArrayOffset,
28450 + e_FmPcdHdrIndex hdrIndex)
28451 +{
28452 + bool offsetRelevant = FALSE;
28453 +
28454 + if (offset)
28455 + offsetRelevant = TRUE;
28456 +
28457 + switch (hdr)
28458 + {
28459 + case (HEADER_TYPE_NONE):
28460 + ASSERT_COND(FALSE);
28461 + break;
28462 + case (HEADER_TYPE_ETH):
28463 + switch (field.eth)
28464 + {
28465 + case (NET_HEADER_FIELD_ETH_TYPE):
28466 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28467 + break;
28468 +
28469 + default:
28470 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28471 + return CC_PC_ILLEGAL;
28472 + }
28473 + break;
28474 +
28475 + case (HEADER_TYPE_VLAN):
28476 + switch (field.vlan)
28477 + {
28478 + case (NET_HEADER_FIELD_VLAN_TCI):
28479 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28480 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28481 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28482 + else
28483 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28484 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28485 + break;
28486 +
28487 + default:
28488 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28489 + return CC_PC_ILLEGAL;
28490 + }
28491 + break;
28492 +
28493 + default:
28494 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28495 + return CC_PC_ILLEGAL;
28496 + }
28497 +
28498 + if (offsetRelevant)
28499 + return CC_PR_OFFSET;
28500 + else
28501 + return CC_PR_WITHOUT_OFFSET;
28502 +}
28503 +
28504 +static void FillAdOfTypeResult(t_Handle h_Ad,
28505 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28506 + t_FmPcd *p_FmPcd,
28507 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28508 +{
28509 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28510 + t_Handle h_TmpAd;
28511 + uint32_t tmp = 0, tmpNia = 0;
28512 + uint16_t profileId;
28513 + t_Handle p_AdNewPtr = NULL;
28514 + t_Error err = E_OK;
28515 +
28516 + /* There are 3 cases handled in this routine of building a "result" type AD.
28517 + * Case 1: No Manip. The action descriptor is built within the match table.
28518 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28519 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28520 + * initialized and returned here.
28521 + * p_AdResult (within the match table) will be initialized after
28522 + * this routine returns and point to the existing AD.
28523 + * Case 3: Manip exists. The action descriptor is built within the match table.
28524 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28525 + *
28526 + * If statistics were enabled and the statistics mode of this node requires
28527 + * a statistics Ad, it will be placed after the result Ad and before the
28528 + * manip Ad, if manip Ad exists here.
28529 + */
28530 +
28531 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28532 + * AD will be written into the match table itself (case (1))*/
28533 + p_AdNewPtr = p_AdResult;
28534 +
28535 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28536 + if (p_FmPcdCcStatsParams)
28537 + {
28538 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28539 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28540 +
28541 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28542 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28543 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28544 + h_Ad = h_TmpAd;
28545 +
28546 + p_AdNewPtr = h_Ad;
28547 + p_AdResult = h_Ad;
28548 +
28549 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28550 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28551 + }
28552 +
28553 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28554 + if (p_CcNextEngineParams->h_Manip)
28555 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28556 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28557 +
28558 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28559 + if (p_AdNewPtr)
28560 + {
28561 + /* case (1) and (2) */
28562 + switch (p_CcNextEngineParams->nextEngine)
28563 + {
28564 + case (e_FM_PCD_DONE):
28565 + if (p_CcNextEngineParams->params.enqueueParams.action
28566 + == e_FM_PCD_ENQ_FRAME)
28567 + {
28568 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28569 + {
28570 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28571 + tmp |=
28572 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28573 +#if (DPAA_VERSION >= 11)
28574 + tmp |=
28575 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28576 + & FM_PCD_AD_RESULT_VSP_MASK)
28577 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28578 +#endif /* (DPAA_VERSION >= 11) */
28579 + }
28580 + else
28581 + {
28582 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28583 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28584 + }
28585 + }
28586 +
28587 + if (p_CcNextEngineParams->params.enqueueParams.action
28588 + == e_FM_PCD_DROP_FRAME)
28589 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28590 + else
28591 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28592 + break;
28593 +
28594 + case (e_FM_PCD_KG):
28595 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28596 + {
28597 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28598 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28599 +#if (DPAA_VERSION >= 11)
28600 + tmp |=
28601 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28602 + & FM_PCD_AD_RESULT_VSP_MASK)
28603 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28604 +#endif /* (DPAA_VERSION >= 11) */
28605 + }
28606 + else
28607 + {
28608 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28609 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28610 + }
28611 + tmpNia = NIA_KG_DIRECT;
28612 + tmpNia |= NIA_ENG_KG;
28613 + tmpNia |= NIA_KG_CC_EN;
28614 + tmpNia |= FmPcdKgGetSchemeId(
28615 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28616 + break;
28617 +
28618 + case (e_FM_PCD_PLCR):
28619 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28620 + {
28621 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28622 +
28623 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28624 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28625 + {
28626 + tmpNia |= NIA_PLCR_ABSOLUTE;
28627 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28628 + (t_Handle)p_FmPcd,
28629 + e_FM_PCD_PLCR_SHARED,
28630 + NULL,
28631 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28632 + &profileId);
28633 +
28634 + if (err != E_OK) {
28635 + REPORT_ERROR(MAJOR, err, NO_MSG);
28636 + return;
28637 + }
28638 +
28639 + }
28640 + else
28641 + profileId =
28642 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28643 +
28644 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28645 +#if (DPAA_VERSION >= 11)
28646 + tmp |=
28647 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28648 + & FM_PCD_AD_RESULT_VSP_MASK)
28649 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28650 +#endif /* (DPAA_VERSION >= 11) */
28651 + WRITE_UINT32(
28652 + p_AdResult->plcrProfile,
28653 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28654 + }
28655 + else
28656 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28657 +
28658 + tmpNia |=
28659 + NIA_ENG_PLCR
28660 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28661 + break;
28662 +
28663 + default:
28664 + return;
28665 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28666 +
28667 + if (p_CcNextEngineParams->h_Manip)
28668 + {
28669 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28670 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28671 + - (p_FmPcd->physicalMuramBase)) >> 4;
28672 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28673 +
28674 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28675 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28676 + }
28677 +
28678 +#if (DPAA_VERSION >= 11)
28679 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28680 +#endif /* (DPAA_VERSION >= 11) */
28681 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28682 + }
28683 +}
28684 +
28685 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28686 + t_Handle h_FmPort, t_Handle h_FmTree,
28687 + bool validate)
28688 +{
28689 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28690 +
28691 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28692 + p_CcTree->keyAndNextEngineParams,
28693 + p_CcTree->numOfEntries,
28694 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28695 + h_FmTree, FALSE);
28696 +}
28697 +
28698 +
28699 +static void ReleaseNewNodeCommonPart(
28700 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28701 +{
28702 + if (p_AdditionalInfo->p_AdTableNew)
28703 + FM_MURAM_FreeMem(
28704 + FmPcdGetMuramHandle(
28705 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28706 + p_AdditionalInfo->p_AdTableNew);
28707 +
28708 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28709 + FM_MURAM_FreeMem(
28710 + FmPcdGetMuramHandle(
28711 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28712 + p_AdditionalInfo->p_KeysMatchTableNew);
28713 +}
28714 +
28715 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28716 + uint8_t *p_Mask)
28717 +{
28718 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28719 +
28720 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28721 + && !p_CcNode->lclMask)
28722 + {
28723 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28724 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28725 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28726 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28727 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28728 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28729 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28730 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28731 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28732 + {
28733 + p_CcNode->glblMaskSize = 0;
28734 + p_CcNode->lclMask = TRUE;
28735 + }
28736 + else
28737 + {
28738 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28739 + p_CcNode->glblMaskUpdated = TRUE;
28740 + p_CcNode->glblMaskSize = 4;
28741 + }
28742 + }
28743 + else
28744 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28745 + {
28746 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28747 + {
28748 + p_CcNode->lclMask = TRUE;
28749 + p_CcNode->glblMaskSize = 0;
28750 + }
28751 + }
28752 + else
28753 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28754 + {
28755 + uint32_t tmpMask = 0xffffffff;
28756 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28757 + {
28758 + p_CcNode->lclMask = TRUE;
28759 + p_CcNode->glblMaskSize = 0;
28760 + }
28761 + }
28762 + else
28763 + if (p_Mask)
28764 + {
28765 + p_CcNode->lclMask = TRUE;
28766 + p_CcNode->glblMaskSize = 0;
28767 + }
28768 +
28769 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28770 + only is mask support was enabled at initialization */
28771 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28772 + {
28773 + p_CcNode->lclMask = FALSE;
28774 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28775 + return ERROR_CODE(E_NOT_SUPPORTED);
28776 + }
28777 +
28778 + return E_OK;
28779 +}
28780 +
28781 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28782 +{
28783 + t_FmPcd *p_FmPcd;
28784 + t_Handle h_Ad;
28785 +
28786 + if (isTree)
28787 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28788 + else
28789 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28790 +
28791 + if ((isTree && p_FmPcd->p_CcShadow)
28792 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28793 + {
28794 + /* The allocated shadow is divided as follows:
28795 + 0 . . . 16 . . .
28796 + ---------------------------------------------------
28797 + | Shadow | Shadow Keys | Shadow Next |
28798 + | Ad | Match Table | Engine Table |
28799 + | (16 bytes) | (maximal size) | (maximal size) |
28800 + ---------------------------------------------------
28801 + */
28802 + if (!p_FmPcd->p_CcShadow)
28803 + {
28804 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28805 + return NULL;
28806 + }
28807 +
28808 + h_Ad = p_FmPcd->p_CcShadow;
28809 + }
28810 + else
28811 + {
28812 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28813 + FM_PCD_CC_AD_ENTRY_SIZE,
28814 + FM_PCD_CC_AD_TABLE_ALIGN);
28815 + if (!h_Ad)
28816 + {
28817 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28818 + return NULL;
28819 + }
28820 + }
28821 +
28822 + return h_Ad;
28823 +}
28824 +
28825 +static t_Error BuildNewNodeCommonPart(
28826 + t_FmPcdCcNode *p_CcNode, int *size,
28827 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28828 +{
28829 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28830 +
28831 + if (p_CcNode->lclMask)
28832 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
28833 + else
28834 + *size = p_CcNode->ccKeySizeAccExtraction;
28835 +
28836 + if (p_CcNode->maxNumOfKeys == 0)
28837 + {
28838 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
28839 + FmPcdGetMuramHandle(p_FmPcd),
28840 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28841 + * FM_PCD_CC_AD_ENTRY_SIZE),
28842 + FM_PCD_CC_AD_TABLE_ALIGN);
28843 + if (!p_AdditionalInfo->p_AdTableNew)
28844 + RETURN_ERROR(
28845 + MAJOR, E_NO_MEMORY,
28846 + ("MURAM allocation for CC node action descriptors table"));
28847 +
28848 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
28849 + FmPcdGetMuramHandle(p_FmPcd),
28850 + (uint32_t)(*size * sizeof(uint8_t)
28851 + * (p_AdditionalInfo->numOfKeys + 1)),
28852 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
28853 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
28854 + {
28855 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
28856 + p_AdditionalInfo->p_AdTableNew);
28857 + p_AdditionalInfo->p_AdTableNew = NULL;
28858 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28859 + ("MURAM allocation for CC node key match table"));
28860 + }
28861 +
28862 + MemSet8(
28863 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28864 + 0,
28865 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28866 + * FM_PCD_CC_AD_ENTRY_SIZE));
28867 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28868 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
28869 + }
28870 + else
28871 + {
28872 + /* The allocated shadow is divided as follows:
28873 + 0 . . . 16 . . .
28874 + ---------------------------------------------------
28875 + | Shadow | Shadow Keys | Shadow Next |
28876 + | Ad | Match Table | Engine Table |
28877 + | (16 bytes) | (maximal size) | (maximal size) |
28878 + ---------------------------------------------------
28879 + */
28880 +
28881 + if (!p_FmPcd->p_CcShadow)
28882 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28883 +
28884 + p_AdditionalInfo->p_KeysMatchTableNew =
28885 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
28886 + p_AdditionalInfo->p_AdTableNew =
28887 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
28888 +
28889 + MemSet8(
28890 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28891 + 0,
28892 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
28893 + * FM_PCD_CC_AD_ENTRY_SIZE));
28894 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28895 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
28896 + }
28897 +
28898 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
28899 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
28900 +
28901 + return E_OK;
28902 +}
28903 +
28904 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
28905 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
28906 + t_FmPcdCcKeyParams *p_KeyParams,
28907 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
28908 +{
28909 + t_Error err = E_OK;
28910 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
28911 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
28912 + int size;
28913 + int i = 0, j = 0;
28914 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28915 + uint32_t requiredAction = 0;
28916 + bool prvLclMask;
28917 + t_CcNodeInformation *p_CcNodeInformation;
28918 + t_FmPcdCcStatsParams statsParams = { 0 };
28919 + t_List *p_Pos;
28920 + t_FmPcdStatsObj *p_StatsObj;
28921 +
28922 + /* Check that new NIA is legal */
28923 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
28924 + p_CcNode->statisticsMode);
28925 + if (err)
28926 + RETURN_ERROR(MAJOR, err, NO_MSG);
28927 +
28928 + prvLclMask = p_CcNode->lclMask;
28929 +
28930 + /* Check that new key is not require update of localMask */
28931 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
28932 + p_KeyParams->p_Mask);
28933 + if (err)
28934 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28935 +
28936 + /* Update internal data structure with new next engine for the given index */
28937 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
28938 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
28939 +
28940 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
28941 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
28942 +
28943 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
28944 + == e_FM_PCD_CC)
28945 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
28946 + {
28947 + err =
28948 + AllocAndFillAdForContLookupManip(
28949 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
28950 + if (err)
28951 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28952 + }
28953 +
28954 + if (p_KeyParams->p_Mask)
28955 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
28956 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
28957 + else
28958 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
28959 + p_CcNode->userSizeOfExtraction);
28960 +
28961 + /* Update numOfKeys */
28962 + if (add)
28963 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
28964 + else
28965 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
28966 +
28967 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
28968 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
28969 + if (err)
28970 + RETURN_ERROR(MAJOR, err, NO_MSG);
28971 +
28972 + /* Check that manip is legal and what requiredAction is necessary for this manip */
28973 + if (p_KeyParams->ccNextEngineParams.h_Manip)
28974 + {
28975 + err = FmPcdManipCheckParamsForCcNextEngine(
28976 + &p_KeyParams->ccNextEngineParams, &requiredAction);
28977 + if (err)
28978 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28979 + }
28980 +
28981 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
28982 + requiredAction;
28983 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
28984 + UPDATE_CC_WITH_TREE;
28985 +
28986 + /* Update new Ad and new Key Table according to new requirement */
28987 + i = 0;
28988 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
28989 + {
28990 + p_AdTableNewTmp =
28991 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
28992 +
28993 + if (j == keyIndex)
28994 + {
28995 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
28996 + {
28997 + /* Allocate a statistics object that holds statistics AD and counters.
28998 + - For added key - New statistics AD and counters pointer need to be allocated
28999 + new statistics object. If statistics were enabled, we need to replace the
29000 + existing descriptor with a new descriptor with nullified counters.
29001 + */
29002 + p_StatsObj = GetStatsObj(p_CcNode);
29003 + ASSERT_COND(p_StatsObj);
29004 +
29005 + /* Store allocated statistics object */
29006 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29007 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29008 + p_StatsObj;
29009 +
29010 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29011 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29012 +#if (DPAA_VERSION >= 11)
29013 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
29014 +
29015 +#endif /* (DPAA_VERSION >= 11) */
29016 +
29017 + /* Building action descriptor for the received new key */
29018 + NextStepAd(p_AdTableNewTmp, &statsParams,
29019 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29020 + }
29021 + else
29022 + {
29023 + /* Building action descriptor for the received new key */
29024 + NextStepAd(p_AdTableNewTmp, NULL,
29025 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29026 + }
29027 +
29028 + /* Copy the received new key into keys match table */
29029 + p_KeysMatchTableNewTmp =
29030 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
29031 +
29032 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
29033 + p_CcNode->userSizeOfExtraction);
29034 +
29035 + /* Update mask for the received new key */
29036 + if (p_CcNode->lclMask)
29037 + {
29038 + if (p_KeyParams->p_Mask)
29039 + {
29040 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29041 + p_CcNode->ccKeySizeAccExtraction),
29042 + p_KeyParams->p_Mask,
29043 + p_CcNode->userSizeOfExtraction);
29044 + }
29045 + else
29046 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29047 + {
29048 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29049 + p_CcNode->ccKeySizeAccExtraction),
29050 + 0xff, p_CcNode->userSizeOfExtraction);
29051 + }
29052 + else
29053 + {
29054 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29055 + p_CcNode->ccKeySizeAccExtraction),
29056 + p_CcNode->p_GlblMask,
29057 + p_CcNode->userSizeOfExtraction);
29058 + }
29059 + }
29060 +
29061 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
29062 + if (!add)
29063 + i++;
29064 + }
29065 + else
29066 + {
29067 + /* Copy existing action descriptors to the newly allocated Ad table */
29068 + p_AdTableOldTmp =
29069 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29070 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
29071 + FM_PCD_CC_AD_ENTRY_SIZE);
29072 +
29073 + /* Copy existing keys and their masks to the newly allocated keys match table */
29074 + p_KeysMatchTableNewTmp =
29075 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29076 + p_KeysMatchTableOldTmp =
29077 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
29078 +
29079 + if (p_CcNode->lclMask)
29080 + {
29081 + if (prvLclMask)
29082 + {
29083 + MemCpy8(
29084 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29085 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29086 + p_CcNode->ccKeySizeAccExtraction);
29087 + }
29088 + else
29089 + {
29090 + p_KeysMatchTableOldTmp =
29091 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29092 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29093 +
29094 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29095 + {
29096 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29097 + p_CcNode->ccKeySizeAccExtraction),
29098 + 0xff, p_CcNode->userSizeOfExtraction);
29099 + }
29100 + else
29101 + {
29102 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29103 + p_CcNode->ccKeySizeAccExtraction),
29104 + p_CcNode->p_GlblMask,
29105 + p_CcNode->userSizeOfExtraction);
29106 + }
29107 + }
29108 + }
29109 +
29110 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29111 + p_CcNode->ccKeySizeAccExtraction);
29112 +
29113 + i++;
29114 + }
29115 + }
29116 +
29117 + /* Miss action descriptor */
29118 + p_AdTableNewTmp =
29119 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29120 + p_AdTableOldTmp =
29121 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
29122 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29123 +
29124 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
29125 + {
29126 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
29127 + {
29128 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29129 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29130 + /* Update the manipulation which has to be updated from parameters of the port */
29131 + /* It's has to be updated with restrictions defined in the function */
29132 + err =
29133 + SetRequiredAction(
29134 + p_CcNode->h_FmPcd,
29135 + p_CcNode->shadowAction
29136 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29137 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29138 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29139 + 1, p_CcNodeInformation->h_CcNode);
29140 + if (err)
29141 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29142 +
29143 + err =
29144 + CcUpdateParam(
29145 + p_CcNode->h_FmPcd,
29146 + NULL,
29147 + NULL,
29148 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29149 + 1,
29150 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29151 + TRUE, p_CcNodeInformation->index,
29152 + p_CcNodeInformation->h_CcNode, TRUE);
29153 + if (err)
29154 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29155 + }
29156 + }
29157 +
29158 + if (p_CcNode->lclMask)
29159 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
29160 +
29161 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
29162 + p_AdditionalInfo->h_NodeForAdd =
29163 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
29164 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29165 + p_AdditionalInfo->h_ManipForAdd =
29166 + p_KeyParams->ccNextEngineParams.h_Manip;
29167 +
29168 +#if (DPAA_VERSION >= 11)
29169 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
29170 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
29171 + p_AdditionalInfo->h_FrmReplicForAdd =
29172 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
29173 +#endif /* (DPAA_VERSION >= 11) */
29174 +
29175 + if (!add)
29176 + {
29177 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29178 + == e_FM_PCD_CC)
29179 + p_AdditionalInfo->h_NodeForRmv =
29180 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29181 +
29182 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29183 + p_AdditionalInfo->h_ManipForRmv =
29184 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29185 +
29186 + /* If statistics were previously enabled, store the old statistics object to be released */
29187 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29188 + {
29189 + p_AdditionalInfo->p_StatsObjForRmv =
29190 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29191 + }
29192 +
29193 +#if (DPAA_VERSION >= 11)
29194 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29195 + == e_FM_PCD_FR)
29196 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29197 + p_AdditionalInfo->h_FrmReplicForRmv =
29198 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29199 +#endif /* (DPAA_VERSION >= 11) */
29200 + }
29201 +
29202 + return E_OK;
29203 +}
29204 +
29205 +static t_Error BuildNewNodeRemoveKey(
29206 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29207 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29208 +{
29209 + int i = 0, j = 0;
29210 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29211 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29212 + int size;
29213 + t_Error err = E_OK;
29214 +
29215 + /*save new numOfKeys*/
29216 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29217 +
29218 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29219 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29220 + if (err)
29221 + RETURN_ERROR(MAJOR, err, NO_MSG);
29222 +
29223 + /*update new Ad and new Key Table according to new requirement*/
29224 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29225 + {
29226 + if (j == keyIndex)
29227 + j++;
29228 +
29229 + if (j == p_CcNode->numOfKeys)
29230 + break;
29231 + p_AdTableNewTmp =
29232 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29233 + p_AdTableOldTmp =
29234 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29235 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29236 +
29237 + p_KeysMatchTableOldTmp =
29238 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29239 + p_KeysMatchTableNewTmp =
29240 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29241 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29242 + size * sizeof(uint8_t));
29243 + }
29244 +
29245 + p_AdTableNewTmp =
29246 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29247 + p_AdTableOldTmp =
29248 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29249 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29250 +
29251 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29252 + == e_FM_PCD_CC)
29253 + p_AdditionalInfo->h_NodeForRmv =
29254 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29255 +
29256 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29257 + p_AdditionalInfo->h_ManipForRmv =
29258 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29259 +
29260 + /* If statistics were previously enabled, store the old statistics object to be released */
29261 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29262 + {
29263 + p_AdditionalInfo->p_StatsObjForRmv =
29264 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29265 + }
29266 +
29267 +#if (DPAA_VERSION >= 11)
29268 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29269 + == e_FM_PCD_FR)
29270 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29271 + p_AdditionalInfo->h_FrmReplicForRmv =
29272 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29273 +#endif /* (DPAA_VERSION >= 11) */
29274 +
29275 + return E_OK;
29276 +}
29277 +
29278 +static t_Error BuildNewNodeModifyKey(
29279 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29280 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29281 +{
29282 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29283 + t_Error err = E_OK;
29284 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29285 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29286 + int size;
29287 + int i = 0, j = 0;
29288 + bool prvLclMask;
29289 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29290 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29291 +
29292 + prvLclMask = p_CcNode->lclMask;
29293 +
29294 + /* Check that new key is not require update of localMask */
29295 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29296 + if (err)
29297 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29298 +
29299 + /* Update internal data structure with new next engine for the given index */
29300 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29301 + p_CcNode->userSizeOfExtraction);
29302 +
29303 + if (p_Mask)
29304 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29305 + p_CcNode->userSizeOfExtraction);
29306 + else
29307 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29308 + p_CcNode->userSizeOfExtraction);
29309 +
29310 + /*function which build in the memory new KeyTbl, AdTbl*/
29311 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29312 + if (err)
29313 + RETURN_ERROR(MAJOR, err, NO_MSG);
29314 +
29315 + /*fill the New AdTable and New KeyTable*/
29316 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29317 + {
29318 + p_AdTableNewTmp =
29319 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29320 + p_AdTableOldTmp =
29321 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29322 +
29323 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29324 +
29325 + if (j == keyIndex)
29326 + {
29327 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29328 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29329 + {
29330 + /* As statistics were enabled, we need to update the existing
29331 + statistics descriptor with a new nullified counters. */
29332 + p_StatsObj = GetStatsObj(p_CcNode);
29333 + ASSERT_COND(p_StatsObj);
29334 +
29335 + SetStatsCounters(
29336 + p_AdTableNewTmp,
29337 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29338 + - p_FmPcd->physicalMuramBase)));
29339 +
29340 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29341 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29342 +
29343 + /* As we need to replace only the counters, we build a new statistics
29344 + object that holds the old AD and the new counters - this will be the
29345 + currently used statistics object.
29346 + The newly allocated AD is not required and may be released back to
29347 + the available objects with the previous counters pointer. */
29348 + p_StatsObj->h_StatsAd =
29349 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29350 +
29351 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29352 + tmpStatsObj.h_StatsAd;
29353 +
29354 + /* Store allocated statistics object */
29355 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29356 + p_StatsObj;
29357 +
29358 + /* As statistics were previously enabled, store the old statistics object to be released */
29359 + p_AdditionalInfo->p_StatsObjForRmv =
29360 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29361 + }
29362 +
29363 + p_KeysMatchTableNewTmp =
29364 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29365 +
29366 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29367 + p_CcNode->userSizeOfExtraction);
29368 +
29369 + if (p_CcNode->lclMask)
29370 + {
29371 + if (p_Mask)
29372 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29373 + p_CcNode->ccKeySizeAccExtraction),
29374 + p_Mask, p_CcNode->userSizeOfExtraction);
29375 + else
29376 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29377 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29378 + p_CcNode->ccKeySizeAccExtraction),
29379 + 0xff, p_CcNode->userSizeOfExtraction);
29380 + else
29381 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29382 + p_CcNode->ccKeySizeAccExtraction),
29383 + p_CcNode->p_GlblMask,
29384 + p_CcNode->userSizeOfExtraction);
29385 + }
29386 + }
29387 + else
29388 + {
29389 + p_KeysMatchTableNewTmp =
29390 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29391 + p_KeysMatchTableOldTmp =
29392 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29393 +
29394 + if (p_CcNode->lclMask)
29395 + {
29396 + if (prvLclMask)
29397 + MemCpy8(
29398 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29399 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29400 + p_CcNode->userSizeOfExtraction);
29401 + else
29402 + {
29403 + p_KeysMatchTableOldTmp =
29404 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29405 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29406 +
29407 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29408 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29409 + p_CcNode->ccKeySizeAccExtraction),
29410 + 0xff, p_CcNode->userSizeOfExtraction);
29411 + else
29412 + MemCpy8(
29413 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29414 + p_CcNode->p_GlblMask,
29415 + p_CcNode->userSizeOfExtraction);
29416 + }
29417 + }
29418 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29419 + p_CcNode->ccKeySizeAccExtraction);
29420 + }
29421 + }
29422 +
29423 + p_AdTableNewTmp =
29424 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29425 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29426 +
29427 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29428 +
29429 + return E_OK;
29430 +}
29431 +
29432 +static t_Error BuildNewNodeModifyNextEngine(
29433 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29434 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29435 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29436 +{
29437 + t_Error err = E_OK;
29438 + uint32_t requiredAction = 0;
29439 + t_List *p_Pos;
29440 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29441 + t_Handle p_Ad;
29442 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29443 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29444 + t_FmPcdStatsObj *p_StatsObj;
29445 + t_FmPcdCcStatsParams statsParams = { 0 };
29446 +
29447 + ASSERT_COND(p_CcNextEngineParams);
29448 +
29449 + /* check that new NIA is legal */
29450 + if (!p_AdditionalInfo->tree)
29451 + err = ValidateNextEngineParams(
29452 + h_FmPcd, p_CcNextEngineParams,
29453 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29454 + else
29455 + /* Statistics are not supported for CC root */
29456 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29457 + e_FM_PCD_CC_STATS_MODE_NONE);
29458 + if (err)
29459 + RETURN_ERROR(MAJOR, err, NO_MSG);
29460 +
29461 + /* Update internal data structure for next engine per index (index - key) */
29462 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29463 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29464 +
29465 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29466 + if (p_CcNextEngineParams->h_Manip)
29467 + {
29468 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29469 + &requiredAction);
29470 + if (err)
29471 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29472 + }
29473 +
29474 + if (!p_AdditionalInfo->tree)
29475 + {
29476 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29477 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29478 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29479 +
29480 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29481 + == e_FM_PCD_CC)
29482 + p_AdditionalInfo->h_NodeForRmv =
29483 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29484 +
29485 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29486 + p_AdditionalInfo->h_ManipForRmv =
29487 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29488 +
29489 +#if (DPAA_VERSION >= 11)
29490 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29491 + == e_FM_PCD_FR)
29492 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29493 + p_AdditionalInfo->h_FrmReplicForRmv =
29494 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29495 +#endif /* (DPAA_VERSION >= 11) */
29496 + }
29497 + else
29498 + {
29499 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29500 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29501 +
29502 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29503 + == e_FM_PCD_CC)
29504 + p_AdditionalInfo->h_NodeForRmv =
29505 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29506 +
29507 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29508 + p_AdditionalInfo->h_ManipForRmv =
29509 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29510 +
29511 +#if (DPAA_VERSION >= 11)
29512 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29513 + == e_FM_PCD_FR)
29514 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29515 + p_AdditionalInfo->h_FrmReplicForRmv =
29516 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29517 +#endif /* (DPAA_VERSION >= 11) */
29518 + }
29519 +
29520 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29521 + && p_CcNextEngineParams->h_Manip)
29522 + {
29523 + err = AllocAndFillAdForContLookupManip(
29524 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29525 + if (err)
29526 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29527 + }
29528 +
29529 + ASSERT_COND(p_Ad);
29530 +
29531 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29532 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29533 +
29534 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29535 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29536 + only the actual Nia-Ad should be modified. */
29537 + if ((!p_AdditionalInfo->tree)
29538 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29539 + && (p_CcNextEngineParams->statisticsEn))
29540 + ccNodeInfo.h_CcNode =
29541 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29542 +
29543 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29544 +
29545 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29546 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29547 + if (!p_Ad)
29548 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29549 + ("MURAM allocation for CC node action descriptor"));
29550 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29551 +
29552 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29553 + object that holds statistics AD and counters. */
29554 + if ((!p_AdditionalInfo->tree)
29555 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29556 + && (p_CcNextEngineParams->statisticsEn))
29557 + {
29558 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29559 + ASSERT_COND(p_StatsObj);
29560 +
29561 + /* Store allocated statistics object */
29562 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29563 + p_StatsObj;
29564 +
29565 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29566 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29567 +
29568 +#if (DPAA_VERSION >= 11)
29569 + statsParams.h_StatsFLRs =
29570 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29571 +
29572 +#endif /* (DPAA_VERSION >= 11) */
29573 +
29574 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29575 + }
29576 + else
29577 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29578 +
29579 + ccNodeInfo.h_CcNode = p_Ad;
29580 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29581 +
29582 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29583 + requiredAction;
29584 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29585 + UPDATE_CC_WITH_TREE;
29586 +
29587 + if (!p_AdditionalInfo->tree)
29588 + {
29589 + ASSERT_COND(p_FmPcdCcNode1);
29590 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29591 + {
29592 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29593 + {
29594 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29595 +
29596 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29597 + /* Update the manipulation which has to be updated from parameters of the port
29598 + it's has to be updated with restrictions defined in the function */
29599 +
29600 + err =
29601 + SetRequiredAction(
29602 + p_FmPcdCcNode1->h_FmPcd,
29603 + p_FmPcdCcNode1->shadowAction
29604 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29605 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29606 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29607 + if (err)
29608 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29609 +
29610 + err = CcUpdateParam(
29611 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29612 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29613 + p_Ad, TRUE, p_CcNodeInformation->index,
29614 + p_CcNodeInformation->h_CcNode, TRUE);
29615 + if (err)
29616 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29617 + }
29618 + }
29619 + }
29620 + else
29621 + {
29622 + ASSERT_COND(p_FmPcdCcTree);
29623 +
29624 + err =
29625 + SetRequiredAction(
29626 + h_FmPcd,
29627 + p_FmPcdCcTree->requiredAction
29628 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29629 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29630 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29631 + if (err)
29632 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29633 +
29634 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29635 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29636 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29637 + if (err)
29638 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29639 + }
29640 +
29641 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29642 + p_AdditionalInfo->h_NodeForAdd =
29643 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29644 + if (p_CcNextEngineParams->h_Manip)
29645 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29646 +
29647 + /* If statistics were previously enabled, but now are disabled,
29648 + store the old statistics object to be released */
29649 + if ((!p_AdditionalInfo->tree)
29650 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29651 + && (!p_CcNextEngineParams->statisticsEn))
29652 + {
29653 + p_AdditionalInfo->p_StatsObjForRmv =
29654 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29655 +
29656 +
29657 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29658 + }
29659 +#if (DPAA_VERSION >= 11)
29660 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29661 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29662 + p_AdditionalInfo->h_FrmReplicForAdd =
29663 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29664 +#endif /* (DPAA_VERSION >= 11) */
29665 +
29666 + return E_OK;
29667 +}
29668 +
29669 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29670 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29671 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29672 +{
29673 + t_CcNodeInformation *p_CcNodeInformation;
29674 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29675 + t_List *p_Pos;
29676 + int i = 0;
29677 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29678 + t_CcNodeInformation ccNodeInfo;
29679 +
29680 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29681 + {
29682 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29683 + p_NodePtrOnCurrentMdfNode =
29684 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29685 +
29686 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29687 +
29688 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29689 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29690 + {
29691 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29692 + == e_FM_PCD_CC)
29693 + {
29694 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29695 + == (t_Handle)p_CrntMdfNode)
29696 + {
29697 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29698 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29699 + else
29700 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29701 + p_AdTablePtOnCrntCurrentMdfNode =
29702 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29703 + else
29704 + p_AdTablePtOnCrntCurrentMdfNode =
29705 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29706 +
29707 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29708 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29709 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29710 +
29711 + if (!(*p_NextEngineParams))
29712 + *p_NextEngineParams =
29713 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29714 + }
29715 + }
29716 + }
29717 +
29718 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29719 + }
29720 +}
29721 +
29722 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29723 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29724 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29725 +{
29726 + t_CcNodeInformation *p_CcNodeInformation;
29727 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29728 + t_List *p_Pos;
29729 + int i = 0;
29730 + t_Handle p_AdTableTmp;
29731 + t_CcNodeInformation ccNodeInfo;
29732 +
29733 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29734 + {
29735 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29736 + p_TreePtrOnCurrentMdfNode =
29737 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29738 +
29739 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29740 +
29741 + /*search in the trees which exact index points on this current modified node for getting AD */
29742 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29743 + {
29744 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29745 + == e_FM_PCD_CC)
29746 + {
29747 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29748 + == (t_Handle)p_CrntMdfNode)
29749 + {
29750 + p_AdTableTmp =
29751 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29752 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29753 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29754 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29755 +
29756 + if (!(*p_NextEngineParams))
29757 + *p_NextEngineParams =
29758 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29759 + }
29760 + }
29761 + }
29762 +
29763 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29764 + }
29765 +}
29766 +
29767 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29768 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29769 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29770 +{
29771 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29772 + int i = 0, j = 0;
29773 + bool wasUpdate = FALSE;
29774 + t_FmPcdCcNode *p_CcNode = NULL;
29775 + t_FmPcdCcTree *p_FmPcdCcTree;
29776 + uint16_t numOfKeys;
29777 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29778 +
29779 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29780 +
29781 + if (!tree)
29782 + {
29783 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29784 + numOfKeys = p_CcNode->numOfKeys;
29785 +
29786 + /* node has to be pointed by another node or tree */
29787 +
29788 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29789 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29790 + if (!p_KeyAndNextEngineParams)
29791 + {
29792 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29793 + return NULL;
29794 + }
29795 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29796 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29797 +
29798 + if (ttlCheck)
29799 + {
29800 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29801 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29802 + {
29803 + XX_Free(p_KeyAndNextEngineParams);
29804 + 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"));
29805 + return NULL;
29806 + }
29807 + }
29808 +
29809 + if (hashCheck)
29810 + {
29811 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29812 + {
29813 + XX_Free(p_KeyAndNextEngineParams);
29814 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29815 + return NULL;
29816 + }
29817 + }
29818 + }
29819 + else
29820 + {
29821 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29822 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29823 +
29824 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29825 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29826 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29827 + if (!p_KeyAndNextEngineParams)
29828 + {
29829 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29830 + return NULL;
29831 + }
29832 + memcpy(p_KeyAndNextEngineParams,
29833 + p_FmPcdCcTree->keyAndNextEngineParams,
29834 + FM_PCD_MAX_NUM_OF_CC_GROUPS
29835 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29836 + }
29837 +
29838 + p_FmPcdModifyCcKeyAdditionalParams =
29839 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
29840 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29841 + if (!p_FmPcdModifyCcKeyAdditionalParams)
29842 + {
29843 + XX_Free(p_KeyAndNextEngineParams);
29844 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
29845 + return NULL;
29846 + }
29847 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
29848 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29849 +
29850 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
29851 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
29852 +
29853 + while (i < numOfKeys)
29854 + {
29855 + if ((j == keyIndex) && !wasUpdate)
29856 + {
29857 + if (modifyState == e_MODIFY_STATE_ADD)
29858 + j++;
29859 + else
29860 + if (modifyState == e_MODIFY_STATE_REMOVE)
29861 + i++;
29862 + wasUpdate = TRUE;
29863 + }
29864 + else
29865 + {
29866 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29867 + p_KeyAndNextEngineParams + i,
29868 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29869 + i++;
29870 + j++;
29871 + }
29872 + }
29873 +
29874 + if (keyIndex == numOfKeys)
29875 + {
29876 + if (modifyState == e_MODIFY_STATE_ADD)
29877 + j++;
29878 + }
29879 +
29880 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29881 + p_KeyAndNextEngineParams + numOfKeys,
29882 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29883 +
29884 + XX_Free(p_KeyAndNextEngineParams);
29885 +
29886 + return p_FmPcdModifyCcKeyAdditionalParams;
29887 +}
29888 +
29889 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
29890 + t_FmPcdCcNode *p_CcNode,
29891 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
29892 + t_List *h_OldLst, t_List *h_NewLst)
29893 +{
29894 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
29895 + t_CcNodeInformation ccNodeInfo = { 0 };
29896 + t_Handle h_NewAd;
29897 + t_Handle h_OrigAd = NULL;
29898 +
29899 + /* Building a list of all action descriptors that point to the previous node */
29900 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
29901 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29902 + &p_NextEngineParams);
29903 +
29904 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
29905 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29906 + &p_NextEngineParams);
29907 +
29908 + /* This node must be found as next engine of one of its previous nodes or trees*/
29909 + if (p_NextEngineParams)
29910 + {
29911 + /* Building a new action descriptor that points to the modified node */
29912 + h_NewAd = GetNewAd(p_CcNode, FALSE);
29913 + if (!h_NewAd)
29914 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
29915 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29916 +
29917 + h_OrigAd = p_CcNode->h_Ad;
29918 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
29919 + p_NextEngineParams);
29920 +
29921 + ccNodeInfo.h_CcNode = h_NewAd;
29922 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29923 +
29924 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
29925 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
29926 + }
29927 + return E_OK;
29928 +}
29929 +
29930 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
29931 +{
29932 + ASSERT_COND(p_FmPcdCcTree);
29933 +
29934 + /* this routine must be protected by the calling routine! */
29935 +
29936 + if (add)
29937 + p_FmPcdCcTree->owners++;
29938 + else
29939 + {
29940 + ASSERT_COND(p_FmPcdCcTree->owners);
29941 + p_FmPcdCcTree->owners--;
29942 + }
29943 +}
29944 +
29945 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
29946 +{
29947 + t_Error err = E_OK;
29948 + int i = 0;
29949 +
29950 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29951 + {
29952 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29953 + {
29954 + err =
29955 + FmPcdManipCheckParamsWithCcNodeParams(
29956 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
29957 + (t_Handle)p_CcNode);
29958 + if (err)
29959 + return err;
29960 + }
29961 + }
29962 +
29963 + return err;
29964 +}
29965 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
29966 + t_FmPcdCcNodeParams *p_CcNodeParam,
29967 + uint32_t *p_NumOfRanges,
29968 + uint32_t *p_CountersArraySize)
29969 +{
29970 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
29971 + uint32_t i;
29972 +
29973 + UNUSED(p_CcNodeParam);
29974 +
29975 + switch (statisticsMode)
29976 + {
29977 + case e_FM_PCD_CC_STATS_MODE_NONE:
29978 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29979 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
29980 + RETURN_ERROR(
29981 + MAJOR,
29982 + E_INVALID_VALUE,
29983 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
29984 + return E_OK;
29985 +
29986 + case e_FM_PCD_CC_STATS_MODE_FRAME:
29987 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
29988 + *p_NumOfRanges = 1;
29989 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29990 + return E_OK;
29991 +
29992 +#if (DPAA_VERSION >= 11)
29993 + case e_FM_PCD_CC_STATS_MODE_RMON:
29994 + {
29995 + uint16_t *p_FrameLengthRanges =
29996 + p_CcNodeParam->keysParams.frameLengthRanges;
29997 + uint32_t i;
29998 +
29999 + if (p_FrameLengthRanges[0] <= 0)
30000 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30001 +
30002 + if (p_FrameLengthRanges[0] == 0xFFFF)
30003 + {
30004 + *p_NumOfRanges = 1;
30005 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
30006 + return E_OK;
30007 + }
30008 +
30009 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
30010 + {
30011 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
30012 + RETURN_ERROR(
30013 + MAJOR,
30014 + E_INVALID_VALUE,
30015 + ("Frame length range must be larger at least by 1 from preceding range"));
30016 +
30017 + /* Stop when last range is reached */
30018 + if (p_FrameLengthRanges[i] == 0xFFFF)
30019 + break;
30020 + }
30021 +
30022 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
30023 + || (p_FrameLengthRanges[i] != 0xFFFF))
30024 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30025 + ("Last Frame length range must be 0xFFFF"));
30026 +
30027 + *p_NumOfRanges = i + 1;
30028 +
30029 + /* Allocate an extra counter for byte count, as counters
30030 + array always begins with byte count */
30031 + *p_CountersArraySize = (*p_NumOfRanges + 1)
30032 + * FM_PCD_CC_STATS_COUNTER_SIZE;
30033 +
30034 + }
30035 + return E_OK;
30036 +#endif /* (DPAA_VERSION >= 11) */
30037 +
30038 + default:
30039 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30040 + }
30041 +}
30042 +
30043 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30044 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30045 +{
30046 + int tmp = 0;
30047 + t_FmPcdCcKeyParams *p_KeyParams;
30048 + t_Error err;
30049 + uint32_t requiredAction = 0;
30050 +
30051 + /* Validate statistics parameters */
30052 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30053 + &(p_CcNode->numOfStatsFLRs),
30054 + &(p_CcNode->countersArraySize));
30055 + if (err)
30056 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30057 +
30058 + /* Validate next engine parameters on Miss */
30059 + err = ValidateNextEngineParams(
30060 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30061 + p_CcNode->statisticsMode);
30062 + if (err)
30063 + RETURN_ERROR(MAJOR, err,
30064 + ("For this node MissNextEngineParams are not valid"));
30065 +
30066 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30067 + {
30068 + err = FmPcdManipCheckParamsForCcNextEngine(
30069 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30070 + &requiredAction);
30071 + if (err)
30072 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30073 + }
30074 +
30075 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30076 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30077 + sizeof(t_FmPcdCcNextEngineParams));
30078 +
30079 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30080 + requiredAction;
30081 +
30082 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30083 + == e_FM_PCD_CC)
30084 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30085 + {
30086 + err =
30087 + AllocAndFillAdForContLookupManip(
30088 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30089 + if (err)
30090 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30091 + }
30092 +
30093 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30094 + {
30095 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30096 +
30097 + if (!p_KeyParams->p_Key)
30098 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
30099 +
30100 + err = ValidateNextEngineParams(h_FmPcd,
30101 + &p_KeyParams->ccNextEngineParams,
30102 + p_CcNode->statisticsMode);
30103 + if (err)
30104 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30105 +
30106 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
30107 + p_KeyParams->p_Mask);
30108 + if (err)
30109 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30110 +
30111 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30112 + {
30113 + err = FmPcdManipCheckParamsForCcNextEngine(
30114 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30115 + if (err)
30116 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30117 + }
30118 +
30119 + /* Store 'key' parameters - key, mask (if passed by the user) */
30120 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
30121 + p_CcNodeParam->keysParams.keySize);
30122 +
30123 + if (p_KeyParams->p_Mask)
30124 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
30125 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
30126 + else
30127 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
30128 + p_CcNodeParam->keysParams.keySize);
30129 +
30130 + /* Store next engine parameters */
30131 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30132 + &p_KeyParams->ccNextEngineParams,
30133 + sizeof(t_FmPcdCcNextEngineParams));
30134 +
30135 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30136 +
30137 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30138 + == e_FM_PCD_CC)
30139 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30140 + {
30141 + err =
30142 + AllocAndFillAdForContLookupManip(
30143 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30144 + if (err)
30145 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30146 + }
30147 + }
30148 +
30149 + if (p_CcNode->maxNumOfKeys)
30150 + {
30151 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
30152 + RETURN_ERROR(
30153 + MAJOR,
30154 + E_INVALID_VALUE,
30155 + ("Number of keys exceed the provided maximal number of keys"));
30156 + }
30157 +
30158 + *isKeyTblAlloc = TRUE;
30159 +
30160 + return E_OK;
30161 +}
30162 +
30163 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
30164 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30165 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30166 +{
30167 + int tmp = 0;
30168 + t_FmPcdCcKeyParams *p_KeyParams;
30169 + t_Error err;
30170 + uint8_t key = 0x01;
30171 + uint32_t requiredAction = 0;
30172 +
30173 + if (p_CcNode->numOfKeys != 1)
30174 + RETURN_ERROR(
30175 + MAJOR,
30176 + E_INVALID_VALUE,
30177 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
30178 +
30179 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
30180 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
30181 + RETURN_ERROR(
30182 + MAJOR,
30183 + E_INVALID_VALUE,
30184 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
30185 +
30186 + /* Validate statistics parameters */
30187 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30188 + &(p_CcNode->numOfStatsFLRs),
30189 + &(p_CcNode->countersArraySize));
30190 + if (err)
30191 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30192 +
30193 + err = ValidateNextEngineParams(
30194 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30195 + p_CcNodeParam->keysParams.statisticsMode);
30196 + if (err)
30197 + RETURN_ERROR(MAJOR, err,
30198 + ("For this node MissNextEngineParams are not valid"));
30199 +
30200 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30201 + {
30202 + err = FmPcdManipCheckParamsForCcNextEngine(
30203 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30204 + &requiredAction);
30205 + if (err)
30206 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30207 + }
30208 +
30209 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30210 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30211 + sizeof(t_FmPcdCcNextEngineParams));
30212 +
30213 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30214 + requiredAction;
30215 +
30216 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30217 + == e_FM_PCD_CC)
30218 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30219 + {
30220 + err =
30221 + AllocAndFillAdForContLookupManip(
30222 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30223 + if (err)
30224 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30225 + }
30226 +
30227 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30228 + {
30229 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30230 +
30231 + if (p_KeyParams->p_Mask)
30232 + RETURN_ERROR(
30233 + MAJOR,
30234 + E_INVALID_VALUE,
30235 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30236 +
30237 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30238 + RETURN_ERROR(
30239 + MAJOR,
30240 + E_INVALID_VALUE,
30241 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30242 +
30243 + err = ValidateNextEngineParams(h_FmPcd,
30244 + &p_KeyParams->ccNextEngineParams,
30245 + p_CcNode->statisticsMode);
30246 + if (err)
30247 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30248 +
30249 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30250 + {
30251 + err = FmPcdManipCheckParamsForCcNextEngine(
30252 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30253 + if (err)
30254 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30255 + }
30256 +
30257 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30258 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30259 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30260 +
30261 + /* Store NextEngine parameters */
30262 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30263 + &p_KeyParams->ccNextEngineParams,
30264 + sizeof(t_FmPcdCcNextEngineParams));
30265 +
30266 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30267 + == e_FM_PCD_CC)
30268 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30269 + {
30270 + err =
30271 + AllocAndFillAdForContLookupManip(
30272 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30273 + if (err)
30274 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30275 + }
30276 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30277 + }
30278 +
30279 + *isKeyTblAlloc = FALSE;
30280 +
30281 + return E_OK;
30282 +}
30283 +
30284 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30285 + t_FmPcdCcNodeParams *p_CcNodeParam,
30286 + t_FmPcdCcNode *p_CcNode,
30287 + bool *isKeyTblAlloc)
30288 +{
30289 + int tmp = 0, countOnes = 0;
30290 + t_FmPcdCcKeyParams *p_KeyParams;
30291 + t_Error err;
30292 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30293 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30294 + uint32_t requiredAction = 0;
30295 +
30296 + if (glblMask & 0x000f)
30297 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30298 + ("icIndxMask has to be with last nibble 0"));
30299 +
30300 + while (countMask)
30301 + {
30302 + countOnes++;
30303 + countMask = (uint16_t)(countMask >> 1);
30304 + }
30305 +
30306 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30307 + RETURN_ERROR(
30308 + MAJOR,
30309 + E_INVALID_VALUE,
30310 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30311 +
30312 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30313 + RETURN_ERROR(
30314 + MAJOR,
30315 + E_INVALID_VALUE,
30316 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30317 +
30318 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30319 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30320 + RETURN_ERROR(
30321 + MAJOR,
30322 + E_INVALID_VALUE,
30323 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30324 +
30325 + /* Validate statistics parameters */
30326 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30327 + &(p_CcNode->numOfStatsFLRs),
30328 + &(p_CcNode->countersArraySize));
30329 + if (err)
30330 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30331 +
30332 + err = ValidateNextEngineParams(
30333 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30334 + p_CcNode->statisticsMode);
30335 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30336 + RETURN_ERROR(
30337 + MAJOR,
30338 + err,
30339 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30340 +
30341 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30342 + {
30343 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30344 +
30345 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30346 + RETURN_ERROR(
30347 + MAJOR,
30348 + E_INVALID_VALUE,
30349 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30350 +
30351 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30352 + {
30353 + err = ValidateNextEngineParams(h_FmPcd,
30354 + &p_KeyParams->ccNextEngineParams,
30355 + p_CcNode->statisticsMode);
30356 + if (err)
30357 + RETURN_ERROR(
30358 + MAJOR,
30359 + err,
30360 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30361 +
30362 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30363 + {
30364 + err = FmPcdManipCheckParamsForCcNextEngine(
30365 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30366 + if (err)
30367 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30368 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30369 + requiredAction;
30370 + }
30371 +
30372 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30373 + &p_KeyParams->ccNextEngineParams,
30374 + sizeof(t_FmPcdCcNextEngineParams));
30375 +
30376 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30377 + == e_FM_PCD_CC)
30378 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30379 + {
30380 + err =
30381 + AllocAndFillAdForContLookupManip(
30382 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30383 + if (err)
30384 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30385 + }
30386 + }
30387 + else
30388 + {
30389 + err = ValidateNextEngineParams(h_FmPcd,
30390 + &p_KeyParams->ccNextEngineParams,
30391 + p_CcNode->statisticsMode);
30392 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30393 + RETURN_ERROR(
30394 + MAJOR,
30395 + err,
30396 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30397 + }
30398 + }
30399 +
30400 + *isKeyTblAlloc = FALSE;
30401 + cpu_to_be16s(&glblMask);
30402 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30403 +
30404 + return E_OK;
30405 +}
30406 +
30407 +static t_Error ModifyNextEngineParamNode(
30408 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30409 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30410 +{
30411 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30412 + t_FmPcd *p_FmPcd;
30413 + t_List h_OldPointersLst, h_NewPointersLst;
30414 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30415 + t_Error err = E_OK;
30416 +
30417 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30418 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30419 +
30420 + if (keyIndex >= p_CcNode->numOfKeys)
30421 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30422 + ("keyIndex > previously cleared last index + 1"));
30423 +
30424 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30425 +
30426 + INIT_LIST(&h_OldPointersLst);
30427 + INIT_LIST(&h_NewPointersLst);
30428 +
30429 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30430 + e_MODIFY_STATE_CHANGE, FALSE,
30431 + FALSE, FALSE);
30432 + if (!p_ModifyKeyParams)
30433 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30434 +
30435 + if (p_CcNode->maxNumOfKeys
30436 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30437 + {
30438 + XX_Free(p_ModifyKeyParams);
30439 + return ERROR_CODE(E_BUSY);
30440 + }
30441 +
30442 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30443 + p_FmPcdCcNextEngineParams,
30444 + &h_OldPointersLst, &h_NewPointersLst,
30445 + p_ModifyKeyParams);
30446 + if (err)
30447 + {
30448 + XX_Free(p_ModifyKeyParams);
30449 + if (p_CcNode->maxNumOfKeys)
30450 + RELEASE_LOCK(p_FmPcd->shadowLock);
30451 + RETURN_ERROR(MAJOR, err, NO_MSG);
30452 + }
30453 +
30454 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30455 + p_ModifyKeyParams, FALSE);
30456 +
30457 + if (p_CcNode->maxNumOfKeys)
30458 + RELEASE_LOCK(p_FmPcd->shadowLock);
30459 +
30460 + ReleaseLst(&h_OldPointersLst);
30461 + ReleaseLst(&h_NewPointersLst);
30462 +
30463 + return err;
30464 +}
30465 +
30466 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30467 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30468 +{
30469 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30470 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30471 + uint16_t i;
30472 +
30473 + ASSERT_COND(p_Key);
30474 + ASSERT_COND(p_KeyIndex);
30475 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30476 +
30477 + if (keySize != p_CcNode->userSizeOfExtraction)
30478 + RETURN_ERROR(
30479 + MINOR, E_INVALID_VALUE,
30480 + ("Key size doesn't match the extraction size of the node"));
30481 +
30482 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30483 + if (!p_Mask)
30484 + memset(tmpMask, 0xFF, keySize);
30485 +
30486 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30487 + {
30488 + /* Comparing received key */
30489 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30490 + == 0)
30491 + {
30492 + if (p_Mask)
30493 + {
30494 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30495 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30496 + keySize) == 0)
30497 + {
30498 + *p_KeyIndex = i;
30499 + return E_OK;
30500 + }
30501 + }
30502 + else
30503 + {
30504 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30505 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30506 + keySize) == 0)
30507 + {
30508 + *p_KeyIndex = i;
30509 + return E_OK;
30510 + }
30511 + }
30512 + }
30513 + }
30514 +
30515 + return ERROR_CODE(E_NOT_FOUND);
30516 +}
30517 +
30518 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30519 + bool isKeyTblAlloc,
30520 + uint32_t *p_MatchTableSize,
30521 + uint32_t *p_AdTableSize)
30522 +{
30523 + uint32_t shadowSize;
30524 + t_Error err;
30525 +
30526 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30527 + (if local mask support is requested) */
30528 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30529 + * p_CcNode->maxNumOfKeys;
30530 +
30531 + if (p_CcNode->maskSupport)
30532 + *p_MatchTableSize *= 2;
30533 +
30534 + /* Calculate next action descriptors table, including one more entry for miss */
30535 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30536 + * FM_PCD_CC_AD_ENTRY_SIZE);
30537 +
30538 + /* Calculate maximal shadow size of this node.
30539 + All shadow structures will be used for runtime modifications host command. If
30540 + keys table was allocated for this node, the keys table and next engines table may
30541 + be modified in run time (entries added or removed), so shadow tables are requires.
30542 + Otherwise, the only supported runtime modification is a specific next engine update
30543 + and this requires shadow memory of a single AD */
30544 +
30545 + /* Shadow size should be enough to hold the following 3 structures:
30546 + * 1 - an action descriptor */
30547 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30548 +
30549 + /* 2 - keys match table, if was allocated for the current node */
30550 + if (isKeyTblAlloc)
30551 + shadowSize += *p_MatchTableSize;
30552 +
30553 + /* 3 - next action descriptors table */
30554 + shadowSize += *p_AdTableSize;
30555 +
30556 + /* Update shadow to the calculated size */
30557 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30558 + FM_PCD_CC_AD_TABLE_ALIGN);
30559 + if (err != E_OK)
30560 + {
30561 + DeleteNode(p_CcNode);
30562 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30563 + }
30564 +
30565 + return E_OK;
30566 +}
30567 +
30568 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30569 +{
30570 + t_FmPcdStatsObj *p_StatsObj;
30571 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30572 + uint32_t i;
30573 +
30574 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30575 + if (!h_FmMuram)
30576 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30577 +
30578 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30579 + will be allocated to support runtime modifications */
30580 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30581 + {
30582 + /* Allocate list object structure */
30583 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30584 + if (!p_StatsObj)
30585 + {
30586 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30587 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30588 + }
30589 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30590 +
30591 + /* Allocate statistics AD from MURAM */
30592 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30593 + FM_PCD_CC_AD_ENTRY_SIZE,
30594 + FM_PCD_CC_AD_TABLE_ALIGN);
30595 + if (!h_StatsAd)
30596 + {
30597 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30598 + XX_Free(p_StatsObj);
30599 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30600 + ("MURAM allocation for statistics ADs"));
30601 + }
30602 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30603 +
30604 + /* Allocate statistics counters from MURAM */
30605 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30606 + h_FmMuram, p_CcNode->countersArraySize,
30607 + FM_PCD_CC_AD_TABLE_ALIGN);
30608 + if (!h_StatsCounters)
30609 + {
30610 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30611 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30612 + XX_Free(p_StatsObj);
30613 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30614 + ("MURAM allocation for statistics counters"));
30615 + }
30616 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30617 +
30618 + p_StatsObj->h_StatsAd = h_StatsAd;
30619 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30620 +
30621 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30622 + }
30623 +
30624 + return E_OK;
30625 +}
30626 +
30627 +static t_Error MatchTableGetKeyStatistics(
30628 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30629 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30630 +{
30631 + uint32_t *p_StatsCounters, i;
30632 +
30633 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30634 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30635 + ("Statistics were not enabled for this match table"));
30636 +
30637 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30638 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30639 + ("Statistics were not enabled for this key"));
30640 +
30641 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30642 +
30643 + p_StatsCounters =
30644 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30645 + ASSERT_COND(p_StatsCounters);
30646 +
30647 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30648 +
30649 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30650 + {
30651 + p_StatsCounters =
30652 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30653 +
30654 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30655 +
30656 +#if (DPAA_VERSION >= 11)
30657 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30658 + GET_UINT32(*p_StatsCounters);
30659 +#endif /* (DPAA_VERSION >= 11) */
30660 + }
30661 +
30662 + return E_OK;
30663 +}
30664 +
30665 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30666 + t_FmPcdCcNodeParams *p_CcNodeParam)
30667 +{
30668 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30669 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30670 + t_Error err = E_OK;
30671 + uint32_t tmp, keySize;
30672 + bool glblMask = FALSE;
30673 + t_FmPcdCcKeyParams *p_KeyParams;
30674 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30675 +#if (DPAA_VERSION >= 11)
30676 + t_Handle h_StatsFLRs;
30677 +#endif /* (DPAA_VERSION >= 11) */
30678 + bool fullField = FALSE;
30679 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30680 + bool isKeyTblAlloc, fromIc = FALSE;
30681 + uint32_t matchTableSize, adTableSize;
30682 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30683 + t_FmPcdStatsObj *p_StatsObj;
30684 + t_FmPcdCcStatsParams statsParams = { 0 };
30685 + t_Handle h_Manip;
30686 +
30687 + ASSERT_COND(h_FmPcd);
30688 + ASSERT_COND(p_CcNode);
30689 + ASSERT_COND(p_CcNodeParam);
30690 +
30691 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30692 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30693 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30694 +
30695 + p_CcNode->h_FmPcd = h_FmPcd;
30696 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30697 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30698 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30699 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30700 +
30701 + /* For backward compatibility - even if statistics mode is nullified,
30702 + we'll fix it to frame mode so we can support per-key request for
30703 + statistics using 'statisticsEn' in next engine parameters */
30704 + if (!p_CcNode->maxNumOfKeys
30705 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30706 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30707 +
30708 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30709 + if (!h_FmMuram)
30710 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30711 +
30712 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30713 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30714 + INIT_LIST(&p_CcNode->ccTreesLst);
30715 + INIT_LIST(&p_CcNode->availableStatsLst);
30716 +
30717 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30718 + if (!p_CcNode->h_Spinlock)
30719 + {
30720 + DeleteNode(p_CcNode);
30721 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30722 + }
30723 +
30724 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30725 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30726 + == HEADER_TYPE_IPv4)
30727 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30728 + == HEADER_TYPE_IPv6))
30729 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30730 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30731 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30732 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30733 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30734 + == NET_HEADER_FIELD_IPv4_TTL)))
30735 + {
30736 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30737 + &isKeyTblAlloc);
30738 + glblMask = FALSE;
30739 + }
30740 + else
30741 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30742 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30743 + == e_FM_PCD_EXTRACT_FROM_KEY)
30744 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30745 + == e_FM_PCD_EXTRACT_FROM_HASH)
30746 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30747 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30748 + {
30749 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30750 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30751 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30752 + {
30753 + DeleteNode(p_CcNode);
30754 + RETURN_ERROR(
30755 + MAJOR,
30756 + E_INVALID_VALUE,
30757 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30758 + }
30759 +
30760 + icCode = IcDefineCode(p_CcNodeParam);
30761 + fromIc = TRUE;
30762 + if (icCode == CC_PRIVATE_INFO_NONE)
30763 + {
30764 + DeleteNode(p_CcNode);
30765 + RETURN_ERROR(
30766 + MAJOR,
30767 + E_INVALID_STATE,
30768 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30769 + }
30770 +
30771 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30772 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30773 + {
30774 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30775 + &isKeyTblAlloc);
30776 + glblMask = TRUE;
30777 + }
30778 + else
30779 + {
30780 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30781 + &isKeyTblAlloc);
30782 + if (p_CcNode->glblMaskSize)
30783 + glblMask = TRUE;
30784 + }
30785 + }
30786 + else
30787 + {
30788 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30789 + if (p_CcNode->glblMaskSize)
30790 + glblMask = TRUE;
30791 + }
30792 +
30793 + if (err)
30794 + {
30795 + DeleteNode(p_CcNode);
30796 + RETURN_ERROR(MAJOR, err, NO_MSG);
30797 + }
30798 +
30799 + switch (p_CcNodeParam->extractCcParams.type)
30800 + {
30801 + case (e_FM_PCD_EXTRACT_BY_HDR):
30802 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30803 + {
30804 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30805 + p_CcNode->parseCode =
30806 + GetFullFieldParseCode(
30807 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30808 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30809 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30810 + GetSizeHeaderField(
30811 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30812 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30813 + &p_CcNode->sizeOfExtraction);
30814 + fullField = TRUE;
30815 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30816 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30817 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30818 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30819 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30820 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30821 + && (p_CcNode->parseCode
30822 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30823 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30824 + && (p_CcNode->parseCode
30825 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30826 + && glblMask)
30827 + {
30828 + glblMask = FALSE;
30829 + p_CcNode->glblMaskSize = 4;
30830 + p_CcNode->lclMask = TRUE;
30831 + }
30832 + break;
30833 +
30834 + case (e_FM_PCD_EXTRACT_FROM_HDR):
30835 + p_CcNode->sizeOfExtraction =
30836 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
30837 + p_CcNode->offset =
30838 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30839 + p_CcNode->userOffset =
30840 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30841 + p_CcNode->parseCode =
30842 + GetPrParseCode(
30843 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30844 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30845 + p_CcNode->offset, glblMask,
30846 + &p_CcNode->prsArrayOffset);
30847 + break;
30848 +
30849 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
30850 + p_CcNode->offset =
30851 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30852 + p_CcNode->userOffset =
30853 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30854 + p_CcNode->sizeOfExtraction =
30855 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
30856 + p_CcNode->parseCode =
30857 + GetFieldParseCode(
30858 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30859 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
30860 + p_CcNode->offset,
30861 + &p_CcNode->prsArrayOffset,
30862 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
30863 + break;
30864 +
30865 + default:
30866 + DeleteNode(p_CcNode);
30867 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30868 + }
30869 + break;
30870 +
30871 + case (e_FM_PCD_EXTRACT_NON_HDR):
30872 + /* get the field code for the generic extract */
30873 + p_CcNode->sizeOfExtraction =
30874 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
30875 + p_CcNode->offset =
30876 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30877 + p_CcNode->userOffset =
30878 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30879 + p_CcNode->parseCode = GetGenParseCode(
30880 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
30881 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
30882 + fromIc, icCode);
30883 +
30884 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
30885 + {
30886 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
30887 + {
30888 + DeleteNode(p_CcNode);
30889 + RETURN_ERROR(
30890 + MAJOR,
30891 + E_INVALID_SELECTION,
30892 + ("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)"));
30893 + }
30894 + }
30895 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
30896 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
30897 + {
30898 + p_CcNode->offset += p_CcNode->prsArrayOffset;
30899 + p_CcNode->prsArrayOffset = 0;
30900 + }
30901 + break;
30902 +
30903 + default:
30904 + DeleteNode(p_CcNode);
30905 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30906 + }
30907 +
30908 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
30909 + {
30910 + DeleteNode(p_CcNode);
30911 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
30912 + }
30913 +
30914 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
30915 + || !p_CcNode->sizeOfExtraction)
30916 + {
30917 + DeleteNode(p_CcNode);
30918 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30919 + ("sizeOfExatrction can not be greater than 56 and not 0"));
30920 + }
30921 +
30922 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
30923 + {
30924 + DeleteNode(p_CcNode);
30925 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30926 + ("keySize has to be equal to sizeOfExtraction"));
30927 + }
30928 +
30929 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
30930 +
30931 + if (!glblMask)
30932 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30933 +
30934 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
30935 + if (err != E_OK)
30936 + {
30937 + DeleteNode(p_CcNode);
30938 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30939 + ("keySize has to be equal to sizeOfExtraction"));
30940 + }
30941 +
30942 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
30943 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
30944 + &p_CcNode->ccKeySizeAccExtraction);
30945 +
30946 + /* If local mask is used, it is stored next to each key in the keys match table */
30947 + if (p_CcNode->lclMask)
30948 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
30949 + else
30950 + keySize = p_CcNode->ccKeySizeAccExtraction;
30951 +
30952 + /* Update CC shadow with maximal size required by this node */
30953 + if (p_CcNode->maxNumOfKeys)
30954 + {
30955 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
30956 + &adTableSize);
30957 + if (err != E_OK)
30958 + {
30959 + DeleteNode(p_CcNode);
30960 + RETURN_ERROR(MAJOR, err, NO_MSG);
30961 + }
30962 +
30963 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
30964 +
30965 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
30966 + {
30967 + err = AllocStatsObjs(p_CcNode);
30968 + if (err != E_OK)
30969 + {
30970 + DeleteNode(p_CcNode);
30971 + RETURN_ERROR(MAJOR, err, NO_MSG);
30972 + }
30973 + }
30974 +
30975 + /* If manipulation will be initialized before this node, it will use the table
30976 + descriptor in the AD table of previous node and this node will need an extra
30977 + AD as his table descriptor. */
30978 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
30979 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
30980 + if (!p_CcNode->h_TmpAd)
30981 + {
30982 + DeleteNode(p_CcNode);
30983 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30984 + ("MURAM allocation for CC action descriptor"));
30985 + }
30986 + }
30987 + else
30988 + {
30989 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
30990 + * (p_CcNode->numOfKeys + 1));
30991 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
30992 + * (p_CcNode->numOfKeys + 1));
30993 + }
30994 +
30995 +#if (DPAA_VERSION >= 11)
30996 + switch (p_CcNode->statisticsMode)
30997 + {
30998 +
30999 + case e_FM_PCD_CC_STATS_MODE_RMON:
31000 + /* If RMON statistics or RMON conditional statistics modes are requested,
31001 + allocate frame length ranges array */
31002 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
31003 + h_FmMuram,
31004 + (uint32_t)(p_CcNode->numOfStatsFLRs)
31005 + * FM_PCD_CC_STATS_FLR_SIZE,
31006 + FM_PCD_CC_AD_TABLE_ALIGN);
31007 +
31008 + if (!p_CcNode->h_StatsFLRs)
31009 + {
31010 + DeleteNode(p_CcNode);
31011 + RETURN_ERROR(
31012 + MAJOR, E_NO_MEMORY,
31013 + ("MURAM allocation for CC frame length ranges array"));
31014 + }
31015 +
31016 + /* Initialize using value received from the user */
31017 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
31018 + {
31019 + uint16_t flr =
31020 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
31021 +
31022 + h_StatsFLRs =
31023 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
31024 +
31025 + MemCpy8(h_StatsFLRs,
31026 + &flr,
31027 + FM_PCD_CC_STATS_FLR_SIZE);
31028 + }
31029 + break;
31030 +
31031 + default:
31032 + break;
31033 + }
31034 +#endif /* (DPAA_VERSION >= 11) */
31035 +
31036 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
31037 + identification, IPv6 hop count identification, etc. */
31038 + if (isKeyTblAlloc)
31039 + {
31040 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
31041 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
31042 + if (!p_CcNode->h_KeysMatchTable)
31043 + {
31044 + DeleteNode(p_CcNode);
31045 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31046 + ("MURAM allocation for CC node key match table"));
31047 + }
31048 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
31049 + }
31050 +
31051 + /* Allocate action descriptors table */
31052 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
31053 + FM_PCD_CC_AD_TABLE_ALIGN);
31054 + if (!p_CcNode->h_AdTable)
31055 + {
31056 + DeleteNode(p_CcNode);
31057 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31058 + ("MURAM allocation for CC node action descriptors table"));
31059 + }
31060 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
31061 +
31062 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
31063 + p_AdTableTmp = p_CcNode->h_AdTable;
31064 +
31065 + /* For each key, create the key and the next step AD */
31066 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31067 + {
31068 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31069 +
31070 + if (p_KeysMatchTblTmp)
31071 + {
31072 + /* Copy the key */
31073 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
31074 + p_CcNode->sizeOfExtraction);
31075 +
31076 + /* Copy the key mask or initialize it to 0xFF..F */
31077 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
31078 + {
31079 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
31080 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31081 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31082 + }
31083 + else
31084 + if (p_CcNode->lclMask)
31085 + {
31086 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
31087 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31088 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31089 + }
31090 +
31091 + p_KeysMatchTblTmp =
31092 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
31093 + }
31094 +
31095 + /* Create the next action descriptor in the match table */
31096 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
31097 + {
31098 + p_StatsObj = GetStatsObj(p_CcNode);
31099 + ASSERT_COND(p_StatsObj);
31100 +
31101 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31102 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31103 +#if (DPAA_VERSION >= 11)
31104 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31105 +
31106 +#endif /* (DPAA_VERSION >= 11) */
31107 + NextStepAd(p_AdTableTmp, &statsParams,
31108 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
31109 +
31110 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31111 + }
31112 + else
31113 + {
31114 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
31115 + p_FmPcd);
31116 +
31117 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31118 + }
31119 +
31120 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31121 + }
31122 +
31123 + /* Update next engine for the 'miss' entry */
31124 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
31125 + {
31126 + p_StatsObj = GetStatsObj(p_CcNode);
31127 + ASSERT_COND(p_StatsObj);
31128 +
31129 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
31130 + allocated by the hash table. So, if this node is a bucket of a hash table,
31131 + we'll replace the locally allocated counters with the shared counters. */
31132 + if (p_CcNode->isHashBucket)
31133 + {
31134 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
31135 +
31136 + /* Store original counters pointer and replace it with mutual preallocated pointer */
31137 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
31138 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
31139 + }
31140 +
31141 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31142 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31143 +#if (DPAA_VERSION >= 11)
31144 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31145 +
31146 +#endif /* (DPAA_VERSION >= 11) */
31147 +
31148 + NextStepAd(p_AdTableTmp, &statsParams,
31149 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31150 + p_FmPcd);
31151 +
31152 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31153 + }
31154 + else
31155 + {
31156 + NextStepAd(p_AdTableTmp, NULL,
31157 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31158 + p_FmPcd);
31159 +
31160 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31161 + }
31162 +
31163 + /* This parameter will be used to initialize the "key length" field in the action descriptor
31164 + that points to this node and it should be 0 for full field extraction */
31165 + if (fullField == TRUE)
31166 + p_CcNode->sizeOfExtraction = 0;
31167 +
31168 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31169 + {
31170 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31171 + == e_FM_PCD_CC)
31172 + {
31173 + p_FmPcdCcNextNode =
31174 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
31175 + p_CcInformation = FindNodeInfoInReleventLst(
31176 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
31177 + p_FmPcdCcNextNode->h_Spinlock);
31178 + if (!p_CcInformation)
31179 + {
31180 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31181 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31182 + ccNodeInfo.index = 1;
31183 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
31184 + &ccNodeInfo,
31185 + p_FmPcdCcNextNode->h_Spinlock);
31186 + }
31187 + else
31188 + p_CcInformation->index++;
31189 +
31190 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31191 + {
31192 + h_Manip =
31193 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31194 + p_CcInformation = FindNodeInfoInReleventLst(
31195 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31196 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31197 + if (!p_CcInformation)
31198 + {
31199 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31200 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31201 + ccNodeInfo.index = 1;
31202 + EnqueueNodeInfoToRelevantLst(
31203 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31204 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31205 + }
31206 + else
31207 + p_CcInformation->index++;
31208 + }
31209 + }
31210 + }
31211 +
31212 + p_AdTableTmp = p_CcNode->h_AdTable;
31213 +
31214 + if (!FmPcdLockTryLockAll(h_FmPcd))
31215 + {
31216 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31217 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31218 + return ERROR_CODE(E_BUSY);
31219 + }
31220 +
31221 + /* Required action for each next engine */
31222 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31223 + {
31224 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31225 + {
31226 + err = SetRequiredAction(
31227 + h_FmPcd,
31228 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31229 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31230 + NULL);
31231 + if (err)
31232 + {
31233 + FmPcdLockUnlockAll(h_FmPcd);
31234 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31235 + RETURN_ERROR(MAJOR, err, NO_MSG);
31236 + }
31237 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31238 + }
31239 + }
31240 +
31241 + FmPcdLockUnlockAll(h_FmPcd);
31242 +
31243 + return E_OK;
31244 +}
31245 +/************************** End of static functions **************************/
31246 +
31247 +/*****************************************************************************/
31248 +/* Inter-module API routines */
31249 +/*****************************************************************************/
31250 +
31251 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31252 + t_Handle h_Spinlock)
31253 +{
31254 + t_CcNodeInformation *p_CcInformation;
31255 + t_List *p_Pos;
31256 + uint32_t intFlags;
31257 +
31258 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31259 +
31260 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31261 + p_Pos = LIST_NEXT(p_Pos))
31262 + {
31263 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31264 +
31265 + ASSERT_COND(p_CcInformation->h_CcNode);
31266 +
31267 + if (p_CcInformation->h_CcNode == h_Info)
31268 + {
31269 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31270 + return p_CcInformation;
31271 + }
31272 + }
31273 +
31274 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31275 +
31276 + return NULL;
31277 +}
31278 +
31279 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31280 + t_Handle h_Spinlock)
31281 +{
31282 + t_CcNodeInformation *p_CcInformation;
31283 + uint32_t intFlags = 0;
31284 +
31285 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31286 + sizeof(t_CcNodeInformation));
31287 +
31288 + if (p_CcInformation)
31289 + {
31290 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31291 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31292 + INIT_LIST(&p_CcInformation->node);
31293 +
31294 + if (h_Spinlock)
31295 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31296 +
31297 + LIST_AddToTail(&p_CcInformation->node, p_List);
31298 +
31299 + if (h_Spinlock)
31300 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31301 + }
31302 + else
31303 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31304 +}
31305 +
31306 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31307 + t_Handle h_Spinlock)
31308 +{
31309 + t_CcNodeInformation *p_CcInformation = NULL;
31310 + uint32_t intFlags = 0;
31311 + t_List *p_Pos;
31312 +
31313 + if (h_Spinlock)
31314 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31315 +
31316 + if (LIST_IsEmpty(p_List))
31317 + {
31318 + XX_RestoreAllIntr(intFlags);
31319 + return;
31320 + }
31321 +
31322 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31323 + p_Pos = LIST_NEXT(p_Pos))
31324 + {
31325 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31326 + ASSERT_COND(p_CcInformation);
31327 + ASSERT_COND(p_CcInformation->h_CcNode);
31328 + if (p_CcInformation->h_CcNode == h_Info)
31329 + break;
31330 + }
31331 +
31332 + if (p_CcInformation)
31333 + {
31334 + LIST_DelAndInit(&p_CcInformation->node);
31335 + XX_Free(p_CcInformation);
31336 + }
31337 +
31338 + if (h_Spinlock)
31339 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31340 +}
31341 +
31342 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31343 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31344 + t_FmPcd *p_FmPcd)
31345 +{
31346 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31347 + {
31348 + case (e_FM_PCD_KG):
31349 + case (e_FM_PCD_PLCR):
31350 + case (e_FM_PCD_DONE):
31351 + /* if NIA is not CC, create a "result" type AD */
31352 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31353 + p_FmPcdCcNextEngineParams);
31354 + break;
31355 +#if (DPAA_VERSION >= 11)
31356 + case (e_FM_PCD_FR):
31357 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31358 + {
31359 + FillAdOfTypeContLookup(
31360 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31361 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31362 + p_FmPcdCcNextEngineParams->h_Manip,
31363 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31364 + FrmReplicGroupUpdateOwner(
31365 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31366 + TRUE/* add */);
31367 + }
31368 + break;
31369 +#endif /* (DPAA_VERSION >= 11) */
31370 +
31371 + case (e_FM_PCD_CC):
31372 + /* if NIA is not CC, create a TD to continue the CC lookup */
31373 + FillAdOfTypeContLookup(
31374 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31375 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31376 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31377 +
31378 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31379 + TRUE);
31380 + break;
31381 +
31382 + default:
31383 + return;
31384 + }
31385 +}
31386 +
31387 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31388 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31389 + bool createSchemes)
31390 +{
31391 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31392 + t_FmPcdCcNextEngineParams nextEngineParams;
31393 + t_NetEnvParams netEnvParams;
31394 + t_Handle h_Ad;
31395 + bool isIpv6Present;
31396 + uint8_t ipv4GroupId, ipv6GroupId;
31397 + t_Error err;
31398 +
31399 + ASSERT_COND(p_FmPcdCcTree);
31400 +
31401 + /* this routine must be protected by the calling routine! */
31402 +
31403 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31404 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31405 +
31406 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31407 +
31408 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31409 +
31410 + if (isIpv6Present
31411 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31412 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31413 +
31414 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31415 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31416 +
31417 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31418 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31419 +
31420 + /* Lock tree */
31421 + err = CcRootTryLock(p_FmPcdCcTree);
31422 + if (err)
31423 + return ERROR_CODE(E_BUSY);
31424 +
31425 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31426 + {
31427 + CcRootReleaseLock(p_FmPcdCcTree);
31428 + return E_OK;
31429 + }
31430 +
31431 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31432 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31433 + {
31434 + CcRootReleaseLock(p_FmPcdCcTree);
31435 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31436 + ("This tree was previously updated with different IPR"));
31437 + }
31438 +
31439 + /* Initialize IPR for the first time for this tree */
31440 + if (isIpv6Present)
31441 + {
31442 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31443 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31444 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31445 +
31446 + if (createSchemes)
31447 + {
31448 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31449 + p_FmPcdCcTree,
31450 + h_IpReassemblyManip, FALSE,
31451 + ipv6GroupId);
31452 + if (err)
31453 + {
31454 + p_FmPcdCcTree->numOfGrps--;
31455 + CcRootReleaseLock(p_FmPcdCcTree);
31456 + RETURN_ERROR(MAJOR, err, NO_MSG);
31457 + }
31458 + }
31459 +
31460 + NextStepAd(
31461 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31462 + NULL, &nextEngineParams, h_FmPcd);
31463 + }
31464 +
31465 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31466 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31467 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31468 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31469 +
31470 + if (createSchemes)
31471 + {
31472 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31473 + h_IpReassemblyManip, TRUE,
31474 + ipv4GroupId);
31475 + if (err)
31476 + {
31477 + p_FmPcdCcTree->numOfGrps--;
31478 + if (isIpv6Present)
31479 + {
31480 + p_FmPcdCcTree->numOfGrps--;
31481 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31482 + }
31483 + CcRootReleaseLock(p_FmPcdCcTree);
31484 + RETURN_ERROR(MAJOR, err, NO_MSG);
31485 + }
31486 + }
31487 +
31488 + NextStepAd(
31489 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31490 + NULL, &nextEngineParams, h_FmPcd);
31491 +
31492 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31493 +
31494 + CcRootReleaseLock(p_FmPcdCcTree);
31495 +
31496 + return E_OK;
31497 +}
31498 +
31499 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31500 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31501 + bool createSchemes)
31502 +{
31503 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31504 + t_FmPcdCcNextEngineParams nextEngineParams;
31505 + t_NetEnvParams netEnvParams;
31506 + t_Handle h_Ad;
31507 + uint8_t groupId;
31508 + t_Error err;
31509 +
31510 + ASSERT_COND(p_FmPcdCcTree);
31511 +
31512 + /* this routine must be protected by the calling routine! */
31513 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31514 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31515 +
31516 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31517 +
31518 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31519 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31520 +
31521 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31522 + nextEngineParams.h_Manip = h_ReassemblyManip;
31523 +
31524 + /* Lock tree */
31525 + err = CcRootTryLock(p_FmPcdCcTree);
31526 + if (err)
31527 + return ERROR_CODE(E_BUSY);
31528 +
31529 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31530 + {
31531 + CcRootReleaseLock(p_FmPcdCcTree);
31532 + return E_OK;
31533 + }
31534 +
31535 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31536 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31537 + {
31538 + CcRootReleaseLock(p_FmPcdCcTree);
31539 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31540 + ("This tree was previously updated with different CPR"));
31541 + }
31542 +
31543 + groupId = p_FmPcdCcTree->numOfGrps++;
31544 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31545 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31546 +
31547 + if (createSchemes)
31548 + {
31549 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31550 + p_FmPcdCcTree,
31551 + h_ReassemblyManip, groupId);
31552 + if (err)
31553 + {
31554 + p_FmPcdCcTree->numOfGrps--;
31555 + CcRootReleaseLock(p_FmPcdCcTree);
31556 + RETURN_ERROR(MAJOR, err, NO_MSG);
31557 + }
31558 + }
31559 +
31560 + NextStepAd(
31561 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31562 + NULL, &nextEngineParams, h_FmPcd);
31563 +
31564 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31565 +
31566 + CcRootReleaseLock(p_FmPcdCcTree);
31567 +
31568 + return E_OK;
31569 +}
31570 +
31571 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31572 +{
31573 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31574 +
31575 + ASSERT_COND(p_FmPcdCcTree);
31576 +
31577 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31578 +}
31579 +
31580 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31581 + t_Handle h_SavedManipParams)
31582 +{
31583 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31584 +
31585 + ASSERT_COND(p_FmPcdCcTree);
31586 +
31587 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31588 +}
31589 +
31590 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31591 +{
31592 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31593 +
31594 + ASSERT_COND(p_CcNode);
31595 +
31596 + return p_CcNode->parseCode;
31597 +}
31598 +
31599 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31600 +{
31601 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31602 +
31603 + ASSERT_COND(p_CcNode);
31604 +
31605 + return p_CcNode->offset;
31606 +}
31607 +
31608 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31609 +{
31610 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31611 +
31612 + ASSERT_COND(p_CcNode);
31613 +
31614 + return p_CcNode->numOfKeys;
31615 +}
31616 +
31617 +t_Error FmPcdCcModifyNextEngineParamTree(
31618 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31619 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31620 +{
31621 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31622 + t_FmPcd *p_FmPcd;
31623 + t_List h_OldPointersLst, h_NewPointersLst;
31624 + uint16_t keyIndex;
31625 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31626 + t_Error err = E_OK;
31627 +
31628 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31629 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31630 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31631 +
31632 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31633 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31634 + ("grpId you asked > numOfGroup of relevant tree"));
31635 +
31636 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31637 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31638 +
31639 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31640 +
31641 + INIT_LIST(&h_OldPointersLst);
31642 + INIT_LIST(&h_NewPointersLst);
31643 +
31644 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31645 + + index);
31646 +
31647 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31648 + e_MODIFY_STATE_CHANGE, FALSE,
31649 + FALSE, TRUE);
31650 + if (!p_ModifyKeyParams)
31651 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31652 +
31653 + p_ModifyKeyParams->tree = TRUE;
31654 +
31655 + if (p_FmPcd->p_CcShadow
31656 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31657 + {
31658 + XX_Free(p_ModifyKeyParams);
31659 + return ERROR_CODE(E_BUSY);
31660 + }
31661 +
31662 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31663 + p_FmPcdCcNextEngineParams,
31664 + &h_OldPointersLst, &h_NewPointersLst,
31665 + p_ModifyKeyParams);
31666 + if (err)
31667 + {
31668 + XX_Free(p_ModifyKeyParams);
31669 + RETURN_ERROR(MAJOR, err, NO_MSG);
31670 + }
31671 +
31672 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31673 + p_ModifyKeyParams, FALSE);
31674 +
31675 + if (p_FmPcd->p_CcShadow)
31676 + RELEASE_LOCK(p_FmPcd->shadowLock);
31677 +
31678 + ReleaseLst(&h_OldPointersLst);
31679 + ReleaseLst(&h_NewPointersLst);
31680 +
31681 + return err;
31682 +
31683 +}
31684 +
31685 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31686 + uint16_t keyIndex)
31687 +{
31688 +
31689 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31690 + t_FmPcd *p_FmPcd;
31691 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31692 + t_List h_OldPointersLst, h_NewPointersLst;
31693 + bool useShadowStructs = FALSE;
31694 + t_Error err = E_OK;
31695 +
31696 + if (keyIndex >= p_CcNode->numOfKeys)
31697 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31698 + ("impossible to remove key when numOfKeys <= keyIndex"));
31699 +
31700 + if (p_CcNode->h_FmPcd != h_FmPcd)
31701 + RETURN_ERROR(
31702 + MAJOR,
31703 + E_INVALID_VALUE,
31704 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31705 +
31706 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31707 +
31708 + INIT_LIST(&h_OldPointersLst);
31709 + INIT_LIST(&h_NewPointersLst);
31710 +
31711 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31712 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31713 + FALSE);
31714 + if (!p_ModifyKeyParams)
31715 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31716 +
31717 + if (p_CcNode->maxNumOfKeys)
31718 + {
31719 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31720 + {
31721 + XX_Free(p_ModifyKeyParams);
31722 + return ERROR_CODE(E_BUSY);
31723 + }
31724 +
31725 + useShadowStructs = TRUE;
31726 + }
31727 +
31728 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31729 + if (err)
31730 + {
31731 + XX_Free(p_ModifyKeyParams);
31732 + if (p_CcNode->maxNumOfKeys)
31733 + RELEASE_LOCK(p_FmPcd->shadowLock);
31734 + RETURN_ERROR(MAJOR, err, NO_MSG);
31735 + }
31736 +
31737 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31738 + &h_OldPointersLst,
31739 + &h_NewPointersLst);
31740 + if (err)
31741 + {
31742 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31743 + XX_Free(p_ModifyKeyParams);
31744 + if (p_CcNode->maxNumOfKeys)
31745 + RELEASE_LOCK(p_FmPcd->shadowLock);
31746 + RETURN_ERROR(MAJOR, err, NO_MSG);
31747 + }
31748 +
31749 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31750 + p_ModifyKeyParams, useShadowStructs);
31751 +
31752 + if (p_CcNode->maxNumOfKeys)
31753 + RELEASE_LOCK(p_FmPcd->shadowLock);
31754 +
31755 + ReleaseLst(&h_OldPointersLst);
31756 + ReleaseLst(&h_NewPointersLst);
31757 +
31758 + return err;
31759 +}
31760 +
31761 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31762 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31763 + uint8_t *p_Mask)
31764 +{
31765 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31766 + t_FmPcd *p_FmPcd;
31767 + t_List h_OldPointersLst, h_NewPointersLst;
31768 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31769 + uint16_t tmpKeyIndex;
31770 + bool useShadowStructs = FALSE;
31771 + t_Error err = E_OK;
31772 +
31773 + if (keyIndex >= p_CcNode->numOfKeys)
31774 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31775 + ("keyIndex > previously cleared last index + 1"));
31776 +
31777 + if (keySize != p_CcNode->userSizeOfExtraction)
31778 + RETURN_ERROR(
31779 + MAJOR,
31780 + E_INVALID_VALUE,
31781 + ("size for ModifyKey has to be the same as defined in SetNode"));
31782 +
31783 + if (p_CcNode->h_FmPcd != h_FmPcd)
31784 + RETURN_ERROR(
31785 + MAJOR,
31786 + E_INVALID_VALUE,
31787 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31788 +
31789 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31790 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31791 + RETURN_ERROR(
31792 + MINOR,
31793 + E_ALREADY_EXISTS,
31794 + ("The received key and mask pair was already found in the match table of the provided node"));
31795 +
31796 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31797 +
31798 + INIT_LIST(&h_OldPointersLst);
31799 + INIT_LIST(&h_NewPointersLst);
31800 +
31801 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31802 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31803 + FALSE);
31804 + if (!p_ModifyKeyParams)
31805 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31806 +
31807 + if (p_CcNode->maxNumOfKeys)
31808 + {
31809 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31810 + {
31811 + XX_Free(p_ModifyKeyParams);
31812 + return ERROR_CODE(E_BUSY);
31813 + }
31814 +
31815 + useShadowStructs = TRUE;
31816 + }
31817 +
31818 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31819 + p_ModifyKeyParams);
31820 + if (err)
31821 + {
31822 + XX_Free(p_ModifyKeyParams);
31823 + if (p_CcNode->maxNumOfKeys)
31824 + RELEASE_LOCK(p_FmPcd->shadowLock);
31825 + RETURN_ERROR(MAJOR, err, NO_MSG);
31826 + }
31827 +
31828 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31829 + &h_OldPointersLst,
31830 + &h_NewPointersLst);
31831 + if (err)
31832 + {
31833 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31834 + XX_Free(p_ModifyKeyParams);
31835 + if (p_CcNode->maxNumOfKeys)
31836 + RELEASE_LOCK(p_FmPcd->shadowLock);
31837 + RETURN_ERROR(MAJOR, err, NO_MSG);
31838 + }
31839 +
31840 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31841 + p_ModifyKeyParams, useShadowStructs);
31842 +
31843 + if (p_CcNode->maxNumOfKeys)
31844 + RELEASE_LOCK(p_FmPcd->shadowLock);
31845 +
31846 + ReleaseLst(&h_OldPointersLst);
31847 + ReleaseLst(&h_NewPointersLst);
31848 +
31849 + return err;
31850 +}
31851 +
31852 +t_Error FmPcdCcModifyMissNextEngineParamNode(
31853 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31854 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31855 +{
31856 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31857 + t_FmPcd *p_FmPcd;
31858 + t_List h_OldPointersLst, h_NewPointersLst;
31859 + uint16_t keyIndex;
31860 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31861 + t_Error err = E_OK;
31862 +
31863 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
31864 +
31865 + keyIndex = p_CcNode->numOfKeys;
31866 +
31867 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31868 +
31869 + INIT_LIST(&h_OldPointersLst);
31870 + INIT_LIST(&h_NewPointersLst);
31871 +
31872 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31873 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
31874 + FALSE);
31875 + if (!p_ModifyKeyParams)
31876 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31877 +
31878 + if (p_CcNode->maxNumOfKeys
31879 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31880 + {
31881 + XX_Free(p_ModifyKeyParams);
31882 + return ERROR_CODE(E_BUSY);
31883 + }
31884 +
31885 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
31886 + p_FmPcdCcNextEngineParams,
31887 + &h_OldPointersLst, &h_NewPointersLst,
31888 + p_ModifyKeyParams);
31889 + if (err)
31890 + {
31891 + XX_Free(p_ModifyKeyParams);
31892 + if (p_CcNode->maxNumOfKeys)
31893 + RELEASE_LOCK(p_FmPcd->shadowLock);
31894 + RETURN_ERROR(MAJOR, err, NO_MSG);
31895 + }
31896 +
31897 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31898 + p_ModifyKeyParams, FALSE);
31899 +
31900 + if (p_CcNode->maxNumOfKeys)
31901 + RELEASE_LOCK(p_FmPcd->shadowLock);
31902 +
31903 + ReleaseLst(&h_OldPointersLst);
31904 + ReleaseLst(&h_NewPointersLst);
31905 +
31906 + return err;
31907 +}
31908 +
31909 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31910 + uint16_t keyIndex, uint8_t keySize,
31911 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31912 +{
31913 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31914 + t_FmPcd *p_FmPcd;
31915 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31916 + t_List h_OldPointersLst, h_NewPointersLst;
31917 + bool useShadowStructs = FALSE;
31918 + uint16_t tmpKeyIndex;
31919 + t_Error err = E_OK;
31920 +
31921 + if (keyIndex > p_CcNode->numOfKeys)
31922 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
31923 + ("keyIndex > previously cleared last index + 1"));
31924 +
31925 + if (keySize != p_CcNode->userSizeOfExtraction)
31926 + RETURN_ERROR(
31927 + MAJOR,
31928 + E_INVALID_VALUE,
31929 + ("keySize has to be defined as it was defined in initialization step"));
31930 +
31931 + if (p_CcNode->h_FmPcd != h_FmPcd)
31932 + RETURN_ERROR(
31933 + MAJOR,
31934 + E_INVALID_VALUE,
31935 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31936 +
31937 + if (p_CcNode->maxNumOfKeys)
31938 + {
31939 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
31940 + RETURN_ERROR(
31941 + MAJOR,
31942 + E_FULL,
31943 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
31944 + }
31945 + else
31946 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
31947 + RETURN_ERROR(
31948 + MAJOR,
31949 + E_INVALID_VALUE,
31950 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
31951 +
31952 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31953 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31954 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31955 + RETURN_ERROR(
31956 + MAJOR,
31957 + E_ALREADY_EXISTS,
31958 + ("The received key and mask pair was already found in the match table of the provided node"));
31959 +
31960 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31961 +
31962 + INIT_LIST(&h_OldPointersLst);
31963 + INIT_LIST(&h_NewPointersLst);
31964 +
31965 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31966 + e_MODIFY_STATE_ADD, TRUE, TRUE,
31967 + FALSE);
31968 + if (!p_ModifyKeyParams)
31969 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31970 +
31971 + if (p_CcNode->maxNumOfKeys)
31972 + {
31973 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31974 + {
31975 + XX_Free(p_ModifyKeyParams);
31976 + return ERROR_CODE(E_BUSY);
31977 + }
31978 +
31979 + useShadowStructs = TRUE;
31980 + }
31981 +
31982 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
31983 + p_FmPcdCcKeyParams,
31984 + p_ModifyKeyParams, TRUE);
31985 + if (err)
31986 + {
31987 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31988 + XX_Free(p_ModifyKeyParams);
31989 + if (p_CcNode->maxNumOfKeys)
31990 + RELEASE_LOCK(p_FmPcd->shadowLock);
31991 + RETURN_ERROR(MAJOR, err, NO_MSG);
31992 + }
31993 +
31994 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31995 + &h_OldPointersLst,
31996 + &h_NewPointersLst);
31997 + if (err)
31998 + {
31999 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32000 + XX_Free(p_ModifyKeyParams);
32001 + if (p_CcNode->maxNumOfKeys)
32002 + RELEASE_LOCK(p_FmPcd->shadowLock);
32003 + RETURN_ERROR(MAJOR, err, NO_MSG);
32004 + }
32005 +
32006 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32007 + p_ModifyKeyParams, useShadowStructs);
32008 + if (p_CcNode->maxNumOfKeys)
32009 + RELEASE_LOCK(p_FmPcd->shadowLock);
32010 +
32011 + ReleaseLst(&h_OldPointersLst);
32012 + ReleaseLst(&h_NewPointersLst);
32013 +
32014 + return err;
32015 +}
32016 +
32017 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32018 + uint16_t keyIndex, uint8_t keySize,
32019 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
32020 +{
32021 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32022 + t_FmPcd *p_FmPcd;
32023 + t_List h_OldPointersLst, h_NewPointersLst;
32024 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32025 + uint16_t tmpKeyIndex;
32026 + bool useShadowStructs = FALSE;
32027 + t_Error err = E_OK;
32028 +
32029 + if (keyIndex > p_CcNode->numOfKeys)
32030 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32031 + ("keyIndex > previously cleared last index + 1"));
32032 +
32033 + if (keySize != p_CcNode->userSizeOfExtraction)
32034 + RETURN_ERROR(
32035 + MAJOR,
32036 + E_INVALID_VALUE,
32037 + ("keySize has to be defined as it was defined in initialization step"));
32038 +
32039 + if (p_CcNode->h_FmPcd != h_FmPcd)
32040 + RETURN_ERROR(
32041 + MAJOR,
32042 + E_INVALID_VALUE,
32043 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32044 +
32045 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32046 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32047 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32048 + RETURN_ERROR(
32049 + MINOR,
32050 + E_ALREADY_EXISTS,
32051 + ("The received key and mask pair was already found in the match table of the provided node"));
32052 +
32053 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32054 +
32055 + INIT_LIST(&h_OldPointersLst);
32056 + INIT_LIST(&h_NewPointersLst);
32057 +
32058 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32059 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
32060 + FALSE);
32061 + if (!p_ModifyKeyParams)
32062 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32063 +
32064 + if (p_CcNode->maxNumOfKeys)
32065 + {
32066 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32067 + {
32068 + XX_Free(p_ModifyKeyParams);
32069 + return ERROR_CODE(E_BUSY);
32070 + }
32071 +
32072 + useShadowStructs = TRUE;
32073 + }
32074 +
32075 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32076 + p_FmPcdCcKeyParams,
32077 + p_ModifyKeyParams, FALSE);
32078 + if (err)
32079 + {
32080 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32081 + XX_Free(p_ModifyKeyParams);
32082 + if (p_CcNode->maxNumOfKeys)
32083 + RELEASE_LOCK(p_FmPcd->shadowLock);
32084 + RETURN_ERROR(MAJOR, err, NO_MSG);
32085 + }
32086 +
32087 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32088 + &h_OldPointersLst,
32089 + &h_NewPointersLst);
32090 + if (err)
32091 + {
32092 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32093 + XX_Free(p_ModifyKeyParams);
32094 + if (p_CcNode->maxNumOfKeys)
32095 + RELEASE_LOCK(p_FmPcd->shadowLock);
32096 + RETURN_ERROR(MAJOR, err, NO_MSG);
32097 + }
32098 +
32099 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32100 + p_ModifyKeyParams, useShadowStructs);
32101 +
32102 + if (p_CcNode->maxNumOfKeys)
32103 + RELEASE_LOCK(p_FmPcd->shadowLock);
32104 +
32105 + ReleaseLst(&h_OldPointersLst);
32106 + ReleaseLst(&h_NewPointersLst);
32107 +
32108 + return err;
32109 +}
32110 +
32111 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
32112 + t_Handle h_Pointer)
32113 +{
32114 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32115 + t_CcNodeInformation *p_CcNodeInfo;
32116 +
32117 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
32118 + (uint32_t)ILLEGAL_BASE);
32119 +
32120 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
32121 +
32122 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
32123 + - p_FmPcd->physicalMuramBase);
32124 +}
32125 +
32126 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
32127 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
32128 +{
32129 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32130 +
32131 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32132 +
32133 + if (grpId >= p_FmPcdCcTree->numOfGrps)
32134 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
32135 + ("grpId you asked > numOfGroup of relevant tree"));
32136 +
32137 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
32138 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
32139 +
32140 + return E_OK;
32141 +}
32142 +
32143 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
32144 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
32145 + t_Handle h_FmPort)
32146 +{
32147 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
32148 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32149 + t_Error err = E_OK;
32150 +
32151 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
32152 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32153 +
32154 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32155 +
32156 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
32157 +
32158 + if (err == E_OK)
32159 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
32160 +
32161 + *p_Offset = (uint32_t)(XX_VirtToPhys(
32162 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
32163 + - p_FmPcd->physicalMuramBase);
32164 +
32165 + return err;
32166 +}
32167 +
32168 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
32169 +{
32170 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32171 +
32172 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32173 +
32174 + UNUSED(h_FmPcd);
32175 +
32176 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32177 +
32178 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
32179 +
32180 + return E_OK;
32181 +}
32182 +
32183 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32184 + t_List *p_List)
32185 +{
32186 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32187 + t_List *p_Pos, *p_Tmp;
32188 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32189 + uint32_t intFlags;
32190 + t_Error err = E_OK;
32191 +
32192 + intFlags = FmPcdLock(h_FmPcd);
32193 +
32194 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32195 + {
32196 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32197 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32198 +
32199 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32200 +
32201 + if (err)
32202 + {
32203 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32204 + {
32205 + if (p_Tmp == p_Pos)
32206 + break;
32207 +
32208 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32209 + }
32210 + break;
32211 + }
32212 +
32213 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32214 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32215 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32216 + }
32217 +
32218 + FmPcdUnlock(h_FmPcd, intFlags);
32219 + CORE_MemoryBarrier();
32220 +
32221 + return err;
32222 +}
32223 +
32224 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32225 +{
32226 + t_List *p_Pos;
32227 + t_CcNodeInformation *p_CcNodeInfo;
32228 + t_Handle h_FmPcdCcTree;
32229 + uint32_t intFlags;
32230 +
32231 + intFlags = FmPcdLock(h_FmPcd);
32232 +
32233 + LIST_FOR_EACH(p_Pos, p_List)
32234 + {
32235 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32236 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32237 + CcRootReleaseLock(h_FmPcdCcTree);
32238 + }
32239 +
32240 + ReleaseLst(p_List);
32241 +
32242 + FmPcdUnlock(h_FmPcd, intFlags);
32243 + CORE_MemoryBarrier();
32244 +}
32245 +
32246 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32247 +{
32248 + uint32_t intFlags;
32249 + uint32_t newSize = 0, newAlign = 0;
32250 + bool allocFail = FALSE;
32251 +
32252 + ASSERT_COND(p_FmPcd);
32253 +
32254 + if (!size)
32255 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32256 +
32257 + if (!POWER_OF_2(align))
32258 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32259 +
32260 + newSize = p_FmPcd->ccShadowSize;
32261 + newAlign = p_FmPcd->ccShadowAlign;
32262 +
32263 + /* Check if current shadow is large enough to hold the requested size */
32264 + if (size > p_FmPcd->ccShadowSize)
32265 + newSize = size;
32266 +
32267 + /* Check if current shadow matches the requested alignment */
32268 + if (align > p_FmPcd->ccShadowAlign)
32269 + newAlign = align;
32270 +
32271 + /* If a bigger shadow size or bigger shadow alignment are required,
32272 + a new shadow will be allocated */
32273 + if ((newSize != p_FmPcd->ccShadowSize)
32274 + || (newAlign != p_FmPcd->ccShadowAlign))
32275 + {
32276 + intFlags = FmPcdLock(p_FmPcd);
32277 +
32278 + if (p_FmPcd->p_CcShadow)
32279 + {
32280 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32281 + p_FmPcd->ccShadowSize = 0;
32282 + p_FmPcd->ccShadowAlign = 0;
32283 + }
32284 +
32285 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32286 + newSize, newAlign);
32287 + if (!p_FmPcd->p_CcShadow)
32288 + {
32289 + allocFail = TRUE;
32290 +
32291 + /* If new shadow size allocation failed,
32292 + re-allocate with previous parameters */
32293 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32294 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32295 + p_FmPcd->ccShadowAlign);
32296 + }
32297 +
32298 + FmPcdUnlock(p_FmPcd, intFlags);
32299 +
32300 + if (allocFail)
32301 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32302 + ("MURAM allocation for CC Shadow memory"));
32303 +
32304 + p_FmPcd->ccShadowSize = newSize;
32305 + p_FmPcd->ccShadowAlign = newAlign;
32306 + }
32307 +
32308 + return E_OK;
32309 +}
32310 +
32311 +#if (DPAA_VERSION >= 11)
32312 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32313 + t_Handle h_ReplicGroup,
32314 + t_List *p_AdTables,
32315 + uint32_t *p_NumOfAdTables)
32316 +{
32317 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32318 + int i = 0;
32319 + void * p_AdTable;
32320 + t_CcNodeInformation ccNodeInfo;
32321 +
32322 + ASSERT_COND(h_Node);
32323 + *p_NumOfAdTables = 0;
32324 +
32325 + /* search in the current node which exact index points on this current replicator group for getting AD */
32326 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32327 + {
32328 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32329 + == e_FM_PCD_FR)
32330 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32331 + == (t_Handle)h_ReplicGroup)))
32332 + {
32333 + /* save the current ad table in the list */
32334 + /* this entry uses the input replicator group */
32335 + p_AdTable =
32336 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32337 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32338 + ccNodeInfo.h_CcNode = p_AdTable;
32339 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32340 + (*p_NumOfAdTables)++;
32341 + }
32342 + }
32343 +
32344 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32345 +}
32346 +#endif /* (DPAA_VERSION >= 11) */
32347 +/*********************** End of inter-module routines ************************/
32348 +
32349 +/****************************************/
32350 +/* API Init unit functions */
32351 +/****************************************/
32352 +
32353 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32354 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32355 +{
32356 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32357 + t_Error err = E_OK;
32358 + int i = 0, j = 0, k = 0;
32359 + t_FmPcdCcTree *p_FmPcdCcTree;
32360 + uint8_t numOfEntries;
32361 + t_Handle p_CcTreeTmp;
32362 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32363 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32364 + t_NetEnvParams netEnvParams;
32365 + uint8_t lastOne = 0;
32366 + uint32_t requiredAction = 0;
32367 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32368 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32369 +
32370 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32371 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32372 +
32373 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32374 + {
32375 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32376 + return NULL;
32377 + }
32378 +
32379 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32380 + if (!p_FmPcdCcTree)
32381 + {
32382 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32383 + return NULL;
32384 + }
32385 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32386 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32387 +
32388 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32389 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32390 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32391 + memset(p_Params,
32392 + 0,
32393 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32394 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32395 +
32396 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32397 +
32398 +#ifdef FM_CAPWAP_SUPPORT
32399 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32400 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32401 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32402 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32403 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32404 + {
32405 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32406 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32407 + {
32408 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32409 + XX_Free(p_Params);
32410 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32411 + return NULL;
32412 + }
32413 + }
32414 +#endif /* FM_CAPWAP_SUPPORT */
32415 +
32416 + numOfEntries = 0;
32417 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32418 +
32419 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32420 + {
32421 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32422 +
32423 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32424 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32425 + {
32426 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32427 + XX_Free(p_Params);
32428 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32429 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32430 + return NULL;
32431 + }
32432 +
32433 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32434 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32435 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32436 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32437 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32438 + {
32439 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32440 + XX_Free(p_Params);
32441 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32442 + return NULL;
32443 + }
32444 +
32445 + if (lastOne)
32446 + {
32447 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32448 + {
32449 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32450 + XX_Free(p_Params);
32451 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32452 + return NULL;
32453 + }
32454 + }
32455 +
32456 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32457 +
32458 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32459 + netEnvParams.numOfDistinctionUnits =
32460 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32461 +
32462 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32463 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32464 +
32465 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32466 + if (err)
32467 + {
32468 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32469 + XX_Free(p_Params);
32470 + REPORT_ERROR(MAJOR, err, NO_MSG);
32471 + return NULL;
32472 + }
32473 +
32474 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32475 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32476 + j++)
32477 + {
32478 + err = ValidateNextEngineParams(
32479 + h_FmPcd,
32480 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32481 + e_FM_PCD_CC_STATS_MODE_NONE);
32482 + if (err)
32483 + {
32484 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32485 + XX_Free(p_Params);
32486 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32487 + return NULL;
32488 + }
32489 +
32490 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32491 + {
32492 + err = FmPcdManipCheckParamsForCcNextEngine(
32493 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32494 + &requiredAction);
32495 + if (err)
32496 + {
32497 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32498 + XX_Free(p_Params);
32499 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32500 + return NULL;
32501 + }
32502 + }
32503 + p_KeyAndNextEngineParams = p_Params + k;
32504 +
32505 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32506 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32507 + sizeof(t_FmPcdCcNextEngineParams));
32508 +
32509 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32510 + == e_FM_PCD_CC)
32511 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32512 + {
32513 + err =
32514 + AllocAndFillAdForContLookupManip(
32515 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32516 + if (err)
32517 + {
32518 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32519 + XX_Free(p_Params);
32520 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32521 + return NULL;
32522 + }
32523 + }
32524 +
32525 + requiredAction |= UPDATE_CC_WITH_TREE;
32526 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32527 +
32528 + k++;
32529 + }
32530 + }
32531 +
32532 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32533 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32534 +
32535 + p_FmPcdCcTree->ccTreeBaseAddr =
32536 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32537 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32538 + FM_PCD_CC_TREE_ADDR_ALIGN));
32539 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32540 + {
32541 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32542 + XX_Free(p_Params);
32543 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32544 + return NULL;
32545 + }
32546 + MemSet8(
32547 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32548 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32549 +
32550 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32551 +
32552 + for (i = 0; i < numOfEntries; i++)
32553 + {
32554 + p_KeyAndNextEngineParams = p_Params + i;
32555 +
32556 + NextStepAd(p_CcTreeTmp, NULL,
32557 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32558 +
32559 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32560 +
32561 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32562 + p_KeyAndNextEngineParams,
32563 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32564 +
32565 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32566 + == e_FM_PCD_CC)
32567 + {
32568 + p_FmPcdCcNextNode =
32569 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32570 + p_CcInformation = FindNodeInfoInReleventLst(
32571 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32572 + p_FmPcdCcNextNode->h_Spinlock);
32573 +
32574 + if (!p_CcInformation)
32575 + {
32576 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32577 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32578 + ccNodeInfo.index = 1;
32579 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32580 + &ccNodeInfo,
32581 + p_FmPcdCcNextNode->h_Spinlock);
32582 + }
32583 + else
32584 + p_CcInformation->index++;
32585 + }
32586 + }
32587 +
32588 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32589 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32590 +
32591 + if (!FmPcdLockTryLockAll(p_FmPcd))
32592 + {
32593 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32594 + XX_Free(p_Params);
32595 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32596 + return NULL;
32597 + }
32598 +
32599 + for (i = 0; i < numOfEntries; i++)
32600 + {
32601 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32602 + {
32603 + err = SetRequiredAction(
32604 + h_FmPcd,
32605 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32606 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32607 + p_FmPcdCcTree);
32608 + if (err)
32609 + {
32610 + FmPcdLockUnlockAll(p_FmPcd);
32611 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32612 + XX_Free(p_Params);
32613 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32614 + return NULL;
32615 + }
32616 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32617 + }
32618 + }
32619 +
32620 + FmPcdLockUnlockAll(p_FmPcd);
32621 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32622 + if (!p_FmPcdCcTree->p_Lock)
32623 + {
32624 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32625 + XX_Free(p_Params);
32626 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32627 + return NULL;
32628 + }
32629 +
32630 + XX_Free(p_Params);
32631 +
32632 + return p_FmPcdCcTree;
32633 +}
32634 +
32635 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32636 +{
32637 + t_FmPcd *p_FmPcd;
32638 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32639 + int i = 0;
32640 +
32641 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32642 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32643 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32644 +
32645 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32646 +
32647 + if (p_CcTree->owners)
32648 + RETURN_ERROR(
32649 + MAJOR,
32650 + E_INVALID_SELECTION,
32651 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32652 +
32653 + /* Delete ip-reassembly schemes if exist */
32654 + if (p_CcTree->h_IpReassemblyManip)
32655 + {
32656 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32657 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32658 + }
32659 +
32660 + /* Delete capwap-reassembly schemes if exist */
32661 + if (p_CcTree->h_CapwapReassemblyManip)
32662 + {
32663 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32664 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32665 + }
32666 +
32667 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32668 + {
32669 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32670 + == e_FM_PCD_CC)
32671 + UpdateNodeOwner(
32672 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32673 + FALSE);
32674 +
32675 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32676 + FmPcdManipUpdateOwner(
32677 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32678 + FALSE);
32679 +
32680 +#ifdef FM_CAPWAP_SUPPORT
32681 + if ((p_CcTree->numOfGrps == 1) &&
32682 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32683 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32684 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32685 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32686 + {
32687 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32688 + return E_INVALID_STATE;
32689 + }
32690 +#endif /* FM_CAPWAP_SUPPORT */
32691 +
32692 +#if (DPAA_VERSION >= 11)
32693 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32694 + == e_FM_PCD_FR)
32695 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32696 + FrmReplicGroupUpdateOwner(
32697 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32698 + FALSE);
32699 +#endif /* (DPAA_VERSION >= 11) */
32700 + }
32701 +
32702 + if (p_CcTree->p_Lock)
32703 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32704 +
32705 + DeleteTree(p_CcTree, p_FmPcd);
32706 +
32707 + return E_OK;
32708 +}
32709 +
32710 +t_Error FM_PCD_CcRootModifyNextEngine(
32711 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32712 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32713 +{
32714 + t_FmPcd *p_FmPcd;
32715 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32716 + t_Error err = E_OK;
32717 +
32718 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32719 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32720 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32721 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32722 +
32723 + if (!FmPcdLockTryLockAll(p_FmPcd))
32724 + {
32725 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32726 + return ERROR_CODE(E_BUSY);
32727 + }
32728 +
32729 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32730 + p_FmPcdCcNextEngineParams);
32731 + FmPcdLockUnlockAll(p_FmPcd);
32732 +
32733 + if (err)
32734 + {
32735 + RETURN_ERROR(MAJOR, err, NO_MSG);
32736 + }
32737 +
32738 + return E_OK;
32739 +}
32740 +
32741 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32742 + t_FmPcdCcNodeParams *p_CcNodeParam)
32743 +{
32744 + t_FmPcdCcNode *p_CcNode;
32745 + t_Error err;
32746 +
32747 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32748 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32749 +
32750 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32751 + if (!p_CcNode)
32752 + {
32753 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32754 + return NULL;
32755 + }
32756 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32757 +
32758 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32759 +
32760 + switch(GET_ERROR_TYPE(err)
32761 +) {
32762 + case E_OK:
32763 + break;
32764 +
32765 + case E_BUSY:
32766 + DBG(TRACE, ("E_BUSY error"));
32767 + return NULL;
32768 +
32769 + default:
32770 + REPORT_ERROR(MAJOR, err, NO_MSG);
32771 + return NULL;
32772 + }
32773 +
32774 + return p_CcNode;
32775 +}
32776 +
32777 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32778 +{
32779 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32780 + int i = 0;
32781 +
32782 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32783 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32784 +
32785 + if (p_CcNode->owners)
32786 + RETURN_ERROR(
32787 + MAJOR,
32788 + E_INVALID_STATE,
32789 + ("This node cannot be removed because it is occupied; first unbind this node"));
32790 +
32791 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32792 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32793 + == e_FM_PCD_CC)
32794 + UpdateNodeOwner(
32795 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32796 + FALSE);
32797 +
32798 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32799 + == e_FM_PCD_CC)
32800 + UpdateNodeOwner(
32801 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32802 + FALSE);
32803 +
32804 + /* Handle also Miss entry */
32805 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32806 + {
32807 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32808 + FmPcdManipUpdateOwner(
32809 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32810 + FALSE);
32811 +
32812 +#if (DPAA_VERSION >= 11)
32813 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32814 + == e_FM_PCD_FR)
32815 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32816 + {
32817 + FrmReplicGroupUpdateOwner(
32818 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32819 + FALSE);
32820 + }
32821 +#endif /* (DPAA_VERSION >= 11) */
32822 + }
32823 +
32824 + DeleteNode(p_CcNode);
32825 +
32826 + return E_OK;
32827 +}
32828 +
32829 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32830 + uint8_t keySize,
32831 + t_FmPcdCcKeyParams *p_KeyParams)
32832 +{
32833 + t_FmPcd *p_FmPcd;
32834 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32835 + t_Error err = E_OK;
32836 +
32837 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32838 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32839 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32840 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32841 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32842 +
32843 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
32844 + keyIndex = p_CcNode->numOfKeys;
32845 +
32846 + if (!FmPcdLockTryLockAll(p_FmPcd))
32847 + {
32848 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32849 + return ERROR_CODE(E_BUSY);
32850 + }
32851 +
32852 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
32853 +
32854 + FmPcdLockUnlockAll(p_FmPcd);
32855 +
32856 + switch(GET_ERROR_TYPE(err)
32857 +) {
32858 + case E_OK:
32859 + return E_OK;
32860 +
32861 + case E_BUSY:
32862 + DBG(TRACE, ("E_BUSY error"));
32863 + return ERROR_CODE(E_BUSY);
32864 +
32865 + default:
32866 + RETURN_ERROR(MAJOR, err, NO_MSG);
32867 + }
32868 +}
32869 +
32870 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
32871 +{
32872 + t_FmPcd *p_FmPcd;
32873 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32874 + t_Error err = E_OK;
32875 +
32876 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32877 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32878 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32879 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32880 +
32881 + if (!FmPcdLockTryLockAll(p_FmPcd))
32882 + {
32883 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32884 + return ERROR_CODE(E_BUSY);
32885 + }
32886 +
32887 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
32888 +
32889 + FmPcdLockUnlockAll(p_FmPcd);
32890 +
32891 + switch(GET_ERROR_TYPE(err)
32892 +) {
32893 + case E_OK:
32894 + return E_OK;
32895 +
32896 + case E_BUSY:
32897 + DBG(TRACE, ("E_BUSY error"));
32898 + return ERROR_CODE(E_BUSY);
32899 +
32900 + default:
32901 + RETURN_ERROR(MAJOR, err, NO_MSG);
32902 + }
32903 +
32904 + return E_OK;
32905 +}
32906 +
32907 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
32908 + uint8_t keySize, uint8_t *p_Key,
32909 + uint8_t *p_Mask)
32910 +{
32911 + t_FmPcd *p_FmPcd;
32912 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32913 + t_Error err = E_OK;
32914 +
32915 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32916 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32917 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32918 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32919 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32920 +
32921 +
32922 + if (!FmPcdLockTryLockAll(p_FmPcd))
32923 + {
32924 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32925 + return ERROR_CODE(E_BUSY);
32926 + }
32927 +
32928 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
32929 +
32930 + FmPcdLockUnlockAll(p_FmPcd);
32931 +
32932 + switch(GET_ERROR_TYPE(err)
32933 +) {
32934 + case E_OK:
32935 + return E_OK;
32936 +
32937 + case E_BUSY:
32938 + DBG(TRACE, ("E_BUSY error"));
32939 + return ERROR_CODE(E_BUSY);
32940 +
32941 + default:
32942 + RETURN_ERROR(MAJOR, err, NO_MSG);
32943 + }
32944 +}
32945 +
32946 +t_Error FM_PCD_MatchTableModifyNextEngine(
32947 + t_Handle h_CcNode, uint16_t keyIndex,
32948 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32949 +{
32950 + t_FmPcd *p_FmPcd;
32951 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32952 + t_Error err = E_OK;
32953 +
32954 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32955 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32956 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32957 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32958 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32959 +
32960 + if (!FmPcdLockTryLockAll(p_FmPcd))
32961 + {
32962 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32963 + return ERROR_CODE(E_BUSY);
32964 + }
32965 +
32966 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
32967 + p_FmPcdCcNextEngineParams);
32968 +
32969 + FmPcdLockUnlockAll(p_FmPcd);
32970 +
32971 + switch(GET_ERROR_TYPE(err)
32972 +) {
32973 + case E_OK:
32974 + return E_OK;
32975 +
32976 + case E_BUSY:
32977 + DBG(TRACE, ("E_BUSY error"));
32978 + return ERROR_CODE(E_BUSY);
32979 +
32980 + default:
32981 + RETURN_ERROR(MAJOR, err, NO_MSG);
32982 + }
32983 +}
32984 +
32985 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
32986 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32987 +{
32988 + t_FmPcd *p_FmPcd;
32989 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32990 + t_Error err = E_OK;
32991 +
32992 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32993 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32994 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32995 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32996 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32997 +
32998 + if (!FmPcdLockTryLockAll(p_FmPcd))
32999 + {
33000 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33001 + return ERROR_CODE(E_BUSY);
33002 + }
33003 +
33004 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
33005 + p_FmPcdCcNextEngineParams);
33006 +
33007 + FmPcdLockUnlockAll(p_FmPcd);
33008 +
33009 + switch(GET_ERROR_TYPE(err)
33010 +) {
33011 + case E_OK:
33012 + return E_OK;
33013 +
33014 + case E_BUSY:
33015 + DBG(TRACE, ("E_BUSY error"));
33016 + return ERROR_CODE(E_BUSY);
33017 +
33018 + default:
33019 + RETURN_ERROR(MAJOR, err, NO_MSG);
33020 + }
33021 +}
33022 +
33023 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
33024 + uint16_t keyIndex,
33025 + uint8_t keySize,
33026 + t_FmPcdCcKeyParams *p_KeyParams)
33027 +{
33028 + t_FmPcd *p_FmPcd;
33029 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33030 + t_Error err = E_OK;
33031 +
33032 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33033 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33034 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33035 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33036 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33037 +
33038 + if (!FmPcdLockTryLockAll(p_FmPcd))
33039 + {
33040 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33041 + return ERROR_CODE(E_BUSY);
33042 + }
33043 +
33044 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
33045 + p_KeyParams);
33046 +
33047 + FmPcdLockUnlockAll(p_FmPcd);
33048 +
33049 + switch(GET_ERROR_TYPE(err)
33050 +) {
33051 + case E_OK:
33052 + return E_OK;
33053 +
33054 + case E_BUSY:
33055 + DBG(TRACE, ("E_BUSY error"));
33056 + return ERROR_CODE(E_BUSY);
33057 +
33058 + default:
33059 + RETURN_ERROR(MAJOR, err, NO_MSG);
33060 + }
33061 +}
33062 +
33063 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
33064 + uint8_t *p_Key, uint8_t *p_Mask)
33065 +{
33066 + t_FmPcd *p_FmPcd;
33067 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33068 + uint16_t keyIndex;
33069 + t_Error err;
33070 +
33071 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33072 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33073 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33074 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33075 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33076 +
33077 + if (!FmPcdLockTryLockAll(p_FmPcd))
33078 + {
33079 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33080 + return ERROR_CODE(E_BUSY);
33081 + }
33082 +
33083 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33084 + if (GET_ERROR_TYPE(err) != E_OK)
33085 + {
33086 + FmPcdLockUnlockAll(p_FmPcd);
33087 + RETURN_ERROR(
33088 + MAJOR,
33089 + err,
33090 + ("The received key and mask pair was not found in the match table of the provided node"));
33091 + }
33092 +
33093 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33094 +
33095 + FmPcdLockUnlockAll(p_FmPcd);
33096 +
33097 + switch(GET_ERROR_TYPE(err)
33098 +) {
33099 + case E_OK:
33100 + return E_OK;
33101 +
33102 + case E_BUSY:
33103 + DBG(TRACE, ("E_BUSY error"));
33104 + return ERROR_CODE(E_BUSY);
33105 +
33106 + default:
33107 + RETURN_ERROR(MAJOR, err, NO_MSG);
33108 + }
33109 +}
33110 +
33111 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
33112 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33113 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33114 +{
33115 + t_FmPcd *p_FmPcd;
33116 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33117 + uint16_t keyIndex;
33118 + t_Error err;
33119 +
33120 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33121 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33122 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33123 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33124 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33125 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33126 +
33127 + if (!FmPcdLockTryLockAll(p_FmPcd))
33128 + {
33129 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33130 + return ERROR_CODE(E_BUSY);
33131 + }
33132 +
33133 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33134 + if (GET_ERROR_TYPE(err) != E_OK)
33135 + {
33136 + FmPcdLockUnlockAll(p_FmPcd);
33137 + RETURN_ERROR(
33138 + MAJOR,
33139 + err,
33140 + ("The received key and mask pair was not found in the match table of the provided node"));
33141 + }
33142 +
33143 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33144 + p_FmPcdCcNextEngineParams);
33145 +
33146 + FmPcdLockUnlockAll(p_FmPcd);
33147 +
33148 + switch(GET_ERROR_TYPE(err)
33149 +) {
33150 + case E_OK:
33151 + return E_OK;
33152 +
33153 + case E_BUSY:
33154 + DBG(TRACE, ("E_BUSY error"));
33155 + return ERROR_CODE(E_BUSY);
33156 +
33157 + default:
33158 + RETURN_ERROR(MAJOR, err, NO_MSG);
33159 + }
33160 +}
33161 +
33162 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
33163 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33164 + t_FmPcdCcKeyParams *p_KeyParams)
33165 +{
33166 + t_FmPcd *p_FmPcd;
33167 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33168 + uint16_t keyIndex;
33169 + t_Error err;
33170 +
33171 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33172 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33173 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33174 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33175 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33176 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33177 +
33178 + if (!FmPcdLockTryLockAll(p_FmPcd))
33179 + {
33180 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33181 + return ERROR_CODE(E_BUSY);
33182 + }
33183 +
33184 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33185 + if (GET_ERROR_TYPE(err) != E_OK)
33186 + {
33187 + FmPcdLockUnlockAll(p_FmPcd);
33188 + RETURN_ERROR(
33189 + MAJOR,
33190 + err,
33191 + ("The received key and mask pair was not found in the match table of the provided node"));
33192 + }
33193 +
33194 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33195 + p_KeyParams);
33196 +
33197 + FmPcdLockUnlockAll(p_FmPcd);
33198 +
33199 + switch(GET_ERROR_TYPE(err)
33200 +) {
33201 + case E_OK:
33202 + return E_OK;
33203 +
33204 + case E_BUSY:
33205 + DBG(TRACE, ("E_BUSY error"));
33206 + return ERROR_CODE(E_BUSY);
33207 +
33208 + default:
33209 + RETURN_ERROR(MAJOR, err, NO_MSG);
33210 + }
33211 +}
33212 +
33213 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33214 + uint8_t *p_Key, uint8_t *p_Mask,
33215 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33216 +{
33217 + t_FmPcd *p_FmPcd;
33218 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33219 + t_List h_List;
33220 + uint16_t keyIndex;
33221 + t_Error err;
33222 +
33223 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33224 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33225 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33226 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33227 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33228 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33229 +
33230 + INIT_LIST(&h_List);
33231 +
33232 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33233 + if (err)
33234 + {
33235 + DBG(TRACE, ("Node's trees lock failed"));
33236 + return ERROR_CODE(E_BUSY);
33237 + }
33238 +
33239 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33240 + if (GET_ERROR_TYPE(err) != E_OK)
33241 + {
33242 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33243 + RETURN_ERROR(MAJOR, err,
33244 + ("The received key and mask pair was not found in the "
33245 + "match table of the provided node"));
33246 + }
33247 +
33248 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33249 + p_NewMask);
33250 +
33251 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33252 +
33253 + switch(GET_ERROR_TYPE(err)
33254 +) {
33255 + case E_OK:
33256 + return E_OK;
33257 +
33258 + case E_BUSY:
33259 + DBG(TRACE, ("E_BUSY error"));
33260 + return ERROR_CODE(E_BUSY);
33261 +
33262 + default:
33263 + RETURN_ERROR(MAJOR, err, NO_MSG);
33264 + }
33265 +}
33266 +
33267 +t_Error FM_PCD_MatchTableGetNextEngine(
33268 + t_Handle h_CcNode, uint16_t keyIndex,
33269 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33270 +{
33271 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33272 +
33273 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33274 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33275 +
33276 + if (keyIndex >= p_CcNode->numOfKeys)
33277 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33278 + ("keyIndex exceeds current number of keys"));
33279 +
33280 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33281 + RETURN_ERROR(
33282 + MAJOR,
33283 + E_INVALID_VALUE,
33284 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33285 +
33286 + memcpy(p_FmPcdCcNextEngineParams,
33287 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33288 + sizeof(t_FmPcdCcNextEngineParams));
33289 +
33290 + return E_OK;
33291 +}
33292 +
33293 +
33294 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33295 +{
33296 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33297 + uint32_t *p_StatsCounters, frameCount;
33298 + uint32_t intFlags;
33299 +
33300 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33301 +
33302 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33303 + {
33304 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33305 + return 0;
33306 + }
33307 +
33308 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33309 + && (p_CcNode->statisticsMode
33310 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33311 + {
33312 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33313 + return 0;
33314 + }
33315 +
33316 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33317 +
33318 + if (keyIndex >= p_CcNode->numOfKeys)
33319 + {
33320 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33321 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33322 + return 0;
33323 + }
33324 +
33325 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33326 + {
33327 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33328 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33329 + return 0;
33330 + }
33331 +
33332 + p_StatsCounters =
33333 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33334 + ASSERT_COND(p_StatsCounters);
33335 +
33336 + /* The first counter is byte counter, so we need to advance to the next counter */
33337 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33338 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33339 +
33340 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33341 +
33342 + return frameCount;
33343 +}
33344 +
33345 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33346 + t_Handle h_CcNode, uint16_t keyIndex,
33347 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33348 +{
33349 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33350 + uint32_t intFlags;
33351 + t_Error err;
33352 +
33353 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33354 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33355 +
33356 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33357 +
33358 + if (keyIndex >= p_CcNode->numOfKeys)
33359 + RETURN_ERROR(
33360 + MAJOR,
33361 + E_INVALID_STATE,
33362 + ("The provided keyIndex exceeds the number of keys in this match table"));
33363 +
33364 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33365 +
33366 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33367 +
33368 + if (err != E_OK)
33369 + RETURN_ERROR(MAJOR, err, NO_MSG);
33370 +
33371 + return E_OK;
33372 +}
33373 +
33374 +t_Error FM_PCD_MatchTableGetMissStatistics(
33375 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33376 +{
33377 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33378 + uint32_t intFlags;
33379 + t_Error err;
33380 +
33381 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33382 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33383 +
33384 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33385 +
33386 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33387 + p_MissStatistics);
33388 +
33389 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33390 +
33391 + if (err != E_OK)
33392 + RETURN_ERROR(MAJOR, err, NO_MSG);
33393 +
33394 + return E_OK;
33395 +}
33396 +
33397 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33398 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33399 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33400 +{
33401 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33402 + uint16_t keyIndex;
33403 + uint32_t intFlags;
33404 + t_Error err;
33405 +
33406 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33407 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33408 +
33409 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33410 +
33411 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33412 + if (GET_ERROR_TYPE(err) != E_OK)
33413 + {
33414 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33415 + RETURN_ERROR(MAJOR, err,
33416 + ("The received key and mask pair was not found in the "
33417 + "match table of the provided node"));
33418 + }
33419 +
33420 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33421 +
33422 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33423 +
33424 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33425 +
33426 + if (err != E_OK)
33427 + RETURN_ERROR(MAJOR, err, NO_MSG);
33428 +
33429 + return E_OK;
33430 +}
33431 +
33432 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33433 + uint8_t keySize, uint8_t *p_Key,
33434 + uint8_t hashShift,
33435 + t_Handle *p_CcNodeBucketHandle,
33436 + uint8_t *p_BucketIndex,
33437 + uint16_t *p_LastIndex)
33438 +{
33439 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33440 + uint16_t glblMask;
33441 + uint64_t crc64 = 0;
33442 +
33443 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33444 + SANITY_CHECK_RETURN_ERROR(
33445 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33446 + E_INVALID_STATE);
33447 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33448 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33449 +
33450 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33451 + be16_to_cpus(&glblMask);
33452 +
33453 + crc64 = crc64_init();
33454 + crc64 = crc64_compute(p_Key, keySize, crc64);
33455 + crc64 >>= hashShift;
33456 +
33457 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33458 + & glblMask) >> 4);
33459 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33460 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33461 +
33462 + *p_CcNodeBucketHandle =
33463 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33464 + if (!*p_CcNodeBucketHandle)
33465 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33466 +
33467 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33468 +
33469 + return E_OK;
33470 +}
33471 +
33472 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33473 +{
33474 + t_FmPcdCcNode *p_CcNodeHashTbl;
33475 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33476 + t_FmPcdCcNode *p_CcNode;
33477 + t_Handle h_MissStatsCounters = NULL;
33478 + t_FmPcdCcKeyParams *p_HashKeyParams;
33479 + int i;
33480 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33481 + bool statsEnForMiss = FALSE;
33482 + t_Error err;
33483 +
33484 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33485 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33486 +
33487 + if (p_Param->maxNumOfKeys == 0)
33488 + {
33489 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33490 + return NULL;
33491 + }
33492 +
33493 + if (p_Param->hashResMask == 0)
33494 + {
33495 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33496 + return NULL;
33497 + }
33498 +
33499 + /*Fix: QorIQ SDK / QSDK-2131*/
33500 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33501 + {
33502 + 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."));
33503 + return NULL;
33504 + }
33505 +
33506 +#if (DPAA_VERSION >= 11)
33507 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33508 + {
33509 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33510 + ("RMON statistics mode is not supported for hash table"));
33511 + return NULL;
33512 + }
33513 +#endif /* (DPAA_VERSION >= 11) */
33514 +
33515 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33516 + sizeof(t_FmPcdCcNodeParams));
33517 + if (!p_ExactMatchCcNodeParam)
33518 + {
33519 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33520 + return NULL;
33521 + }
33522 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33523 +
33524 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33525 + sizeof(t_FmPcdCcNodeParams));
33526 + if (!p_IndxHashCcNodeParam)
33527 + {
33528 + XX_Free(p_ExactMatchCcNodeParam);
33529 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33530 + return NULL;
33531 + }
33532 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33533 +
33534 + /* Calculate number of sets and number of ways of the hash table */
33535 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33536 + while (countMask)
33537 + {
33538 + onesCount++;
33539 + countMask = (uint16_t)(countMask >> 1);
33540 + }
33541 +
33542 + numOfSets = (uint16_t)(1 << onesCount);
33543 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33544 +
33545 + if (p_Param->maxNumOfKeys % numOfSets)
33546 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33547 +
33548 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33549 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33550 + {
33551 + /* Allocating a statistics counters table that will be used by all
33552 + 'miss' entries of the hash table */
33553 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33554 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33555 + FM_PCD_CC_AD_TABLE_ALIGN);
33556 + if (!h_MissStatsCounters)
33557 + {
33558 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33559 + XX_Free(p_IndxHashCcNodeParam);
33560 + XX_Free(p_ExactMatchCcNodeParam);
33561 + return NULL;
33562 + }
33563 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33564 +
33565 + /* Always enable statistics for 'miss', so that a statistics AD will be
33566 + initialized from the start. We'll store the requested 'statistics enable'
33567 + value and it will be used when statistics are read by the user. */
33568 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33569 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33570 + }
33571 +
33572 + /* Building exact-match node params, will be used to create the hash buckets */
33573 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33574 +
33575 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33576 + e_FM_PCD_EXTRACT_FROM_KEY;
33577 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33578 + e_FM_PCD_ACTION_EXACT_MATCH;
33579 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33580 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33581 + p_Param->matchKeySize;
33582 +
33583 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33584 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33585 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33586 + p_Param->statisticsMode;
33587 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33588 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33589 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33590 + p_Param->ccNextEngineParamsForMiss;
33591 +
33592 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33593 +
33594 + for (i = 0; i < numOfSets; i++)
33595 + {
33596 + /* Each exact-match node will be marked as a 'bucket' and provided with
33597 + a pointer to statistics counters, to be used for 'miss' entry
33598 + statistics */
33599 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33600 + if (!p_CcNode)
33601 + break;
33602 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33603 +
33604 + p_CcNode->isHashBucket = TRUE;
33605 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33606 +
33607 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33608 + if (err)
33609 + break;
33610 +
33611 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33612 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33613 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33614 + p_CcNode;
33615 + }
33616 +
33617 + if (i < numOfSets)
33618 + {
33619 + for (i = i - 1; i >= 0; i--)
33620 + FM_PCD_MatchTableDelete(
33621 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33622 +
33623 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33624 +
33625 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33626 + XX_Free(p_IndxHashCcNodeParam);
33627 + XX_Free(p_ExactMatchCcNodeParam);
33628 + return NULL;
33629 + }
33630 +
33631 + /* Creating indexed-hash CC node */
33632 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33633 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33634 + e_FM_PCD_EXTRACT_FROM_HASH;
33635 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33636 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33637 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33638 + p_Param->hashResMask;
33639 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33640 + p_Param->hashShift;
33641 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33642 +
33643 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33644 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33645 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33646 + e_FM_PCD_CC_STATS_MODE_NONE;
33647 + /* Number of keys of this node is number of sets of the hash */
33648 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33649 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33650 +
33651 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33652 +
33653 + if (p_CcNodeHashTbl)
33654 + {
33655 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33656 +
33657 + /* Storing the allocated counters for buckets 'miss' in the hash table
33658 + and if statistics for miss were enabled. */
33659 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33660 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33661 + }
33662 +
33663 + XX_Free(p_IndxHashCcNodeParam);
33664 + XX_Free(p_ExactMatchCcNodeParam);
33665 +
33666 + return p_CcNodeHashTbl;
33667 +}
33668 +
33669 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33670 +{
33671 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33672 + t_Handle h_FmPcd;
33673 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33674 + uint16_t i, numOfBuckets;
33675 + t_Error err;
33676 +
33677 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33678 +
33679 + /* Store all hash buckets before the hash is freed */
33680 + numOfBuckets = p_HashTbl->numOfKeys;
33681 +
33682 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33683 + if (!p_HashBuckets)
33684 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33685 +
33686 + for (i = 0; i < numOfBuckets; i++)
33687 + p_HashBuckets[i] =
33688 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33689 +
33690 + h_FmPcd = p_HashTbl->h_FmPcd;
33691 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33692 +
33693 + /* Free the hash */
33694 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33695 +
33696 + /* Free each hash bucket */
33697 + for (i = 0; i < numOfBuckets; i++)
33698 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33699 +
33700 + XX_Free(p_HashBuckets);
33701 +
33702 + /* Free statistics counters for 'miss', if these were allocated */
33703 + if (h_MissStatsCounters)
33704 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33705 +
33706 + if (err)
33707 + RETURN_ERROR(MAJOR, err, NO_MSG);
33708 +
33709 + return E_OK;
33710 +}
33711 +
33712 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33713 + t_FmPcdCcKeyParams *p_KeyParams)
33714 +{
33715 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33716 + t_Handle h_HashBucket;
33717 + uint8_t bucketIndex;
33718 + uint16_t lastIndex;
33719 + t_Error err;
33720 +
33721 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33722 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33723 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33724 +
33725 + if (p_KeyParams->p_Mask)
33726 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33727 + ("Keys masks not supported for hash table"));
33728 +
33729 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33730 + p_KeyParams->p_Key,
33731 + p_HashTbl->kgHashShift,
33732 + &h_HashBucket, &bucketIndex,
33733 + &lastIndex);
33734 + if (err)
33735 + RETURN_ERROR(MAJOR, err, NO_MSG);
33736 +
33737 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33738 + p_KeyParams);
33739 +}
33740 +
33741 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33742 + uint8_t *p_Key)
33743 +{
33744 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33745 + t_Handle h_HashBucket;
33746 + uint8_t bucketIndex;
33747 + uint16_t lastIndex;
33748 + t_Error err;
33749 +
33750 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33751 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33752 +
33753 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33754 + p_HashTbl->kgHashShift,
33755 + &h_HashBucket, &bucketIndex,
33756 + &lastIndex);
33757 + if (err)
33758 + RETURN_ERROR(MAJOR, err, NO_MSG);
33759 +
33760 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33761 +}
33762 +
33763 +t_Error FM_PCD_HashTableModifyNextEngine(
33764 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33765 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33766 +{
33767 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33768 + t_Handle h_HashBucket;
33769 + uint8_t bucketIndex;
33770 + uint16_t lastIndex;
33771 + t_Error err;
33772 +
33773 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33774 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33775 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33776 +
33777 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33778 + p_HashTbl->kgHashShift,
33779 + &h_HashBucket, &bucketIndex,
33780 + &lastIndex);
33781 + if (err)
33782 + RETURN_ERROR(MAJOR, err, NO_MSG);
33783 +
33784 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33785 + NULL,
33786 + p_FmPcdCcNextEngineParams);
33787 +}
33788 +
33789 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33790 + t_Handle h_HashTbl,
33791 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33792 +{
33793 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33794 + t_Handle h_HashBucket;
33795 + uint8_t i;
33796 + bool nullifyMissStats = FALSE;
33797 + t_Error err;
33798 +
33799 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33800 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33801 +
33802 + if ((!p_HashTbl->h_MissStatsCounters)
33803 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33804 + RETURN_ERROR(
33805 + MAJOR,
33806 + E_CONFLICT,
33807 + ("Statistics are requested for a key, but statistics mode was set"
33808 + "to 'NONE' upon initialization"));
33809 +
33810 + if (p_HashTbl->h_MissStatsCounters)
33811 + {
33812 + if ((!p_HashTbl->statsEnForMiss)
33813 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33814 + nullifyMissStats = TRUE;
33815 +
33816 + if ((p_HashTbl->statsEnForMiss)
33817 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33818 + {
33819 + p_HashTbl->statsEnForMiss = FALSE;
33820 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33821 + }
33822 + }
33823 +
33824 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33825 + {
33826 + h_HashBucket =
33827 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33828 +
33829 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33830 + p_FmPcdCcNextEngineParams);
33831 + if (err)
33832 + RETURN_ERROR(MAJOR, err, NO_MSG);
33833 + }
33834 +
33835 + if (nullifyMissStats)
33836 + {
33837 + memset(p_HashTbl->h_MissStatsCounters, 0,
33838 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33839 + memset(p_HashTbl->h_MissStatsCounters, 0,
33840 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33841 + p_HashTbl->statsEnForMiss = TRUE;
33842 + }
33843 +
33844 + return E_OK;
33845 +}
33846 +
33847 +
33848 +t_Error FM_PCD_HashTableGetMissNextEngine(
33849 + t_Handle h_HashTbl,
33850 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33851 +{
33852 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33853 + t_FmPcdCcNode *p_HashBucket;
33854 +
33855 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33856 +
33857 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
33858 + p_HashBucket =
33859 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33860 +
33861 + memcpy(p_FmPcdCcNextEngineParams,
33862 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
33863 + sizeof(t_FmPcdCcNextEngineParams));
33864 +
33865 + return E_OK;
33866 +}
33867 +
33868 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
33869 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33870 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33871 +{
33872 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33873 + t_Handle h_HashBucket;
33874 + uint8_t bucketIndex;
33875 + uint16_t lastIndex;
33876 + t_Error err;
33877 +
33878 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33879 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33880 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33881 +
33882 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33883 + p_HashTbl->kgHashShift,
33884 + &h_HashBucket, &bucketIndex,
33885 + &lastIndex);
33886 + if (err)
33887 + RETURN_ERROR(MAJOR, err, NO_MSG);
33888 +
33889 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
33890 + NULL, p_KeyStatistics);
33891 +}
33892 +
33893 +t_Error FM_PCD_HashTableGetMissStatistics(
33894 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
33895 +{
33896 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33897 + t_Handle h_HashBucket;
33898 +
33899 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33900 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33901 +
33902 + if (!p_HashTbl->statsEnForMiss)
33903 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33904 + ("Statistics were not enabled for miss"));
33905 +
33906 + h_HashBucket =
33907 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33908 +
33909 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
33910 +}
33911 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
33912 new file mode 100644
33913 index 00000000..3456bb56
33914 --- /dev/null
33915 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
33916 @@ -0,0 +1,399 @@
33917 +/*
33918 + * Copyright 2008-2012 Freescale Semiconductor Inc.
33919 + *
33920 + * Redistribution and use in source and binary forms, with or without
33921 + * modification, are permitted provided that the following conditions are met:
33922 + * * Redistributions of source code must retain the above copyright
33923 + * notice, this list of conditions and the following disclaimer.
33924 + * * Redistributions in binary form must reproduce the above copyright
33925 + * notice, this list of conditions and the following disclaimer in the
33926 + * documentation and/or other materials provided with the distribution.
33927 + * * Neither the name of Freescale Semiconductor nor the
33928 + * names of its contributors may be used to endorse or promote products
33929 + * derived from this software without specific prior written permission.
33930 + *
33931 + *
33932 + * ALTERNATIVELY, this software may be distributed under the terms of the
33933 + * GNU General Public License ("GPL") as published by the Free Software
33934 + * Foundation, either version 2 of that License or (at your option) any
33935 + * later version.
33936 + *
33937 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
33938 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33939 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33940 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
33941 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33942 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33943 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33944 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33945 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33946 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33947 + */
33948 +
33949 +
33950 +/******************************************************************************
33951 + @File fm_cc.h
33952 +
33953 + @Description FM PCD CC ...
33954 +*//***************************************************************************/
33955 +#ifndef __FM_CC_H
33956 +#define __FM_CC_H
33957 +
33958 +#include "std_ext.h"
33959 +#include "error_ext.h"
33960 +#include "list_ext.h"
33961 +
33962 +#include "fm_pcd.h"
33963 +
33964 +
33965 +/***********************************************************************/
33966 +/* Coarse classification defines */
33967 +/***********************************************************************/
33968 +
33969 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
33970 +
33971 +#define CC_PC_FF_MACDST 0x00
33972 +#define CC_PC_FF_MACSRC 0x01
33973 +#define CC_PC_FF_ETYPE 0x02
33974 +
33975 +#define CC_PC_FF_TCI1 0x03
33976 +#define CC_PC_FF_TCI2 0x04
33977 +
33978 +#define CC_PC_FF_MPLS1 0x06
33979 +#define CC_PC_FF_MPLS_LAST 0x07
33980 +
33981 +#define CC_PC_FF_IPV4DST1 0x08
33982 +#define CC_PC_FF_IPV4DST2 0x16
33983 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
33984 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
33985 +#define CC_PC_FF_IPV4PTYPE1 0x0A
33986 +#define CC_PC_FF_IPV4PTYPE2 0x18
33987 +#define CC_PC_FF_IPV4SRC1 0x0b
33988 +#define CC_PC_FF_IPV4SRC2 0x19
33989 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
33990 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
33991 +#define CC_PC_FF_IPV4TTL 0x29
33992 +
33993 +
33994 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
33995 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
33996 +#define CC_PC_FF_IPV6PTYPE1 0x0e
33997 +#define CC_PC_FF_IPV6PTYPE2 0x1c
33998 +#define CC_PC_FF_IPV6DST1 0x0f
33999 +#define CC_PC_FF_IPV6DST2 0x1d
34000 +#define CC_PC_FF_IPV6SRC1 0x10
34001 +#define CC_PC_FF_IPV6SRC2 0x1e
34002 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
34003 +#define CC_PC_FF_IPPID 0x24
34004 +#define CC_PC_FF_IPDSCP 0x76
34005 +
34006 +#define CC_PC_FF_GREPTYPE 0x11
34007 +
34008 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
34009 +#define CC_PC_FF_MINENCAP_IPDST 0x13
34010 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
34011 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
34012 +
34013 +#define CC_PC_FF_L4PSRC 0x1f
34014 +#define CC_PC_FF_L4PDST 0x20
34015 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
34016 +
34017 +#define CC_PC_FF_PPPPID 0x05
34018 +
34019 +#define CC_PC_PR_SHIM1 0x22
34020 +#define CC_PC_PR_SHIM2 0x23
34021 +
34022 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
34023 +#define CC_PC_GENERIC_WITH_MASK 0x28
34024 +#define CC_PC_GENERIC_IC_GMASK 0x2B
34025 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
34026 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
34027 +
34028 +#define CC_PR_OFFSET 0x25
34029 +#define CC_PR_WITHOUT_OFFSET 0x26
34030 +
34031 +#define CC_PC_PR_ETH_OFFSET 19
34032 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
34033 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
34034 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
34035 +#define CC_PC_PR_VLAN1_OFFSET 21
34036 +#define CC_PC_PR_VLAN2_OFFSET 22
34037 +#define CC_PC_PR_PPPOE_OFFSET 24
34038 +#define CC_PC_PR_MPLS1_OFFSET 25
34039 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
34040 +#define CC_PC_PR_IP1_OFFSET 27
34041 +#define CC_PC_PR_IP_LAST_OFFSET 28
34042 +#define CC_PC_PR_MINENC_OFFSET 28
34043 +#define CC_PC_PR_L4_OFFSET 30
34044 +#define CC_PC_PR_GRE_OFFSET 29
34045 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
34046 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
34047 +
34048 +#define CC_PC_ILLEGAL 0xff
34049 +#define CC_SIZE_ILLEGAL 0
34050 +
34051 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
34052 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
34053 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
34054 +#define FM_PCD_CC_NUM_OF_KEYS 255
34055 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
34056 +
34057 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
34058 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
34059 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
34060 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
34061 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
34062 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
34063 +
34064 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
34065 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
34066 +
34067 +#define FM_PCD_AD_STATS_TYPE 0x40000000
34068 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
34069 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
34070 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
34071 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
34072 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
34073 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
34074 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
34075 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
34076 +
34077 +
34078 +
34079 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
34080 +
34081 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
34082 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
34083 +
34084 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
34085 +#if (DPAA_VERSION >= 11)
34086 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
34087 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
34088 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
34089 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
34090 +#endif /* (DPAA_VERSION >= 11) */
34091 +
34092 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
34093 +#define CC_GLBL_MASK_SIZE 4
34094 +#define CC_AGING_MASK_SIZE 4
34095 +
34096 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
34097 +
34098 +#define CC_PRIVATE_INFO_NONE 0
34099 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
34100 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
34101 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
34102 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
34103 +
34104 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
34105 +/***********************************************************************/
34106 +/* Memory map */
34107 +/***********************************************************************/
34108 +#if defined(__MWERKS__) && !defined(__GNUC__)
34109 +#pragma pack(push,1)
34110 +#endif /* defined(__MWERKS__) && ... */
34111 +
34112 +typedef struct
34113 +{
34114 + volatile uint32_t fqid;
34115 + volatile uint32_t plcrProfile;
34116 + volatile uint32_t nia;
34117 + volatile uint32_t res;
34118 +} t_AdOfTypeResult;
34119 +
34120 +typedef struct
34121 +{
34122 + volatile uint32_t ccAdBase;
34123 + volatile uint32_t matchTblPtr;
34124 + volatile uint32_t pcAndOffsets;
34125 + volatile uint32_t gmask;
34126 +} t_AdOfTypeContLookup;
34127 +
34128 +typedef struct
34129 +{
34130 + volatile uint32_t profileTableAddr;
34131 + volatile uint32_t reserved;
34132 + volatile uint32_t nextActionIndx;
34133 + volatile uint32_t statsTableAddr;
34134 +} t_AdOfTypeStats;
34135 +
34136 +typedef union
34137 +{
34138 + volatile t_AdOfTypeResult adResult;
34139 + volatile t_AdOfTypeContLookup adContLookup;
34140 +} t_Ad;
34141 +
34142 +#if defined(__MWERKS__) && !defined(__GNUC__)
34143 +#pragma pack(pop)
34144 +#endif /* defined(__MWERKS__) && ... */
34145 +
34146 +
34147 +/***********************************************************************/
34148 +/* Driver's internal structures */
34149 +/***********************************************************************/
34150 +
34151 +typedef struct t_FmPcdStatsObj
34152 +{
34153 + t_Handle h_StatsAd;
34154 + t_Handle h_StatsCounters;
34155 + t_List node;
34156 +} t_FmPcdStatsObj;
34157 +
34158 +typedef struct
34159 +{
34160 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
34161 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
34162 +
34163 + t_FmPcdCcNextEngineParams nextEngineParams;
34164 + uint32_t requiredAction;
34165 + uint32_t shadowAction;
34166 +
34167 + t_FmPcdStatsObj *p_StatsObj;
34168 +
34169 +} t_FmPcdCcKeyAndNextEngineParams;
34170 +
34171 +typedef struct
34172 +{
34173 + t_Handle p_Ad;
34174 + e_FmPcdEngine fmPcdEngine;
34175 + bool adAllocated;
34176 + bool isTree;
34177 +
34178 + uint32_t myInfo;
34179 + t_List *h_CcNextNodesLst;
34180 + t_Handle h_AdditionalInfo;
34181 + t_Handle h_Node;
34182 +} t_FmPcdModifyCcAdditionalParams;
34183 +
34184 +typedef struct
34185 +{
34186 + t_Handle p_AdTableNew;
34187 + t_Handle p_KeysMatchTableNew;
34188 + t_Handle p_AdTableOld;
34189 + t_Handle p_KeysMatchTableOld;
34190 + uint16_t numOfKeys;
34191 + t_Handle h_CurrentNode;
34192 + uint16_t savedKeyIndex;
34193 + t_Handle h_NodeForAdd;
34194 + t_Handle h_NodeForRmv;
34195 + t_Handle h_ManipForRmv;
34196 + t_Handle h_ManipForAdd;
34197 + t_FmPcdStatsObj *p_StatsObjForRmv;
34198 +#if (DPAA_VERSION >= 11)
34199 + t_Handle h_FrmReplicForAdd;
34200 + t_Handle h_FrmReplicForRmv;
34201 +#endif /* (DPAA_VERSION >= 11) */
34202 + bool tree;
34203 +
34204 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34205 +} t_FmPcdModifyCcKeyAdditionalParams;
34206 +
34207 +typedef struct
34208 +{
34209 + t_Handle h_Manip;
34210 + t_Handle h_CcNode;
34211 +} t_CcNextEngineInfo;
34212 +
34213 +typedef struct
34214 +{
34215 + uint16_t numOfKeys;
34216 + uint16_t maxNumOfKeys;
34217 +
34218 + bool maskSupport;
34219 + uint32_t keysMatchTableMaxSize;
34220 +
34221 + e_FmPcdCcStatsMode statisticsMode;
34222 + uint32_t numOfStatsFLRs;
34223 + uint32_t countersArraySize;
34224 +
34225 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34226 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34227 + Holds the statistics counters allocated by the hash table and
34228 + are shared by all hash table buckets; */
34229 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34230 + Holds the statistics counters that were allocated for this node
34231 + and replaced by the shared counters (allocated by the hash table); */
34232 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34233 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34234 + returned statistics count to user, statistics AD always present for 'miss'
34235 + for all hash buckets; */
34236 + bool glblMaskUpdated;
34237 + t_Handle p_GlblMask;
34238 + bool lclMask;
34239 + uint8_t parseCode;
34240 + uint8_t offset;
34241 + uint8_t prsArrayOffset;
34242 + bool ctrlFlow;
34243 + uint16_t owners;
34244 +
34245 + uint8_t ccKeySizeAccExtraction;
34246 + uint8_t sizeOfExtraction;
34247 + uint8_t glblMaskSize;
34248 +
34249 + t_Handle h_KeysMatchTable;
34250 + t_Handle h_AdTable;
34251 + t_Handle h_StatsAds;
34252 + t_Handle h_TmpAd;
34253 + t_Handle h_Ad;
34254 + t_Handle h_StatsFLRs;
34255 +
34256 + t_List availableStatsLst;
34257 +
34258 + t_List ccPrevNodesLst;
34259 +
34260 + t_List ccTreeIdLst;
34261 + t_List ccTreesLst;
34262 +
34263 + t_Handle h_FmPcd;
34264 + uint32_t shadowAction;
34265 + uint8_t userSizeOfExtraction;
34266 + uint8_t userOffset;
34267 + uint8_t kgHashShift; /* used in hash-table */
34268 +
34269 + t_Handle h_Spinlock;
34270 +
34271 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34272 +} t_FmPcdCcNode;
34273 +
34274 +typedef struct
34275 +{
34276 + t_FmPcdCcNode *p_FmPcdCcNode;
34277 + bool occupied;
34278 + uint16_t owners;
34279 + volatile bool lock;
34280 +} t_FmPcdCcNodeArray;
34281 +
34282 +typedef struct
34283 +{
34284 + uint8_t numOfEntriesInGroup;
34285 + uint32_t totalBitsMask;
34286 + uint8_t baseGroupEntry;
34287 +} t_FmPcdCcGroupParam;
34288 +
34289 +typedef struct
34290 +{
34291 + t_Handle h_FmPcd;
34292 + uint8_t netEnvId;
34293 + uintptr_t ccTreeBaseAddr;
34294 + uint8_t numOfGrps;
34295 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34296 + t_List fmPortsLst;
34297 + t_FmPcdLock *p_Lock;
34298 + uint8_t numOfEntries;
34299 + uint16_t owners;
34300 + t_Handle h_FmPcdCcSavedManipParams;
34301 + bool modifiedState;
34302 + uint32_t requiredAction;
34303 + t_Handle h_IpReassemblyManip;
34304 + t_Handle h_CapwapReassemblyManip;
34305 +
34306 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34307 +} t_FmPcdCcTree;
34308 +
34309 +
34310 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34311 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34312 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34313 +
34314 +
34315 +#endif /* __FM_CC_H */
34316 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34317 new file mode 100644
34318 index 00000000..f183d2f9
34319 --- /dev/null
34320 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34321 @@ -0,0 +1,3242 @@
34322 +/*
34323 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34324 + *
34325 + * Redistribution and use in source and binary forms, with or without
34326 + * modification, are permitted provided that the following conditions are met:
34327 + * * Redistributions of source code must retain the above copyright
34328 + * notice, this list of conditions and the following disclaimer.
34329 + * * Redistributions in binary form must reproduce the above copyright
34330 + * notice, this list of conditions and the following disclaimer in the
34331 + * documentation and/or other materials provided with the distribution.
34332 + * * Neither the name of Freescale Semiconductor nor the
34333 + * names of its contributors may be used to endorse or promote products
34334 + * derived from this software without specific prior written permission.
34335 + *
34336 + *
34337 + * ALTERNATIVELY, this software may be distributed under the terms of the
34338 + * GNU General Public License ("GPL") as published by the Free Software
34339 + * Foundation, either version 2 of that License or (at your option) any
34340 + * later version.
34341 + *
34342 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34343 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34344 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34345 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34346 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34347 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34348 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34349 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34350 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34351 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34352 + */
34353 +
34354 +
34355 +/******************************************************************************
34356 + @File fm_kg.c
34357 +
34358 + @Description FM PCD ...
34359 +*//***************************************************************************/
34360 +#include "std_ext.h"
34361 +#include "error_ext.h"
34362 +#include "string_ext.h"
34363 +#include "debug_ext.h"
34364 +#include "net_ext.h"
34365 +#include "fm_port_ext.h"
34366 +
34367 +#include "fm_common.h"
34368 +#include "fm_pcd.h"
34369 +#include "fm_hc.h"
34370 +#include "fm_pcd_ipc.h"
34371 +#include "fm_kg.h"
34372 +#include "fsl_fman_kg.h"
34373 +
34374 +
34375 +/****************************************/
34376 +/* static functions */
34377 +/****************************************/
34378 +
34379 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34380 +{
34381 + ASSERT_COND(h_FmPcdKg);
34382 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34383 +}
34384 +
34385 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34386 +{
34387 + ASSERT_COND(h_FmPcdKg);
34388 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34389 +}
34390 +
34391 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34392 +{
34393 + ASSERT_COND(h_Scheme);
34394 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34395 +}
34396 +
34397 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34398 +{
34399 + ASSERT_COND(h_Scheme);
34400 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34401 +}
34402 +
34403 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34404 +{
34405 + ASSERT_COND(h_Scheme);
34406 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34407 +}
34408 +
34409 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34410 +{
34411 + ASSERT_COND(h_Scheme);
34412 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34413 +}
34414 +
34415 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34416 +{
34417 +
34418 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34419 +
34420 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34421 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34422 +
34423 + return E_OK;
34424 +}
34425 +
34426 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34427 +{
34428 + int i;
34429 +
34430 + switch (code)
34431 + {
34432 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34433 + case (KG_SCH_GEN_DEFAULT):
34434 + case (KG_SCH_GEN_NEXTHDR):
34435 + for (i=0 ; i<numOfSwDefaults ; i++)
34436 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34437 + return swDefaults[i].dfltSelect;
34438 + break;
34439 + case (KG_SCH_GEN_SHIM1):
34440 + case (KG_SCH_GEN_SHIM2):
34441 + case (KG_SCH_GEN_IP_PID_NO_V):
34442 + case (KG_SCH_GEN_ETH_NO_V):
34443 + case (KG_SCH_GEN_SNAP_NO_V):
34444 + case (KG_SCH_GEN_VLAN1_NO_V):
34445 + case (KG_SCH_GEN_VLAN2_NO_V):
34446 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34447 + case (KG_SCH_GEN_PPP_NO_V):
34448 + case (KG_SCH_GEN_MPLS1_NO_V):
34449 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34450 + case (KG_SCH_GEN_L3_NO_V):
34451 + case (KG_SCH_GEN_IP2_NO_V):
34452 + case (KG_SCH_GEN_GRE_NO_V):
34453 + case (KG_SCH_GEN_L4_NO_V):
34454 + for (i=0 ; i<numOfSwDefaults ; i++)
34455 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34456 + return swDefaults[i].dfltSelect;
34457 + break;
34458 + case (KG_SCH_GEN_START_OF_FRM):
34459 + case (KG_SCH_GEN_ETH):
34460 + case (KG_SCH_GEN_SNAP):
34461 + case (KG_SCH_GEN_VLAN1):
34462 + case (KG_SCH_GEN_VLAN2):
34463 + case (KG_SCH_GEN_ETH_TYPE):
34464 + case (KG_SCH_GEN_PPP):
34465 + case (KG_SCH_GEN_MPLS1):
34466 + case (KG_SCH_GEN_MPLS2):
34467 + case (KG_SCH_GEN_MPLS3):
34468 + case (KG_SCH_GEN_MPLS_LAST):
34469 + case (KG_SCH_GEN_IPV4):
34470 + case (KG_SCH_GEN_IPV6):
34471 + case (KG_SCH_GEN_IPV4_TUNNELED):
34472 + case (KG_SCH_GEN_IPV6_TUNNELED):
34473 + case (KG_SCH_GEN_MIN_ENCAP):
34474 + case (KG_SCH_GEN_GRE):
34475 + case (KG_SCH_GEN_TCP):
34476 + case (KG_SCH_GEN_UDP):
34477 + case (KG_SCH_GEN_IPSEC_AH):
34478 + case (KG_SCH_GEN_SCTP):
34479 + case (KG_SCH_GEN_DCCP):
34480 + case (KG_SCH_GEN_IPSEC_ESP):
34481 + for (i=0 ; i<numOfSwDefaults ; i++)
34482 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34483 + return swDefaults[i].dfltSelect;
34484 + break;
34485 + default:
34486 + break;
34487 + }
34488 +
34489 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34490 +}
34491 +
34492 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34493 +{
34494 + *p_Offset = 0;
34495 +
34496 + switch (src)
34497 + {
34498 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34499 + return KG_SCH_GEN_START_OF_FRM;
34500 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34501 + return KG_SCH_GEN_DEFAULT;
34502 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34503 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34504 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34505 + *p_Offset = 32;
34506 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34507 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34508 + return KG_SCH_GEN_NEXTHDR;
34509 + default:
34510 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34511 + return 0;
34512 + }
34513 +}
34514 +
34515 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34516 +{
34517 + if (!ignoreProtocolValidation)
34518 + switch (hdr)
34519 + {
34520 + case (HEADER_TYPE_NONE):
34521 + ASSERT_COND(FALSE);
34522 + case (HEADER_TYPE_ETH):
34523 + return KG_SCH_GEN_ETH;
34524 + case (HEADER_TYPE_LLC_SNAP):
34525 + return KG_SCH_GEN_SNAP;
34526 + case (HEADER_TYPE_PPPoE):
34527 + return KG_SCH_GEN_PPP;
34528 + case (HEADER_TYPE_MPLS):
34529 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34530 + return KG_SCH_GEN_MPLS1;
34531 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34532 + return KG_SCH_GEN_MPLS2;
34533 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34534 + return KG_SCH_GEN_MPLS3;
34535 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34536 + return KG_SCH_GEN_MPLS_LAST;
34537 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34538 + return 0;
34539 + case (HEADER_TYPE_IPv4):
34540 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34541 + return KG_SCH_GEN_IPV4;
34542 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34543 + return KG_SCH_GEN_IPV4_TUNNELED;
34544 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34545 + return 0;
34546 + case (HEADER_TYPE_IPv6):
34547 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34548 + return KG_SCH_GEN_IPV6;
34549 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34550 + return KG_SCH_GEN_IPV6_TUNNELED;
34551 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34552 + return 0;
34553 + case (HEADER_TYPE_GRE):
34554 + return KG_SCH_GEN_GRE;
34555 + case (HEADER_TYPE_TCP):
34556 + return KG_SCH_GEN_TCP;
34557 + case (HEADER_TYPE_UDP):
34558 + return KG_SCH_GEN_UDP;
34559 + case (HEADER_TYPE_IPSEC_AH):
34560 + return KG_SCH_GEN_IPSEC_AH;
34561 + case (HEADER_TYPE_IPSEC_ESP):
34562 + return KG_SCH_GEN_IPSEC_ESP;
34563 + case (HEADER_TYPE_SCTP):
34564 + return KG_SCH_GEN_SCTP;
34565 + case (HEADER_TYPE_DCCP):
34566 + return KG_SCH_GEN_DCCP;
34567 + default:
34568 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34569 + return 0;
34570 + }
34571 + else
34572 + switch (hdr)
34573 + {
34574 + case (HEADER_TYPE_NONE):
34575 + ASSERT_COND(FALSE);
34576 + case (HEADER_TYPE_ETH):
34577 + return KG_SCH_GEN_ETH_NO_V;
34578 + case (HEADER_TYPE_LLC_SNAP):
34579 + return KG_SCH_GEN_SNAP_NO_V;
34580 + case (HEADER_TYPE_PPPoE):
34581 + return KG_SCH_GEN_PPP_NO_V;
34582 + case (HEADER_TYPE_MPLS):
34583 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34584 + return KG_SCH_GEN_MPLS1_NO_V;
34585 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34586 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34587 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34588 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34589 + else
34590 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34591 + return 0;
34592 + case (HEADER_TYPE_IPv4):
34593 + case (HEADER_TYPE_IPv6):
34594 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34595 + return KG_SCH_GEN_L3_NO_V;
34596 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34597 + return KG_SCH_GEN_IP2_NO_V;
34598 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34599 + case (HEADER_TYPE_MINENCAP):
34600 + return KG_SCH_GEN_IP2_NO_V;
34601 + case (HEADER_TYPE_USER_DEFINED_L3):
34602 + return KG_SCH_GEN_L3_NO_V;
34603 + case (HEADER_TYPE_GRE):
34604 + return KG_SCH_GEN_GRE_NO_V;
34605 + case (HEADER_TYPE_TCP):
34606 + case (HEADER_TYPE_UDP):
34607 + case (HEADER_TYPE_IPSEC_AH):
34608 + case (HEADER_TYPE_IPSEC_ESP):
34609 + case (HEADER_TYPE_SCTP):
34610 + case (HEADER_TYPE_DCCP):
34611 + return KG_SCH_GEN_L4_NO_V;
34612 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34613 + return KG_SCH_GEN_SHIM1;
34614 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34615 + return KG_SCH_GEN_SHIM2;
34616 + default:
34617 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34618 + return 0;
34619 + }
34620 +}
34621 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34622 +{
34623 + if (!ignoreProtocolValidation)
34624 + switch (hdr)
34625 + {
34626 + case (HEADER_TYPE_NONE):
34627 + ASSERT_COND(FALSE);
34628 + break;
34629 + case (HEADER_TYPE_ETH):
34630 + switch (field.eth)
34631 + {
34632 + case (NET_HEADER_FIELD_ETH_TYPE):
34633 + return KG_SCH_GEN_ETH_TYPE;
34634 + default:
34635 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34636 + return 0;
34637 + }
34638 + break;
34639 + case (HEADER_TYPE_VLAN):
34640 + switch (field.vlan)
34641 + {
34642 + case (NET_HEADER_FIELD_VLAN_TCI):
34643 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34644 + return KG_SCH_GEN_VLAN1;
34645 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34646 + return KG_SCH_GEN_VLAN2;
34647 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34648 + return 0;
34649 + }
34650 + break;
34651 + case (HEADER_TYPE_MPLS):
34652 + case (HEADER_TYPE_IPSEC_AH):
34653 + case (HEADER_TYPE_IPSEC_ESP):
34654 + case (HEADER_TYPE_LLC_SNAP):
34655 + case (HEADER_TYPE_PPPoE):
34656 + case (HEADER_TYPE_IPv4):
34657 + case (HEADER_TYPE_IPv6):
34658 + case (HEADER_TYPE_GRE):
34659 + case (HEADER_TYPE_MINENCAP):
34660 + case (HEADER_TYPE_USER_DEFINED_L3):
34661 + case (HEADER_TYPE_TCP):
34662 + case (HEADER_TYPE_UDP):
34663 + case (HEADER_TYPE_SCTP):
34664 + case (HEADER_TYPE_DCCP):
34665 + case (HEADER_TYPE_USER_DEFINED_L4):
34666 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34667 + return 0;
34668 + default:
34669 + break;
34670 +
34671 + }
34672 + else
34673 + switch (hdr)
34674 + {
34675 + case (HEADER_TYPE_NONE):
34676 + ASSERT_COND(FALSE);
34677 + break;
34678 + case (HEADER_TYPE_ETH):
34679 + switch (field.eth)
34680 + {
34681 + case (NET_HEADER_FIELD_ETH_TYPE):
34682 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34683 + default:
34684 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34685 + return 0;
34686 + }
34687 + break;
34688 + case (HEADER_TYPE_VLAN):
34689 + switch (field.vlan)
34690 + {
34691 + case (NET_HEADER_FIELD_VLAN_TCI) :
34692 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34693 + return KG_SCH_GEN_VLAN1_NO_V;
34694 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34695 + return KG_SCH_GEN_VLAN2_NO_V;
34696 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34697 + return 0;
34698 + }
34699 + break;
34700 + case (HEADER_TYPE_IPv4):
34701 + switch (field.ipv4)
34702 + {
34703 + case (NET_HEADER_FIELD_IPv4_PROTO):
34704 + return KG_SCH_GEN_IP_PID_NO_V;
34705 + default:
34706 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34707 + return 0;
34708 + }
34709 + break;
34710 + case (HEADER_TYPE_IPv6):
34711 + switch (field.ipv6)
34712 + {
34713 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34714 + return KG_SCH_GEN_IP_PID_NO_V;
34715 + default:
34716 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34717 + return 0;
34718 + }
34719 + break;
34720 + case (HEADER_TYPE_MPLS):
34721 + case (HEADER_TYPE_LLC_SNAP):
34722 + case (HEADER_TYPE_PPPoE):
34723 + case (HEADER_TYPE_GRE):
34724 + case (HEADER_TYPE_MINENCAP):
34725 + case (HEADER_TYPE_USER_DEFINED_L3):
34726 + case (HEADER_TYPE_TCP):
34727 + case (HEADER_TYPE_UDP):
34728 + case (HEADER_TYPE_IPSEC_AH):
34729 + case (HEADER_TYPE_IPSEC_ESP):
34730 + case (HEADER_TYPE_SCTP):
34731 + case (HEADER_TYPE_DCCP):
34732 + case (HEADER_TYPE_USER_DEFINED_L4):
34733 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34734 + return 0;
34735 + default:
34736 + break;
34737 + }
34738 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34739 + return 0;
34740 +}
34741 +
34742 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34743 +{
34744 + UNUSED(p_FmPcd);
34745 +
34746 + switch (hdr)
34747 + {
34748 + case (HEADER_TYPE_NONE):
34749 + ASSERT_COND(FALSE);
34750 + break;
34751 + case (HEADER_TYPE_ETH):
34752 + switch (field.eth)
34753 + {
34754 + case (NET_HEADER_FIELD_ETH_DA):
34755 + return KG_SCH_KN_MACDST;
34756 + case (NET_HEADER_FIELD_ETH_SA):
34757 + return KG_SCH_KN_MACSRC;
34758 + case (NET_HEADER_FIELD_ETH_TYPE):
34759 + return KG_SCH_KN_ETYPE;
34760 + default:
34761 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34762 + return 0;
34763 + }
34764 + case (HEADER_TYPE_LLC_SNAP):
34765 + switch (field.llcSnap)
34766 + {
34767 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34768 + return KG_SCH_KN_ETYPE;
34769 + default:
34770 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34771 + return 0;
34772 + }
34773 + case (HEADER_TYPE_VLAN):
34774 + switch (field.vlan)
34775 + {
34776 + case (NET_HEADER_FIELD_VLAN_TCI):
34777 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34778 + return KG_SCH_KN_TCI1;
34779 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34780 + return KG_SCH_KN_TCI2;
34781 + else
34782 + {
34783 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34784 + return 0;
34785 + }
34786 + default:
34787 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34788 + return 0;
34789 + }
34790 + case (HEADER_TYPE_MPLS):
34791 + switch (field.mpls)
34792 + {
34793 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34794 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34795 + return KG_SCH_KN_MPLS1;
34796 + if (index == e_FM_PCD_HDR_INDEX_2)
34797 + return KG_SCH_KN_MPLS2;
34798 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34799 + return KG_SCH_KN_MPLS_LAST;
34800 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34801 + return 0;
34802 + default:
34803 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34804 + return 0;
34805 + }
34806 + case (HEADER_TYPE_IPv4):
34807 + switch (field.ipv4)
34808 + {
34809 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34810 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34811 + return KG_SCH_KN_IPSRC1;
34812 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34813 + return KG_SCH_KN_IPSRC2;
34814 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34815 + return 0;
34816 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34817 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34818 + return KG_SCH_KN_IPDST1;
34819 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34820 + return KG_SCH_KN_IPDST2;
34821 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34822 + return 0;
34823 + case (NET_HEADER_FIELD_IPv4_PROTO):
34824 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34825 + return KG_SCH_KN_PTYPE1;
34826 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34827 + return KG_SCH_KN_PTYPE2;
34828 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34829 + return 0;
34830 + case (NET_HEADER_FIELD_IPv4_TOS):
34831 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34832 + return KG_SCH_KN_IPTOS_TC1;
34833 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34834 + return KG_SCH_KN_IPTOS_TC2;
34835 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34836 + return 0;
34837 + default:
34838 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34839 + return 0;
34840 + }
34841 + case (HEADER_TYPE_IPv6):
34842 + switch (field.ipv6)
34843 + {
34844 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
34845 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34846 + return KG_SCH_KN_IPSRC1;
34847 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34848 + return KG_SCH_KN_IPSRC2;
34849 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34850 + return 0;
34851 + case (NET_HEADER_FIELD_IPv6_DST_IP):
34852 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34853 + return KG_SCH_KN_IPDST1;
34854 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34855 + return KG_SCH_KN_IPDST2;
34856 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34857 + return 0;
34858 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34859 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34860 + return KG_SCH_KN_PTYPE1;
34861 + if (index == e_FM_PCD_HDR_INDEX_2)
34862 + return KG_SCH_KN_PTYPE2;
34863 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34864 +#ifdef FM_KG_NO_IPPID_SUPPORT
34865 + if (p_FmPcd->fmRevInfo.majorRev < 6)
34866 + return KG_SCH_KN_PTYPE2;
34867 +#endif /* FM_KG_NO_IPPID_SUPPORT */
34868 + return KG_SCH_KN_IPPID;
34869 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34870 + return 0;
34871 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
34872 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34873 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
34874 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34875 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
34876 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34877 + return 0;
34878 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
34879 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34880 + return KG_SCH_KN_IPTOS_TC1;
34881 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34882 + return KG_SCH_KN_IPTOS_TC2;
34883 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34884 + return 0;
34885 + case (NET_HEADER_FIELD_IPv6_FL):
34886 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34887 + return KG_SCH_KN_IPV6FL1;
34888 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34889 + return KG_SCH_KN_IPV6FL2;
34890 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34891 + return 0;
34892 + default:
34893 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34894 + return 0;
34895 + }
34896 + case (HEADER_TYPE_GRE):
34897 + switch (field.gre)
34898 + {
34899 + case (NET_HEADER_FIELD_GRE_TYPE):
34900 + return KG_SCH_KN_GREPTYPE;
34901 + default:
34902 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34903 + return 0;
34904 + }
34905 + case (HEADER_TYPE_MINENCAP):
34906 + switch (field.minencap)
34907 + {
34908 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
34909 + return KG_SCH_KN_IPSRC2;
34910 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
34911 + return KG_SCH_KN_IPDST2;
34912 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
34913 + return KG_SCH_KN_PTYPE2;
34914 + default:
34915 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34916 + return 0;
34917 + }
34918 + case (HEADER_TYPE_TCP):
34919 + switch (field.tcp)
34920 + {
34921 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
34922 + return KG_SCH_KN_L4PSRC;
34923 + case (NET_HEADER_FIELD_TCP_PORT_DST):
34924 + return KG_SCH_KN_L4PDST;
34925 + case (NET_HEADER_FIELD_TCP_FLAGS):
34926 + return KG_SCH_KN_TFLG;
34927 + default:
34928 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34929 + return 0;
34930 + }
34931 + case (HEADER_TYPE_UDP):
34932 + switch (field.udp)
34933 + {
34934 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
34935 + return KG_SCH_KN_L4PSRC;
34936 + case (NET_HEADER_FIELD_UDP_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_IPSEC_AH):
34943 + switch (field.ipsecAh)
34944 + {
34945 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
34946 + return KG_SCH_KN_IPSEC_SPI;
34947 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
34948 + return KG_SCH_KN_IPSEC_NH;
34949 + default:
34950 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34951 + return 0;
34952 + }
34953 + case (HEADER_TYPE_IPSEC_ESP):
34954 + switch (field.ipsecEsp)
34955 + {
34956 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
34957 + return KG_SCH_KN_IPSEC_SPI;
34958 + default:
34959 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34960 + return 0;
34961 + }
34962 + case (HEADER_TYPE_SCTP):
34963 + switch (field.sctp)
34964 + {
34965 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
34966 + return KG_SCH_KN_L4PSRC;
34967 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
34968 + return KG_SCH_KN_L4PDST;
34969 + default:
34970 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34971 + return 0;
34972 + }
34973 + case (HEADER_TYPE_DCCP):
34974 + switch (field.dccp)
34975 + {
34976 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
34977 + return KG_SCH_KN_L4PSRC;
34978 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
34979 + return KG_SCH_KN_L4PDST;
34980 + default:
34981 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34982 + return 0;
34983 + }
34984 + case (HEADER_TYPE_PPPoE):
34985 + switch (field.pppoe)
34986 + {
34987 + case (NET_HEADER_FIELD_PPPoE_PID):
34988 + return KG_SCH_KN_PPPID;
34989 + case (NET_HEADER_FIELD_PPPoE_SID):
34990 + return KG_SCH_KN_PPPSID;
34991 + default:
34992 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34993 + return 0;
34994 + }
34995 + default:
34996 + break;
34997 +
34998 + }
34999 +
35000 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35001 + return 0;
35002 +}
35003 +
35004 +
35005 +static uint8_t GetKnownFieldId(uint32_t bitMask)
35006 +{
35007 + uint8_t cnt = 0;
35008 +
35009 + while (bitMask)
35010 + if (bitMask & 0x80000000)
35011 + break;
35012 + else
35013 + {
35014 + cnt++;
35015 + bitMask <<= 1;
35016 + }
35017 + return cnt;
35018 +
35019 +}
35020 +
35021 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
35022 +{
35023 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
35024 +
35025 + /* bitOffset 1-7 --> mask 0x1-0x7F */
35026 + if (bitOffset<8)
35027 + {
35028 + mask = 0;
35029 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
35030 + mask |= walking1Mask;
35031 + }
35032 + else
35033 + {
35034 + mask = 0xFF;
35035 + numOfOnesToClear = 0;
35036 + if (fqid && bitOffset>24)
35037 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
35038 + numOfOnesToClear = (uint8_t)(bitOffset-24);
35039 + else
35040 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
35041 + if (!fqid && bitOffset>8)
35042 + numOfOnesToClear = (uint8_t)(bitOffset-8);
35043 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
35044 + mask &= ~walking1Mask;
35045 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
35046 + }
35047 + return mask;
35048 +}
35049 +
35050 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35051 +{
35052 + t_FmPcdKg *p_FmPcdKg;
35053 + t_FmPcdKgScheme *p_Scheme;
35054 + uint32_t intFlags;
35055 + uint8_t relativeSchemeId;
35056 + int i;
35057 +
35058 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35059 +
35060 + /* for each scheme - update owners counters */
35061 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35062 + {
35063 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35064 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35065 +
35066 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35067 +
35068 + /* increment owners number */
35069 + intFlags = KgSchemeLock(p_Scheme);
35070 + p_Scheme->owners++;
35071 + KgSchemeUnlock(p_Scheme, intFlags);
35072 + }
35073 +}
35074 +
35075 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35076 +{
35077 + t_FmPcdKg *p_FmPcdKg;
35078 + t_FmPcdKgScheme *p_Scheme;
35079 + uint32_t intFlags;
35080 + uint8_t relativeSchemeId;
35081 + int i;
35082 +
35083 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35084 +
35085 + /* for each scheme - update owners counters */
35086 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35087 + {
35088 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35089 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35090 +
35091 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35092 +
35093 + /* increment owners number */
35094 + ASSERT_COND(p_Scheme->owners);
35095 + intFlags = KgSchemeLock(p_Scheme);
35096 + p_Scheme->owners--;
35097 + KgSchemeUnlock(p_Scheme, intFlags);
35098 + }
35099 +}
35100 +
35101 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
35102 +{
35103 + /* this routine is locked by the calling routine */
35104 + ASSERT_COND(p_Scheme);
35105 + ASSERT_COND(p_Scheme->valid);
35106 +
35107 + if (set)
35108 + p_Scheme->requiredActionFlag = TRUE;
35109 + else
35110 + {
35111 + p_Scheme->requiredAction = 0;
35112 + p_Scheme->requiredActionFlag = FALSE;
35113 + }
35114 +}
35115 +
35116 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
35117 +{
35118 + struct fman_kg_regs *p_KgRegs;
35119 +
35120 + uint32_t tmpKgarReg = 0, intFlags;
35121 + t_Error err = E_OK;
35122 +
35123 + /* The calling routine had locked the port, so for each port only one core can access
35124 + * (so we don't need a lock here) */
35125 +
35126 + if (p_FmPcd->h_Hc)
35127 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
35128 +
35129 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35130 +
35131 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
35132 + /* lock a common KG reg */
35133 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35134 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35135 + if (err)
35136 + {
35137 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35138 + RETURN_ERROR(MINOR, err, NO_MSG);
35139 + }
35140 +
35141 + fman_kg_write_sp(p_KgRegs, spReg, add);
35142 +
35143 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
35144 +
35145 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35146 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35147 + return err;
35148 +}
35149 +
35150 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
35151 +{
35152 + struct fman_kg_regs *p_KgRegs;
35153 + uint32_t tmpKgarReg, intFlags;
35154 + t_Error err;
35155 +
35156 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35157 +
35158 + if (p_FmPcd->h_Hc)
35159 + {
35160 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
35161 + return err;
35162 + }
35163 +
35164 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35165 + fman_kg_write_cpp(p_KgRegs, cppReg);
35166 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
35167 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35168 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35169 +
35170 + return err;
35171 +}
35172 +
35173 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
35174 +{
35175 + uint32_t tmpKgpeCpp;
35176 +
35177 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
35178 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
35179 +
35180 + return tmpKgpeCpp;
35181 +}
35182 +
35183 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
35184 +{
35185 + uint32_t tmpKgpeCpp = 0;
35186 +
35187 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
35188 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
35189 +}
35190 +
35191 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
35192 +{
35193 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
35194 +}
35195 +
35196 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35197 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35198 +{
35199 + return (uint32_t)(FM_KG_KGAR_GO |
35200 + FM_KG_KGAR_READ |
35201 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35202 + DUMMY_PORT_ID |
35203 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35204 + FM_PCD_KG_KGAR_WSEL_MASK);
35205 +
35206 + /* if we ever want to write 1 by 1, use:
35207 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35208 + */
35209 +}
35210 +#endif /* (defined(DEBUG_ERRORS) && ... */
35211 +
35212 +static void PcdKgErrorException(t_Handle h_FmPcd)
35213 +{
35214 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35215 + uint32_t event,schemeIndexes = 0, index = 0;
35216 + struct fman_kg_regs *p_KgRegs;
35217 +
35218 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35219 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35220 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35221 +
35222 + if (event & FM_EX_KG_DOUBLE_ECC)
35223 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35224 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35225 + {
35226 + if (schemeIndexes)
35227 + {
35228 + while (schemeIndexes)
35229 + {
35230 + if (schemeIndexes & 0x1)
35231 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35232 + schemeIndexes >>= 1;
35233 + index+=1;
35234 + }
35235 + }
35236 + else /* this should happen only when interrupt is forced. */
35237 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35238 + }
35239 +}
35240 +
35241 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35242 +{
35243 + t_Error err = E_OK;
35244 + t_FmPcdIpcKgSchemesParams kgAlloc;
35245 + uint32_t replyLength;
35246 + t_FmPcdIpcReply reply;
35247 + t_FmPcdIpcMsg msg;
35248 +
35249 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35250 +
35251 + /* in GUEST_PARTITION, we use the IPC */
35252 + memset(&reply, 0, sizeof(reply));
35253 + memset(&msg, 0, sizeof(msg));
35254 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35255 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35256 + kgAlloc.guestId = p_FmPcd->guestId;
35257 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35258 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35259 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35260 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35261 + (uint8_t*)&msg,
35262 + sizeof(msg.msgId) + sizeof(kgAlloc),
35263 + (uint8_t*)&reply,
35264 + &replyLength,
35265 + NULL,
35266 + NULL)) != E_OK)
35267 + RETURN_ERROR(MAJOR, err, NO_MSG);
35268 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35269 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35270 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35271 +
35272 + return (t_Error)reply.error;
35273 +}
35274 +
35275 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35276 +{
35277 + t_Error err = E_OK;
35278 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35279 +
35280 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35281 +
35282 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35283 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35284 +
35285 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35286 +
35287 + /* register even if no interrupts enabled, to allow future enablement */
35288 + FmRegisterIntr(p_FmPcd->h_Fm,
35289 + e_FM_MOD_KG,
35290 + 0,
35291 + e_FM_INTR_TYPE_ERR,
35292 + PcdKgErrorException,
35293 + p_FmPcd);
35294 +
35295 + fman_kg_enable_scheme_interrupts(p_Regs);
35296 +
35297 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35298 + {
35299 + err = FmPcdKgAllocSchemes(p_FmPcd,
35300 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35301 + p_FmPcd->guestId,
35302 + p_FmPcd->p_FmPcdKg->schemesIds);
35303 + if (err)
35304 + RETURN_ERROR(MINOR, err, NO_MSG);
35305 + }
35306 +
35307 + return E_OK;
35308 +}
35309 +
35310 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35311 +{
35312 + ASSERT_COND(!p_Scheme->valid);
35313 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35314 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35315 + p_Scheme->valid = TRUE;
35316 +}
35317 +
35318 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35319 +{
35320 + if (p_Scheme->owners)
35321 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35322 +
35323 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35324 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35325 + p_Scheme->valid = FALSE;
35326 +
35327 + return E_OK;
35328 +}
35329 +
35330 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35331 + t_FmPcdKgSchemeParams *p_SchemeParams,
35332 + struct fman_kg_scheme_regs *p_SchemeRegs)
35333 +{
35334 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35335 + uint32_t grpBits = 0;
35336 + uint8_t grpBase;
35337 + bool direct=TRUE, absolute=FALSE;
35338 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35339 + t_Error err = E_OK;
35340 + int i = 0;
35341 + t_NetEnvParams netEnvParams;
35342 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35343 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35344 + uint8_t j, curr, idx;
35345 + uint8_t id, shift=0, code=0, offset=0, size=0;
35346 + t_FmPcdExtractEntry *p_Extract = NULL;
35347 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35348 + bool generic = FALSE;
35349 + t_KnownFieldsMasks bitMask;
35350 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35351 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35352 + uint8_t numOfSwDefaults = 0;
35353 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35354 + uint8_t currGenId = 0;
35355 +
35356 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35357 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35358 +
35359 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35360 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35361 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35362 +
35363 + /* by netEnv parameters, get match vector */
35364 + if (!p_SchemeParams->alwaysDirect)
35365 + {
35366 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35367 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35368 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35369 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35370 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35371 + if (err)
35372 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35373 + p_Scheme->matchVector = netEnvParams.vector;
35374 + }
35375 + else
35376 + {
35377 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35378 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35379 + }
35380 +
35381 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35382 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35383 +
35384 + if (p_SchemeParams->bypassFqidGeneration)
35385 + {
35386 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35387 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35388 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35389 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35390 + if (p_SchemeParams->baseFqid)
35391 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35392 + }
35393 + else
35394 + if (!p_SchemeParams->baseFqid)
35395 + DBG(WARNING, ("baseFqid is 0."));
35396 +
35397 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35398 + {
35399 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35400 + p_Scheme->directPlcr = direct;
35401 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35402 + if (!direct && absolute)
35403 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35404 +
35405 + if (direct)
35406 + {
35407 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35408 + numOfProfiles = 1;
35409 + }
35410 + else
35411 + {
35412 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35413 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35414 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35415 + }
35416 + }
35417 +
35418 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35419 + {
35420 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35421 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35422 + {
35423 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35424 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35425 + }
35426 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35427 +
35428 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35429 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35430 + &grpBits,
35431 + &grpBase);
35432 + if (err)
35433 + RETURN_ERROR(MAJOR, err, NO_MSG);
35434 + p_Scheme->ccUnits = grpBits;
35435 +
35436 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35437 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35438 + {
35439 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35440 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35441 + absolute = FALSE;
35442 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35443 + if (direct)
35444 + {
35445 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35446 + numOfProfiles = 1;
35447 + }
35448 + else
35449 + {
35450 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35451 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35452 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35453 + }
35454 + }
35455 + }
35456 +
35457 + /* if policer is used directly after KG, or after CC */
35458 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35459 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35460 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35461 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35462 + {
35463 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35464 + if (absolute)
35465 + {
35466 + /* for absolute direct policy only, */
35467 + relativeProfileId = profileId;
35468 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35469 + if (err)
35470 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35471 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35472 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35473 + p_Scheme->relativeProfileId = profileId;
35474 + }
35475 + else
35476 + {
35477 + /* save relative profile id's for later check */
35478 + p_Scheme->nextRelativePlcrProfile = TRUE;
35479 + p_Scheme->relativeProfileId = profileId;
35480 + p_Scheme->numOfProfiles = numOfProfiles;
35481 + }
35482 + }
35483 + else
35484 + {
35485 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35486 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35487 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35488 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35489 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35490 + if (p_SchemeParams->bypassFqidGeneration &&
35491 + p_SchemeParams->useHash &&
35492 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35493 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35494 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35495 + }
35496 +
35497 + /* configure all 21 scheme registers */
35498 + tmpReg = KG_SCH_MODE_EN;
35499 + switch (p_SchemeParams->nextEngine)
35500 + {
35501 + case (e_FM_PCD_PLCR):
35502 + /* add to mode register - NIA */
35503 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35504 + tmpReg |= NIA_ENG_PLCR;
35505 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35506 + /* initialize policer profile command - */
35507 + /* configure kgse_ppc */
35508 + if (direct)
35509 + /* use profileId as base, other fields are 0 */
35510 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35511 + else
35512 + {
35513 + if (shift > MAX_PP_SHIFT)
35514 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35515 +
35516 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35517 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35518 +
35519 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35520 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35521 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35522 + ppcTmp |= (uint32_t)profileId;
35523 +
35524 + p_SchemeRegs->kgse_ppc = ppcTmp;
35525 + }
35526 + break;
35527 + case (e_FM_PCD_CC):
35528 + /* mode reg - define NIA */
35529 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35530 +
35531 + p_SchemeRegs->kgse_ccbs = grpBits;
35532 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35533 +
35534 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35535 + {
35536 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35537 + {
35538 + /* find out if absolute or relative */
35539 + if (absolute)
35540 + 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"));
35541 + if (direct)
35542 + {
35543 + /* mask = 0, base = directProfileId */
35544 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35545 + }
35546 + else
35547 + {
35548 + if (shift > MAX_PP_SHIFT)
35549 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35550 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35551 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35552 +
35553 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35554 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35555 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35556 + ppcTmp |= (uint32_t)profileId;
35557 +
35558 + p_SchemeRegs->kgse_ppc = ppcTmp;
35559 + }
35560 + }
35561 + }
35562 + break;
35563 + case (e_FM_PCD_DONE):
35564 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35565 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35566 + else
35567 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35568 + break;
35569 + default:
35570 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35571 + }
35572 + p_SchemeRegs->kgse_mode = tmpReg;
35573 +
35574 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35575 +
35576 +#if (DPAA_VERSION >= 11)
35577 + if (p_SchemeParams->overrideStorageProfile)
35578 + {
35579 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35580 +
35581 + if (p_SchemeParams->storageProfile.direct)
35582 + {
35583 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35584 + shift = 0;
35585 + numOfProfiles = 1;
35586 + }
35587 + else
35588 + {
35589 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35590 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35591 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35592 + }
35593 + if (shift > MAX_SP_SHIFT)
35594 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35595 +
35596 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35597 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35598 +
35599 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35600 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35601 + tmpReg |= (uint32_t)profileId;
35602 +
35603 +
35604 + p_SchemeRegs->kgse_vsp = tmpReg;
35605 +
35606 + p_Scheme->vspe = TRUE;
35607 +
35608 + }
35609 + else
35610 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35611 +#endif /* (DPAA_VERSION >= 11) */
35612 +
35613 + if (p_SchemeParams->useHash)
35614 + {
35615 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35616 +
35617 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35618 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35619 +
35620 + /* configure kgse_dv0 */
35621 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35622 +
35623 + /* configure kgse_dv1 */
35624 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35625 +
35626 + if (!p_SchemeParams->bypassFqidGeneration)
35627 + {
35628 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35629 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35630 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35631 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35632 + }
35633 +
35634 + /* configure kgse_ekdv */
35635 + tmpReg = 0;
35636 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35637 + {
35638 + switch (p_KeyAndHash->dflts[i].type)
35639 + {
35640 + case (e_FM_PCD_KG_MAC_ADDR):
35641 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35642 + break;
35643 + case (e_FM_PCD_KG_TCI):
35644 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35645 + break;
35646 + case (e_FM_PCD_KG_ENET_TYPE):
35647 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35648 + break;
35649 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35650 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35651 + break;
35652 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35653 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35654 + break;
35655 + case (e_FM_PCD_KG_MPLS_LABEL):
35656 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35657 + break;
35658 + case (e_FM_PCD_KG_IP_ADDR):
35659 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35660 + break;
35661 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35662 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35663 + break;
35664 + case (e_FM_PCD_KG_IP_TOS_TC):
35665 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35666 + break;
35667 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35668 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35669 + break;
35670 + case (e_FM_PCD_KG_IPSEC_SPI):
35671 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35672 + break;
35673 + case (e_FM_PCD_KG_L4_PORT):
35674 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35675 + break;
35676 + case (e_FM_PCD_KG_TCP_FLAG):
35677 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35678 + break;
35679 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35680 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35681 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35682 + numOfSwDefaults ++;
35683 + break;
35684 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35685 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35686 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35687 + numOfSwDefaults ++;
35688 + break;
35689 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35690 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35691 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35692 + numOfSwDefaults ++;
35693 + break;
35694 + default:
35695 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35696 + }
35697 + }
35698 + p_SchemeRegs->kgse_ekdv = tmpReg;
35699 +
35700 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35701 + if (!p_LocalExtractsArray)
35702 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35703 +
35704 + /* configure kgse_ekfc and kgse_gec */
35705 + knownTmp = 0;
35706 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35707 + {
35708 + p_Extract = &p_KeyAndHash->extractArray[i];
35709 + switch (p_Extract->type)
35710 + {
35711 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35712 + knownTmp |= KG_SCH_KN_PORT_ID;
35713 + /* save in driver structure */
35714 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35715 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35716 + break;
35717 + case (e_FM_PCD_EXTRACT_BY_HDR):
35718 + switch (p_Extract->extractByHdr.hdr)
35719 + {
35720 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35721 + case (HEADER_TYPE_UDP_LITE):
35722 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35723 + break;
35724 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35725 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35726 + switch (p_Extract->extractByHdr.type)
35727 + {
35728 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35729 + /* case where extraction from ESP only */
35730 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35731 + {
35732 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35733 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35734 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35735 + }
35736 + else
35737 + {
35738 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35739 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35740 + }
35741 + break;
35742 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35743 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35744 + {
35745 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35746 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35747 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35748 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35749 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35750 + break;
35751 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35752 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35753 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35754 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35755 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35756 + break;
35757 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35758 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35759 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35760 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35761 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35762 + break;
35763 + }
35764 + break;
35765 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35766 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35767 + {
35768 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35769 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35770 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35771 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35772 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35773 + break;
35774 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35775 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35776 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35777 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35778 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35779 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35780 + break;
35781 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35782 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35783 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35784 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35785 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35786 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35787 + break;
35788 + }
35789 + break;
35790 + }
35791 + break;
35792 + default:
35793 + break;
35794 + }
35795 + switch (p_Extract->extractByHdr.type)
35796 + {
35797 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35798 + generic = TRUE;
35799 + /* get the header code for the generic extract */
35800 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35801 + /* set generic register fields */
35802 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35803 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35804 + break;
35805 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35806 + generic = TRUE;
35807 + /* get the field code for the generic extract */
35808 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35809 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35810 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35811 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35812 + break;
35813 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35814 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35815 + {
35816 + /* if we have a known field for it - use it, otherwise use generic */
35817 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35818 + p_Extract->extractByHdr.extractByHdrType.fullField);
35819 + if (bitMask)
35820 + {
35821 + knownTmp |= bitMask;
35822 + /* save in driver structure */
35823 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35824 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35825 + }
35826 + else
35827 + generic = TRUE;
35828 + }
35829 + else
35830 + generic = TRUE;
35831 + if (generic)
35832 + {
35833 + /* tmp - till we cover more headers under generic */
35834 + XX_Free(p_LocalExtractsArray);
35835 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35836 + }
35837 + break;
35838 + default:
35839 + XX_Free(p_LocalExtractsArray);
35840 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35841 + }
35842 + break;
35843 + case (e_FM_PCD_EXTRACT_NON_HDR):
35844 + /* use generic */
35845 + generic = TRUE;
35846 + offset = 0;
35847 + /* get the field code for the generic extract */
35848 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
35849 + offset += p_Extract->extractNonHdr.offset;
35850 + size = p_Extract->extractNonHdr.size;
35851 + break;
35852 + default:
35853 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35854 + }
35855 +
35856 + if (generic)
35857 + {
35858 + /* set generic register fields */
35859 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
35860 + {
35861 + XX_Free(p_LocalExtractsArray);
35862 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35863 + }
35864 + if (!code)
35865 + {
35866 + XX_Free(p_LocalExtractsArray);
35867 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35868 + }
35869 +
35870 + genTmp = KG_SCH_GEN_VALID;
35871 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35872 + genTmp |= offset;
35873 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
35874 + {
35875 + XX_Free(p_LocalExtractsArray);
35876 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
35877 + }
35878 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
35879 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
35880 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
35881 + DBG(WARNING, ("No sw default configured"));
35882 + else
35883 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
35884 +
35885 + genTmp |= KG_SCH_GEN_MASK;
35886 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
35887 + /* save in driver structure */
35888 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
35889 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
35890 + generic = FALSE;
35891 + }
35892 + }
35893 + p_SchemeRegs->kgse_ekfc = knownTmp;
35894 +
35895 + selectTmp = 0;
35896 + maskTmp = 0xFFFFFFFF;
35897 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
35898 +
35899 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
35900 + {
35901 + XX_Free(p_LocalExtractsArray);
35902 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
35903 + }
35904 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
35905 + {
35906 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
35907 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
35908 + /* Get the shift of the select field (depending on i) */
35909 + GET_MASK_SEL_SHIFT(shift,i);
35910 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
35911 + selectTmp |= id << shift;
35912 + else
35913 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
35914 +
35915 + /* Get the shift of the offset field (depending on i) - may
35916 + be in kgse_bmch or in kgse_fqb (depending on i) */
35917 + GET_MASK_OFFSET_SHIFT(shift,i);
35918 + if (i<=1)
35919 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
35920 + else
35921 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
35922 +
35923 + /* Get the shift of the mask field (depending on i) */
35924 + GET_MASK_SHIFT(shift,i);
35925 + /* pass all bits */
35926 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
35927 + /* clear bits that need masking */
35928 + maskTmp &= ~(0xFF << shift) ;
35929 + /* set mask bits */
35930 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
35931 + }
35932 + p_SchemeRegs->kgse_bmch = selectTmp;
35933 + p_SchemeRegs->kgse_bmcl = maskTmp;
35934 + /* kgse_fqb will be written t the end of the routine */
35935 +
35936 + /* configure kgse_hc */
35937 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
35938 + {
35939 + XX_Free(p_LocalExtractsArray);
35940 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
35941 + }
35942 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
35943 + {
35944 + XX_Free(p_LocalExtractsArray);
35945 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
35946 + }
35947 +
35948 + tmpReg = 0;
35949 +
35950 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
35951 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
35952 +
35953 + if (p_KeyAndHash->symmetricHash)
35954 + {
35955 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
35956 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
35957 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
35958 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
35959 + {
35960 + XX_Free(p_LocalExtractsArray);
35961 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
35962 + }
35963 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
35964 + }
35965 + p_SchemeRegs->kgse_hc = tmpReg;
35966 +
35967 + /* build the return array describing the order of the extractions */
35968 +
35969 + /* the last currGenId places of the array
35970 + are for generic extracts that are always last.
35971 + We now sort for the calculation of the order of the known
35972 + extractions we sort the known extracts between orderedArray[0] and
35973 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
35974 + for the calculation of the order of the generic extractions we use:
35975 + num_of_generic - currGenId
35976 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
35977 + first_generic_index = num_of_known */
35978 + curr = 0;
35979 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35980 + {
35981 + if (p_LocalExtractsArray->extractsArray[i].known)
35982 + {
35983 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
35984 + j = curr;
35985 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
35986 + index in the user's extractions array */
35987 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
35988 + location */
35989 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
35990 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
35991 + {
35992 + p_Scheme->orderedArray[j] =
35993 + p_Scheme->orderedArray[j-1];
35994 + j--;
35995 + }
35996 + p_Scheme->orderedArray[j] = (uint8_t)i;
35997 + curr++;
35998 + }
35999 + else
36000 + {
36001 + /* index is first_generic_index + generic index (id) */
36002 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
36003 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
36004 + p_Scheme->orderedArray[idx]= (uint8_t)i;
36005 + }
36006 + }
36007 + XX_Free(p_LocalExtractsArray);
36008 + }
36009 + else
36010 + {
36011 + /* clear all unused registers: */
36012 + p_SchemeRegs->kgse_ekfc = 0;
36013 + p_SchemeRegs->kgse_ekdv = 0;
36014 + p_SchemeRegs->kgse_bmch = 0;
36015 + p_SchemeRegs->kgse_bmcl = 0;
36016 + p_SchemeRegs->kgse_hc = 0;
36017 + p_SchemeRegs->kgse_dv0 = 0;
36018 + p_SchemeRegs->kgse_dv1 = 0;
36019 + }
36020 +
36021 + if (p_SchemeParams->bypassFqidGeneration)
36022 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
36023 +
36024 + /* configure kgse_spc */
36025 + if ( p_SchemeParams->schemeCounter.update)
36026 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
36027 +
36028 +
36029 + /* check that are enough generic registers */
36030 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
36031 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
36032 +
36033 + /* extracted OR mask on Qid */
36034 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
36035 + {
36036 +
36037 + p_Scheme->extractedOrs = TRUE;
36038 + /* configure kgse_gec[i] */
36039 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
36040 + switch (p_ExtractOr->type)
36041 + {
36042 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
36043 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
36044 + offset = 0;
36045 + break;
36046 + case (e_FM_PCD_EXTRACT_BY_HDR):
36047 + /* get the header code for the generic extract */
36048 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
36049 + /* set generic register fields */
36050 + offset = p_ExtractOr->extractionOffset;
36051 + break;
36052 + case (e_FM_PCD_EXTRACT_NON_HDR):
36053 + /* get the field code for the generic extract */
36054 + offset = 0;
36055 + code = GetGenCode(p_ExtractOr->src, &offset);
36056 + offset += p_ExtractOr->extractionOffset;
36057 + break;
36058 + default:
36059 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36060 + }
36061 +
36062 + /* set generic register fields */
36063 + if (!code)
36064 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
36065 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
36066 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
36067 + genTmp |= offset;
36068 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
36069 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
36070 +
36071 + /************************************************************************************
36072 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
36073 + in the following way:
36074 +
36075 + Driver API and implementation:
36076 + ==============================
36077 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
36078 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
36079 + are not overlapping FQID.
36080 + ------------------------
36081 + | FQID (24) |
36082 + ------------------------
36083 + --------
36084 + | | extracted OR byte
36085 + --------
36086 +
36087 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
36088 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
36089 + are not overlapping PP id.
36090 +
36091 + --------
36092 + | PP (8) |
36093 + --------
36094 + --------
36095 + | | extracted OR byte
36096 + --------
36097 +
36098 + HW implementation
36099 + =================
36100 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
36101 + as the highest byte of that word and may be rotated to effect any part os the FQID or
36102 + the PP.
36103 + ------------------------ --------
36104 + | FQID (24) || PP (8) |
36105 + ------------------------ --------
36106 + --------
36107 + | | extracted OR byte
36108 + --------
36109 +
36110 + ************************************************************************************/
36111 +
36112 + if (p_ExtractOr->bitOffsetInFqid)
36113 + {
36114 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
36115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
36116 + if (p_ExtractOr->bitOffsetInFqid<8)
36117 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
36118 + else
36119 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
36120 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
36121 + }
36122 + else /* effect policer profile */
36123 + {
36124 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
36125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
36126 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
36127 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
36128 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
36129 + }
36130 +
36131 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
36132 + /* clear bits that need masking */
36133 + genTmp &= ~KG_SCH_GEN_MASK ;
36134 + /* set mask bits */
36135 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
36136 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
36137 +
36138 + }
36139 + /* clear all unused GEC registers */
36140 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
36141 + p_SchemeRegs->kgse_gec[i] = 0;
36142 +
36143 + /* add base Qid for this scheme */
36144 + /* add configuration for kgse_fqb */
36145 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
36146 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
36147 +
36148 + fqbTmp |= p_SchemeParams->baseFqid;
36149 + p_SchemeRegs->kgse_fqb = fqbTmp;
36150 +
36151 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
36152 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
36153 +
36154 + return E_OK;
36155 +}
36156 +
36157 +
36158 +/*****************************************************************************/
36159 +/* Inter-module API routines */
36160 +/*****************************************************************************/
36161 +
36162 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
36163 +{
36164 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36165 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36166 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36167 + t_Error err = E_OK;
36168 + uint32_t oredVectors = 0;
36169 + int i, j;
36170 +
36171 + /* this routine is protected by the calling routine ! */
36172 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
36173 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
36174 +
36175 + /* find a new clsPlan group */
36176 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
36177 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
36178 + break;
36179 + if (i == FM_MAX_NUM_OF_PORTS)
36180 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
36181 +
36182 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
36183 +
36184 + p_Grp->clsPlanGrpId = (uint8_t)i;
36185 +
36186 + if (p_Grp->numOfOptions == 0)
36187 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
36188 +
36189 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
36190 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
36191 + p_ClsPlanGrp->owners = 0;
36192 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
36193 + if (p_Grp->numOfOptions != 0)
36194 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36195 +
36196 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36197 + /* a minimal group of 8 is required */
36198 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36199 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36200 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36201 + {
36202 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36203 +
36204 + if (err)
36205 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36206 + }
36207 + else
36208 + {
36209 + t_FmPcdIpcMsg msg;
36210 + uint32_t replyLength;
36211 + t_FmPcdIpcReply reply;
36212 +
36213 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36214 + memset(&reply, 0, sizeof(reply));
36215 + memset(&msg, 0, sizeof(msg));
36216 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36217 + kgAlloc.guestId = p_FmPcd->guestId;
36218 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36219 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36220 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36221 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36222 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36223 + (uint8_t*)&msg,
36224 + sizeof(msg.msgId) + sizeof(kgAlloc),
36225 + (uint8_t*)&reply,
36226 + &replyLength,
36227 + NULL,
36228 + NULL)) != E_OK)
36229 + RETURN_ERROR(MAJOR, err, NO_MSG);
36230 +
36231 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36232 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36233 + if ((t_Error)reply.error != E_OK)
36234 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36235 +
36236 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36237 + }
36238 +
36239 + /* build classification plan entries parameters */
36240 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36241 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36242 +
36243 + oredVectors = 0;
36244 + for (i = 0; i<p_Grp->numOfOptions; i++)
36245 + {
36246 + oredVectors |= p_Grp->optVectors[i];
36247 + /* save an array of used options - the indexes represent the power of 2 index */
36248 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36249 + }
36250 + /* set the classification plan relevant entries so that all bits
36251 + * relevant to the list of options is cleared
36252 + */
36253 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36254 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36255 +
36256 + for (i = 0; i<p_Grp->numOfOptions; i++)
36257 + {
36258 + /* option i got the place 2^i in the clsPlan array. all entries that
36259 + * have bit i set, should have the vector bit cleared. So each option
36260 + * has one location that it is exclusive (1,2,4,8...) and represent the
36261 + * presence of that option only, and other locations that represent a
36262 + * combination of options.
36263 + * e.g:
36264 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36265 + * now represents a frame with ethernet-BC header - so the bit
36266 + * representing ethernet-BC should be set and all other option bits
36267 + * should be cleared.
36268 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36269 + * vector[1] set, but they also have other bits set:
36270 + * 3=1+2, options 0 and 1
36271 + * 6=2+4, options 1 and 2
36272 + * 7=1+2+4, options 0,1,and 2
36273 + * 10=2+8, options 1 and 3
36274 + * etc.
36275 + * */
36276 +
36277 + /* now for each option (i), we set their bits in all entries (j)
36278 + * that contain bit 2^i.
36279 + */
36280 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36281 + {
36282 + if (j & (1<<i))
36283 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36284 + }
36285 + }
36286 +
36287 + return E_OK;
36288 +}
36289 +
36290 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36291 +{
36292 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36293 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36294 + t_Error err;
36295 + t_FmPcdIpcMsg msg;
36296 + uint32_t replyLength;
36297 + t_FmPcdIpcReply reply;
36298 +
36299 + /* check that no port is bound to this clsPlan */
36300 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36301 + {
36302 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36303 + return;
36304 + }
36305 +
36306 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36307 +
36308 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36309 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36310 + else
36311 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36312 +
36313 + /* free blocks */
36314 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36315 + KgFreeClsPlanEntries(h_FmPcd,
36316 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36317 + p_FmPcd->guestId,
36318 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36319 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36320 + {
36321 + memset(&reply, 0, sizeof(reply));
36322 + memset(&msg, 0, sizeof(msg));
36323 + kgAlloc.guestId = p_FmPcd->guestId;
36324 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36325 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36326 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36327 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36328 + replyLength = sizeof(uint32_t);
36329 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36330 + (uint8_t*)&msg,
36331 + sizeof(msg.msgId) + sizeof(kgAlloc),
36332 + (uint8_t*)&reply,
36333 + &replyLength,
36334 + NULL,
36335 + NULL);
36336 + if (err != E_OK)
36337 + {
36338 + REPORT_ERROR(MINOR, err, NO_MSG);
36339 + return;
36340 + }
36341 + if (replyLength != sizeof(uint32_t))
36342 + {
36343 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36344 + return;
36345 + }
36346 + if ((t_Error)reply.error != E_OK)
36347 + {
36348 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36349 + return;
36350 + }
36351 + }
36352 +
36353 + /* clear clsPlan driver structure */
36354 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36355 +}
36356 +
36357 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36358 +{
36359 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36360 + uint32_t j, schemesPerPortVector = 0;
36361 + t_FmPcdKgScheme *p_Scheme;
36362 + uint8_t i, relativeSchemeId;
36363 + uint32_t tmp, walking1Mask;
36364 + uint8_t swPortIndex = 0;
36365 +
36366 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36367 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36368 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36369 +
36370 + /* for each scheme */
36371 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36372 + {
36373 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36374 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36375 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36376 +
36377 + if (add)
36378 + {
36379 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36380 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36381 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36382 + /* check netEnvId of the port against the scheme netEnvId */
36383 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36384 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36385 +
36386 + /* if next engine is private port policer profile, we need to check that it is valid */
36387 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36388 + if (p_Scheme->nextRelativePlcrProfile)
36389 + {
36390 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36391 + {
36392 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36393 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36394 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36395 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36396 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36397 + }
36398 + }
36399 + if (!p_BindPort->useClsPlan)
36400 + {
36401 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36402 +
36403 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36404 + cls plan options. Schemes that are used only directly, should not be checked.
36405 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36406 + the match vector and the grpBits (= ccUnits) */
36407 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36408 + {
36409 + uint8_t netEnvId;
36410 + walking1Mask = 0x80000000;
36411 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36412 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36413 + tmp |= p_Scheme->ccUnits;
36414 + while (tmp)
36415 + {
36416 + if (tmp & walking1Mask)
36417 + {
36418 + tmp &= ~walking1Mask;
36419 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36420 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36421 + }
36422 + walking1Mask >>= 1;
36423 + }
36424 + }
36425 + }
36426 + }
36427 + /* build vector */
36428 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36429 + }
36430 +
36431 + *p_SpReg = schemesPerPortVector;
36432 +
36433 + return E_OK;
36434 +}
36435 +
36436 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36437 +{
36438 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36439 + uint32_t spReg;
36440 + t_Error err = E_OK;
36441 +
36442 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36443 + if (err)
36444 + RETURN_ERROR(MAJOR, err, NO_MSG);
36445 +
36446 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36447 + if (err)
36448 + RETURN_ERROR(MAJOR, err, NO_MSG);
36449 +
36450 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36451 +
36452 + return E_OK;
36453 +}
36454 +
36455 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36456 +{
36457 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36458 + uint32_t spReg;
36459 + t_Error err = E_OK;
36460 +
36461 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36462 + if (err)
36463 + RETURN_ERROR(MAJOR, err, NO_MSG);
36464 +
36465 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36466 + if (err)
36467 + RETURN_ERROR(MAJOR, err, NO_MSG);
36468 +
36469 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36470 +
36471 + return E_OK;
36472 +}
36473 +
36474 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36475 +{
36476 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36477 +
36478 + return p_Scheme->valid;
36479 +}
36480 +
36481 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36482 +{
36483 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36484 +
36485 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36486 + return TRUE;
36487 + else
36488 + return FALSE;
36489 +}
36490 +
36491 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36492 +{
36493 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36494 + uint8_t i, j;
36495 +
36496 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36497 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36498 +
36499 + /* This routine is issued only on master core of master partition -
36500 + either directly or through IPC, so no need for lock */
36501 +
36502 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36503 + {
36504 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36505 + {
36506 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36507 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36508 + p_SchemesIds[j] = i;
36509 + j++;
36510 + }
36511 + }
36512 +
36513 + if (j != numOfSchemes)
36514 + {
36515 + /* roll back */
36516 + for (j--; j; j--)
36517 + {
36518 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36519 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36520 + p_SchemesIds[j] = 0;
36521 + }
36522 +
36523 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36524 + }
36525 +
36526 + return E_OK;
36527 +}
36528 +
36529 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36530 +{
36531 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36532 + uint8_t i;
36533 +
36534 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36535 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36536 +
36537 + /* This routine is issued only on master core of master partition -
36538 + either directly or through IPC */
36539 +
36540 + for (i = 0; i < numOfSchemes; i++)
36541 + {
36542 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36543 + {
36544 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36545 + }
36546 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36547 + {
36548 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36549 + }
36550 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36551 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36552 + }
36553 +
36554 + return E_OK;
36555 +}
36556 +
36557 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36558 +{
36559 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36560 + uint8_t numOfBlocks, blocksFound=0, first=0;
36561 + uint8_t i, j;
36562 +
36563 + /* This routine is issued only on master core of master partition -
36564 + either directly or through IPC, so no need for lock */
36565 +
36566 + if (!numOfClsPlanEntries)
36567 + return E_OK;
36568 +
36569 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36570 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36571 +
36572 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36573 +
36574 + /* try to find consequent blocks */
36575 + first = 0;
36576 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36577 + {
36578 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36579 + {
36580 + blocksFound++;
36581 + i++;
36582 + if (blocksFound == numOfBlocks)
36583 + break;
36584 + }
36585 + else
36586 + {
36587 + blocksFound = 0;
36588 + /* advance i to the next aligned address */
36589 + first = i = (uint8_t)(first + numOfBlocks);
36590 + }
36591 + }
36592 +
36593 + if (blocksFound == numOfBlocks)
36594 + {
36595 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36596 + for (j = first; j < (first + numOfBlocks); j++)
36597 + {
36598 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36599 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36600 + }
36601 + return E_OK;
36602 + }
36603 + else
36604 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36605 +}
36606 +
36607 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36608 +{
36609 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36610 + uint8_t numOfBlocks;
36611 + uint8_t i, baseBlock;
36612 +
36613 +#ifdef DISABLE_ASSERTIONS
36614 +UNUSED(guestId);
36615 +#endif /* DISABLE_ASSERTIONS */
36616 +
36617 + /* This routine is issued only on master core of master partition -
36618 + either directly or through IPC, so no need for lock */
36619 +
36620 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36621 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36622 +
36623 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36624 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36625 + {
36626 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36627 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36628 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36629 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36630 + }
36631 +}
36632 +
36633 +void KgEnable(t_FmPcd *p_FmPcd)
36634 +{
36635 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36636 +
36637 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36638 + fman_kg_enable(p_Regs);
36639 +}
36640 +
36641 +void KgDisable(t_FmPcd *p_FmPcd)
36642 +{
36643 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36644 +
36645 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36646 + fman_kg_disable(p_Regs);
36647 +}
36648 +
36649 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36650 +{
36651 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36652 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36653 + uint32_t tmpKgarReg = 0, intFlags;
36654 + uint16_t i, j;
36655 +
36656 + /* This routine is protected by the calling routine ! */
36657 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36658 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36659 +
36660 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36661 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36662 + {
36663 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36664 +
36665 + for (j = i; j < i+8; j++)
36666 + {
36667 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36668 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36669 + }
36670 +
36671 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36672 + {
36673 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36674 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36675 + return;
36676 + }
36677 + }
36678 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36679 +}
36680 +
36681 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36682 +{
36683 + t_FmPcdKg *p_FmPcdKg;
36684 +
36685 + UNUSED(p_FmPcd);
36686 +
36687 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36688 + {
36689 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36690 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36691 + return NULL;
36692 + }
36693 +
36694 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36695 + if (!p_FmPcdKg)
36696 + {
36697 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36698 + return NULL;
36699 + }
36700 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36701 +
36702 +
36703 + if (FmIsMaster(p_FmPcd->h_Fm))
36704 + {
36705 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36706 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36707 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36708 + }
36709 +
36710 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36711 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36712 + {
36713 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36714 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36715 + }
36716 +
36717 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36718 +
36719 + return p_FmPcdKg;
36720 +}
36721 +
36722 +t_Error KgInit(t_FmPcd *p_FmPcd)
36723 +{
36724 + t_Error err = E_OK;
36725 +
36726 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36727 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36728 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36729 +
36730 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36731 + err = KgInitMaster(p_FmPcd);
36732 + else
36733 + err = KgInitGuest(p_FmPcd);
36734 +
36735 + if (err != E_OK)
36736 + {
36737 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36738 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36739 + }
36740 +
36741 + return err;
36742 +}
36743 +
36744 +t_Error KgFree(t_FmPcd *p_FmPcd)
36745 +{
36746 + t_FmPcdIpcKgSchemesParams kgAlloc;
36747 + t_Error err = E_OK;
36748 + t_FmPcdIpcMsg msg;
36749 + uint32_t replyLength;
36750 + t_FmPcdIpcReply reply;
36751 +
36752 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36753 +
36754 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36755 + {
36756 + err = FmPcdKgFreeSchemes(p_FmPcd,
36757 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36758 + p_FmPcd->guestId,
36759 + p_FmPcd->p_FmPcdKg->schemesIds);
36760 + if (err)
36761 + RETURN_ERROR(MAJOR, err, NO_MSG);
36762 +
36763 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36764 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36765 +
36766 + return E_OK;
36767 + }
36768 +
36769 + /* guest */
36770 + memset(&reply, 0, sizeof(reply));
36771 + memset(&msg, 0, sizeof(msg));
36772 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36773 + kgAlloc.guestId = p_FmPcd->guestId;
36774 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36775 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36776 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36777 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36778 + replyLength = sizeof(uint32_t);
36779 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36780 + (uint8_t*)&msg,
36781 + sizeof(msg.msgId) + sizeof(kgAlloc),
36782 + (uint8_t*)&reply,
36783 + &replyLength,
36784 + NULL,
36785 + NULL)) != E_OK)
36786 + RETURN_ERROR(MAJOR, err, NO_MSG);
36787 + if (replyLength != sizeof(uint32_t))
36788 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36789 +
36790 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36791 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36792 +
36793 + return (t_Error)reply.error;
36794 +}
36795 +
36796 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36797 +{
36798 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36799 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36800 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36801 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36802 + t_Error err;
36803 +
36804 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36805 + so no need for lock here */
36806 +
36807 + memset(&grpParams, 0, sizeof(grpParams));
36808 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36809 + p_GrpParams = &grpParams;
36810 +
36811 + p_GrpParams->netEnvId = netEnvId;
36812 +
36813 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36814 + * or needs to build) */
36815 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36816 + if (err)
36817 + RETURN_ERROR(MINOR,err,NO_MSG);
36818 +
36819 + if (p_GrpParams->grpExists)
36820 + {
36821 + /* this group was already updated (at least) in SW */
36822 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36823 + }
36824 + else
36825 + {
36826 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36827 + if (!p_ClsPlanSet)
36828 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36829 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36830 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36831 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36832 + if (err)
36833 + {
36834 + XX_Free(p_ClsPlanSet);
36835 + RETURN_ERROR(MINOR, err, NO_MSG);
36836 + }
36837 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36838 +
36839 + if (p_FmPcd->h_Hc)
36840 + {
36841 + /* write clsPlan entries to memory */
36842 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
36843 + if (err)
36844 + {
36845 + XX_Free(p_ClsPlanSet);
36846 + RETURN_ERROR(MAJOR, err, NO_MSG);
36847 + }
36848 + }
36849 + else
36850 + /* write clsPlan entries to memory */
36851 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36852 +
36853 + XX_Free(p_ClsPlanSet);
36854 + }
36855 +
36856 + /* Set caller parameters */
36857 +
36858 + /* mark if this is an empty classification group */
36859 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36860 + *p_IsEmptyClsPlanGrp = TRUE;
36861 + else
36862 + *p_IsEmptyClsPlanGrp = FALSE;
36863 +
36864 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
36865 +
36866 + /* increment owners number */
36867 + p_ClsPlanGrp->owners++;
36868 +
36869 + /* copy options array for port */
36870 + 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));
36871 +
36872 + /* bind port to the new or existing group */
36873 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
36874 + if (err)
36875 + RETURN_ERROR(MINOR, err, NO_MSG);
36876 +
36877 + return E_OK;
36878 +}
36879 +
36880 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
36881 +{
36882 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36883 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
36884 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36885 + t_Error err;
36886 +
36887 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
36888 + so no need for lock here */
36889 +
36890 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
36891 +
36892 + /* decrement owners number */
36893 + ASSERT_COND(p_ClsPlanGrp->owners);
36894 + p_ClsPlanGrp->owners--;
36895 +
36896 + if (!p_ClsPlanGrp->owners)
36897 + {
36898 + if (p_FmPcd->h_Hc)
36899 + {
36900 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
36901 + return err;
36902 + }
36903 + else
36904 + {
36905 + /* clear clsPlan entries in memory */
36906 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36907 + if (!p_ClsPlanSet)
36908 + {
36909 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36910 + }
36911 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36912 +
36913 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
36914 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
36915 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36916 + XX_Free(p_ClsPlanSet);
36917 +
36918 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
36919 + }
36920 + }
36921 + return E_OK;
36922 +}
36923 +
36924 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
36925 +{
36926 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36927 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36928 +
36929 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
36930 +}
36931 +
36932 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
36933 +{
36934 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36935 +
36936 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36937 +
36938 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
36939 +}
36940 +
36941 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
36942 +{
36943 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36944 +
36945 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36946 +
36947 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
36948 +}
36949 +
36950 +
36951 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
36952 +{
36953 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36954 +
36955 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36956 +
36957 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
36958 +}
36959 +
36960 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
36961 +{
36962 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36963 +
36964 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36965 +
36966 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
36967 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
36968 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
36969 + return TRUE;
36970 + else
36971 + return FALSE;
36972 +
36973 +}
36974 +
36975 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
36976 +{
36977 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36978 +
36979 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
36980 +
36981 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
36982 +}
36983 +
36984 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
36985 +{
36986 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36987 +
36988 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36989 +
36990 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
36991 +}
36992 +
36993 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
36994 +{
36995 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
36996 +
36997 + /* this routine is protected by calling routine */
36998 +
36999 + ASSERT_COND(p_Scheme->valid);
37000 +
37001 + p_Scheme->requiredAction |= requiredAction;
37002 +}
37003 +
37004 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
37005 +{
37006 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
37007 +}
37008 +
37009 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
37010 +{
37011 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37012 + FM_KG_KGAR_GO |
37013 + FM_KG_KGAR_WRITE |
37014 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37015 + DUMMY_PORT_ID |
37016 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
37017 +}
37018 +
37019 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
37020 +{
37021 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37022 + FM_KG_KGAR_GO |
37023 + FM_KG_KGAR_READ |
37024 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37025 + DUMMY_PORT_ID |
37026 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
37027 +
37028 +}
37029 +
37030 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
37031 +{
37032 + return (uint32_t)(FM_KG_KGAR_GO |
37033 + FM_KG_KGAR_WRITE |
37034 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
37035 + DUMMY_PORT_ID |
37036 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37037 + FM_PCD_KG_KGAR_WSEL_MASK);
37038 +
37039 + /* if we ever want to write 1 by 1, use:
37040 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
37041 + */
37042 +}
37043 +
37044 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
37045 +{
37046 +
37047 + return (uint32_t)(FM_KG_KGAR_GO |
37048 + FM_KG_KGAR_WRITE |
37049 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37050 + hardwarePortId |
37051 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37052 +}
37053 +
37054 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
37055 +{
37056 +
37057 + return (uint32_t)(FM_KG_KGAR_GO |
37058 + FM_KG_KGAR_READ |
37059 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37060 + hardwarePortId |
37061 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37062 +}
37063 +
37064 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
37065 +{
37066 +
37067 + return (uint32_t)(FM_KG_KGAR_GO |
37068 + FM_KG_KGAR_WRITE |
37069 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37070 + hardwarePortId |
37071 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
37072 +}
37073 +
37074 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37075 +{
37076 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37077 +
37078 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
37079 +}
37080 +
37081 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37082 +{
37083 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37084 +
37085 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
37086 +}
37087 +
37088 +
37089 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
37090 +{
37091 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
37092 +
37093 +}
37094 +
37095 +#if (DPAA_VERSION >= 11)
37096 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
37097 +{
37098 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
37099 +
37100 +}
37101 +#endif /* (DPAA_VERSION >= 11) */
37102 +
37103 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
37104 +{
37105 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37106 + uint8_t i;
37107 +
37108 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
37109 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
37110 + return i;
37111 +
37112 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
37113 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
37114 +
37115 + return FM_PCD_KG_NUM_OF_SCHEMES;
37116 +}
37117 +
37118 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37119 +{
37120 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37121 +
37122 + ASSERT_COND(p_FmPcd);
37123 +
37124 + /* check that schemeId is in range */
37125 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37126 + {
37127 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37128 + return NULL;
37129 + }
37130 +
37131 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
37132 + return NULL;
37133 +
37134 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37135 +}
37136 +
37137 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
37138 +{
37139 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
37140 +}
37141 +
37142 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
37143 +{
37144 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37145 + uint8_t relativeSchemeId, physicalSchemeId;
37146 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
37147 + t_Error err;
37148 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37149 +
37150 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
37151 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
37152 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
37153 +
37154 + /* Calling function locked all PCD modules, so no need to lock here */
37155 +
37156 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37157 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37158 +
37159 + if (p_FmPcd->h_Hc)
37160 + {
37161 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
37162 +
37163 + UpdateRequiredActionFlag(h_Scheme,TRUE);
37164 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
37165 + return err;
37166 + }
37167 +
37168 + physicalSchemeId = p_Scheme->schemeId;
37169 +
37170 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
37171 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37172 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37173 +
37174 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
37175 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
37176 + {
37177 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
37178 + {
37179 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
37180 + {
37181 + case (e_FM_PCD_DONE):
37182 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
37183 + {
37184 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37185 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37186 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37187 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37188 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
37189 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
37190 + /* call indirect command for scheme write */
37191 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37192 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37193 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37194 + }
37195 + break;
37196 + case (e_FM_PCD_PLCR):
37197 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37198 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37199 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37200 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37201 + {
37202 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37203 + }
37204 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37205 + if (err)
37206 + {
37207 + RETURN_ERROR(MAJOR, err, NO_MSG);
37208 + }
37209 + break;
37210 + default:
37211 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37212 + }
37213 + }
37214 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37215 + {
37216 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37217 + {
37218 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37219 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37220 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37221 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37222 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37223 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37224 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37225 + /* call indirect command for scheme write */
37226 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37227 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37228 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37229 + }
37230 + }
37231 + if (requiredAction & UPDATE_KG_OPT_MODE)
37232 + {
37233 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37234 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37235 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37236 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37237 + /* call indirect command for scheme write */
37238 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37239 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37240 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37241 + }
37242 + if (requiredAction & UPDATE_KG_NIA)
37243 + {
37244 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37245 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37246 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37247 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37248 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37249 + tmpReg32 |= value;
37250 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37251 + /* call indirect command for scheme write */
37252 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37253 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37254 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37255 + }
37256 + }
37257 +
37258 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37259 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37260 +
37261 + return E_OK;
37262 +}
37263 +/*********************** End of inter-module routines ************************/
37264 +
37265 +
37266 +/****************************************/
37267 +/* API routines */
37268 +/****************************************/
37269 +
37270 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37271 +{
37272 + t_FmPcd *p_FmPcd;
37273 + struct fman_kg_scheme_regs schemeRegs;
37274 + struct fman_kg_scheme_regs *p_MemRegs;
37275 + uint8_t i;
37276 + t_Error err = E_OK;
37277 + uint32_t tmpKgarReg;
37278 + uint32_t intFlags;
37279 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37280 + t_FmPcdKgScheme *p_Scheme;
37281 +
37282 + if (p_SchemeParams->modify)
37283 + {
37284 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37285 + p_FmPcd = p_Scheme->h_FmPcd;
37286 +
37287 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37288 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37289 +
37290 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37291 + {
37292 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37293 + ("Scheme is invalid"));
37294 + return NULL;
37295 + }
37296 +
37297 + if (!KgSchemeFlagTryLock(p_Scheme))
37298 + {
37299 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37300 + /* Signal to caller BUSY condition */
37301 + p_SchemeParams->id.h_Scheme = NULL;
37302 + return NULL;
37303 + }
37304 + }
37305 + else
37306 + {
37307 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37308 +
37309 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37310 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37311 +
37312 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37313 + /* check that schemeId is in range */
37314 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37315 + {
37316 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37317 + return NULL;
37318 + }
37319 +
37320 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37321 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37322 + {
37323 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37324 + ("Scheme id (%d)!", relativeSchemeId));
37325 + return NULL;
37326 + }
37327 + /* Clear all fields, scheme may have beed previously used */
37328 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37329 +
37330 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37331 + p_Scheme->h_FmPcd = p_FmPcd;
37332 +
37333 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37334 + if (!p_Scheme->p_Lock)
37335 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37336 + }
37337 +
37338 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37339 + if (err)
37340 + {
37341 + REPORT_ERROR(MAJOR, err, NO_MSG);
37342 + if (p_SchemeParams->modify)
37343 + KgSchemeFlagUnlock(p_Scheme);
37344 + if (!p_SchemeParams->modify &&
37345 + p_Scheme->p_Lock)
37346 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37347 + return NULL;
37348 + }
37349 +
37350 + if (p_FmPcd->h_Hc)
37351 + {
37352 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37353 + (t_Handle)p_Scheme,
37354 + &schemeRegs,
37355 + p_SchemeParams->schemeCounter.update);
37356 + if (p_SchemeParams->modify)
37357 + KgSchemeFlagUnlock(p_Scheme);
37358 + if (err)
37359 + {
37360 + if (!p_SchemeParams->modify &&
37361 + p_Scheme->p_Lock)
37362 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37363 + return NULL;
37364 + }
37365 + if (!p_SchemeParams->modify)
37366 + ValidateSchemeSw(p_Scheme);
37367 + return (t_Handle)p_Scheme;
37368 + }
37369 +
37370 + physicalSchemeId = p_Scheme->schemeId;
37371 +
37372 + /* configure all 21 scheme registers */
37373 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37374 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37375 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37376 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37377 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37378 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37379 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37380 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37381 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37382 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37383 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37384 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37385 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37386 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37387 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37388 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37389 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37390 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37391 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37392 +
37393 + /* call indirect command for scheme write */
37394 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37395 +
37396 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37397 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37398 +
37399 + if (!p_SchemeParams->modify)
37400 + ValidateSchemeSw(p_Scheme);
37401 + else
37402 + KgSchemeFlagUnlock(p_Scheme);
37403 +
37404 + return (t_Handle)p_Scheme;
37405 +}
37406 +
37407 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37408 +{
37409 + t_FmPcd *p_FmPcd;
37410 + uint8_t physicalSchemeId;
37411 + uint32_t tmpKgarReg, intFlags;
37412 + t_Error err = E_OK;
37413 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37414 +
37415 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37416 +
37417 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37418 +
37419 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37420 +
37421 + /* check that no port is bound to this scheme */
37422 + err = InvalidateSchemeSw(h_Scheme);
37423 + if (err)
37424 + RETURN_ERROR(MINOR, err, NO_MSG);
37425 +
37426 + if (p_FmPcd->h_Hc)
37427 + {
37428 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37429 + if (p_Scheme->p_Lock)
37430 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37431 + return err;
37432 + }
37433 +
37434 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37435 +
37436 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37437 + /* clear mode register, including enable bit */
37438 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37439 +
37440 + /* call indirect command for scheme write */
37441 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37442 +
37443 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37444 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37445 +
37446 + if (p_Scheme->p_Lock)
37447 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37448 +
37449 + return E_OK;
37450 +}
37451 +
37452 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37453 +{
37454 + t_FmPcd *p_FmPcd;
37455 + uint32_t tmpKgarReg, spc, intFlags;
37456 + uint8_t physicalSchemeId;
37457 +
37458 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37459 +
37460 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37461 + if (p_FmPcd->h_Hc)
37462 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37463 +
37464 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37465 +
37466 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37467 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37468 +
37469 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37470 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37471 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37472 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37473 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37474 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37475 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37476 +
37477 + return spc;
37478 +}
37479 +
37480 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37481 +{
37482 + t_FmPcd *p_FmPcd;
37483 + uint32_t tmpKgarReg, intFlags;
37484 + uint8_t physicalSchemeId;
37485 +
37486 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37487 +
37488 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37489 +
37490 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37491 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37492 +
37493 + if (p_FmPcd->h_Hc)
37494 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37495 +
37496 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37497 + /* check that schemeId is in range */
37498 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37499 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37500 +
37501 + /* read specified scheme into scheme registers */
37502 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37503 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37504 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37505 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37506 + {
37507 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37508 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37509 + }
37510 +
37511 + /* change counter value */
37512 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37513 +
37514 + /* call indirect command for scheme write */
37515 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37516 +
37517 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37518 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37519 +
37520 + return E_OK;
37521 +}
37522 +
37523 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37524 +{
37525 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37526 + struct fman_kg_regs *p_Regs;
37527 +
37528 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37529 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37530 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37531 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37532 +
37533 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37534 + if (!FmIsMaster(p_FmPcd->h_Fm))
37535 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37536 +
37537 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37538 +
37539 + return E_OK;
37540 +}
37541 +
37542 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37543 +{
37544 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37545 + struct fman_kg_regs *p_Regs;
37546 +
37547 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37548 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37549 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37550 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37551 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37552 +
37553 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37554 +
37555 + if (!FmIsMaster(p_FmPcd->h_Fm))
37556 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37557 +
37558 + if (valueId == 0)
37559 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37560 + else
37561 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37562 + return E_OK;
37563 +}
37564 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37565 new file mode 100644
37566 index 00000000..cb7521a1
37567 --- /dev/null
37568 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37569 @@ -0,0 +1,206 @@
37570 +/*
37571 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37572 + *
37573 + * Redistribution and use in source and binary forms, with or without
37574 + * modification, are permitted provided that the following conditions are met:
37575 + * * Redistributions of source code must retain the above copyright
37576 + * notice, this list of conditions and the following disclaimer.
37577 + * * Redistributions in binary form must reproduce the above copyright
37578 + * notice, this list of conditions and the following disclaimer in the
37579 + * documentation and/or other materials provided with the distribution.
37580 + * * Neither the name of Freescale Semiconductor nor the
37581 + * names of its contributors may be used to endorse or promote products
37582 + * derived from this software without specific prior written permission.
37583 + *
37584 + *
37585 + * ALTERNATIVELY, this software may be distributed under the terms of the
37586 + * GNU General Public License ("GPL") as published by the Free Software
37587 + * Foundation, either version 2 of that License or (at your option) any
37588 + * later version.
37589 + *
37590 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37591 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37592 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37593 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37594 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37595 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37596 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37597 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37598 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37599 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37600 + */
37601 +
37602 +
37603 +/******************************************************************************
37604 + @File fm_kg.h
37605 +
37606 + @Description FM KG private header
37607 +*//***************************************************************************/
37608 +#ifndef __FM_KG_H
37609 +#define __FM_KG_H
37610 +
37611 +#include "std_ext.h"
37612 +
37613 +/***********************************************************************/
37614 +/* Keygen defines */
37615 +/***********************************************************************/
37616 +/* maskes */
37617 +#if (DPAA_VERSION >= 11)
37618 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37619 +#define KG_SCH_OM_VSPE 0x00000001
37620 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37621 +
37622 +#define MAX_SP_SHIFT 23
37623 +#define KG_SCH_VSP_MASK_SHIFT 12
37624 +#define KG_SCH_VSP_SHIFT 24
37625 +#endif /* (DPAA_VERSION >= 11) */
37626 +
37627 +typedef uint32_t t_KnownFieldsMasks;
37628 +#define KG_SCH_KN_PORT_ID 0x80000000
37629 +#define KG_SCH_KN_MACDST 0x40000000
37630 +#define KG_SCH_KN_MACSRC 0x20000000
37631 +#define KG_SCH_KN_TCI1 0x10000000
37632 +#define KG_SCH_KN_TCI2 0x08000000
37633 +#define KG_SCH_KN_ETYPE 0x04000000
37634 +#define KG_SCH_KN_PPPSID 0x02000000
37635 +#define KG_SCH_KN_PPPID 0x01000000
37636 +#define KG_SCH_KN_MPLS1 0x00800000
37637 +#define KG_SCH_KN_MPLS2 0x00400000
37638 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37639 +#define KG_SCH_KN_IPSRC1 0x00100000
37640 +#define KG_SCH_KN_IPDST1 0x00080000
37641 +#define KG_SCH_KN_PTYPE1 0x00040000
37642 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37643 +#define KG_SCH_KN_IPV6FL1 0x00010000
37644 +#define KG_SCH_KN_IPSRC2 0x00008000
37645 +#define KG_SCH_KN_IPDST2 0x00004000
37646 +#define KG_SCH_KN_PTYPE2 0x00002000
37647 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37648 +#define KG_SCH_KN_IPV6FL2 0x00000800
37649 +#define KG_SCH_KN_GREPTYPE 0x00000400
37650 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37651 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37652 +#define KG_SCH_KN_IPPID 0x00000080
37653 +#define KG_SCH_KN_L4PSRC 0x00000004
37654 +#define KG_SCH_KN_L4PDST 0x00000002
37655 +#define KG_SCH_KN_TFLG 0x00000001
37656 +
37657 +typedef uint8_t t_GenericCodes;
37658 +#define KG_SCH_GEN_SHIM1 0x70
37659 +#define KG_SCH_GEN_DEFAULT 0x10
37660 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37661 +#define KG_SCH_GEN_START_OF_FRM 0x40
37662 +#define KG_SCH_GEN_SHIM2 0x71
37663 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37664 +#define KG_SCH_GEN_ETH 0x03
37665 +#define KG_SCH_GEN_ETH_NO_V 0x73
37666 +#define KG_SCH_GEN_SNAP 0x04
37667 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37668 +#define KG_SCH_GEN_VLAN1 0x05
37669 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37670 +#define KG_SCH_GEN_VLAN2 0x06
37671 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37672 +#define KG_SCH_GEN_ETH_TYPE 0x07
37673 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37674 +#define KG_SCH_GEN_PPP 0x08
37675 +#define KG_SCH_GEN_PPP_NO_V 0x78
37676 +#define KG_SCH_GEN_MPLS1 0x09
37677 +#define KG_SCH_GEN_MPLS2 0x19
37678 +#define KG_SCH_GEN_MPLS3 0x29
37679 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37680 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37681 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37682 +#define KG_SCH_GEN_IPV4 0x0b
37683 +#define KG_SCH_GEN_IPV6 0x1b
37684 +#define KG_SCH_GEN_L3_NO_V 0x7b
37685 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37686 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37687 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37688 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37689 +#define KG_SCH_GEN_GRE 0x0d
37690 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37691 +#define KG_SCH_GEN_TCP 0x0e
37692 +#define KG_SCH_GEN_UDP 0x1e
37693 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37694 +#define KG_SCH_GEN_SCTP 0x3e
37695 +#define KG_SCH_GEN_DCCP 0x4e
37696 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37697 +#define KG_SCH_GEN_L4_NO_V 0x7e
37698 +#define KG_SCH_GEN_NEXTHDR 0x7f
37699 +/* shifts */
37700 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37701 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37702 +#define KG_SCH_PP_MASK_SHIFT 16
37703 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37704 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37705 +#define KG_SCH_DEF_TCI_SHIFT 28
37706 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37707 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37708 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37709 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37710 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37711 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37712 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37713 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37714 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37715 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37716 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37717 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37718 +#define KG_SCH_GEN_MASK_SHIFT 16
37719 +#define KG_SCH_GEN_HT_SHIFT 8
37720 +#define KG_SCH_GEN_SIZE_SHIFT 24
37721 +#define KG_SCH_GEN_DEF_SHIFT 29
37722 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37723 +
37724 +/* others */
37725 +#define NUM_OF_SW_DEFAULTS 3
37726 +#define MAX_PP_SHIFT 23
37727 +#define MAX_KG_SCH_SIZE 16
37728 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37729 +#define MAX_HASH_SHIFT 40
37730 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37731 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37732 +#define MAX_DIST_FQID_SHIFT 23
37733 +
37734 +#define GET_MASK_SEL_SHIFT(shift,i) \
37735 +switch (i) { \
37736 + case (0):shift = 26;break; \
37737 + case (1):shift = 20;break; \
37738 + case (2):shift = 10;break; \
37739 + case (3):shift = 4;break; \
37740 + default: \
37741 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37742 +}
37743 +
37744 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37745 +switch (i) { \
37746 + case (0):shift = 16;break; \
37747 + case (1):shift = 0;break; \
37748 + case (2):shift = 28;break; \
37749 + case (3):shift = 24;break; \
37750 + default: \
37751 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37752 +}
37753 +
37754 +#define GET_MASK_SHIFT(shift,i) \
37755 +switch (i) { \
37756 + case (0):shift = 24;break; \
37757 + case (1):shift = 16;break; \
37758 + case (2):shift = 8;break; \
37759 + case (3):shift = 0;break; \
37760 + default: \
37761 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37762 +}
37763 +
37764 +/***********************************************************************/
37765 +/* Keygen defines */
37766 +/***********************************************************************/
37767 +
37768 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37769 +#define NO_VALIDATION 0x70
37770 +#define KG_ACTION_REG_TO 1024
37771 +#define KG_MAX_PROFILE 255
37772 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37773 +
37774 +
37775 +#endif /* __FM_KG_H */
37776 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37777 new file mode 100644
37778 index 00000000..113777e5
37779 --- /dev/null
37780 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37781 @@ -0,0 +1,5571 @@
37782 +/*
37783 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37784 + *
37785 + * Redistribution and use in source and binary forms, with or without
37786 + * modification, are permitted provided that the following conditions are met:
37787 + * * Redistributions of source code must retain the above copyright
37788 + * notice, this list of conditions and the following disclaimer.
37789 + * * Redistributions in binary form must reproduce the above copyright
37790 + * notice, this list of conditions and the following disclaimer in the
37791 + * documentation and/or other materials provided with the distribution.
37792 + * * Neither the name of Freescale Semiconductor nor the
37793 + * names of its contributors may be used to endorse or promote products
37794 + * derived from this software without specific prior written permission.
37795 + *
37796 + *
37797 + * ALTERNATIVELY, this software may be distributed under the terms of the
37798 + * GNU General Public License ("GPL") as published by the Free Software
37799 + * Foundation, either version 2 of that License or (at your option) any
37800 + * later version.
37801 + *
37802 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37803 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37804 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37805 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37806 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37807 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37808 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37809 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37810 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37811 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37812 + */
37813 +
37814 +
37815 +/******************************************************************************
37816 + @File fm_manip.c
37817 +
37818 + @Description FM PCD manip ...
37819 + *//***************************************************************************/
37820 +#include "std_ext.h"
37821 +#include "error_ext.h"
37822 +#include "string_ext.h"
37823 +#include "debug_ext.h"
37824 +#include "fm_pcd_ext.h"
37825 +#include "fm_port_ext.h"
37826 +#include "fm_muram_ext.h"
37827 +#include "memcpy_ext.h"
37828 +
37829 +#include "fm_common.h"
37830 +#include "fm_hc.h"
37831 +#include "fm_manip.h"
37832 +
37833 +/****************************************/
37834 +/* static functions */
37835 +/****************************************/
37836 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37837 +{
37838 + t_FmPcdManip *p_CurManip = p_Manip;
37839 +
37840 + if (!MANIP_IS_UNIFIED(p_Manip))
37841 + p_CurManip = p_Manip;
37842 + else
37843 + {
37844 + /* go to first unified */
37845 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37846 + p_CurManip = p_CurManip->h_PrevManip;
37847 + }
37848 +
37849 + switch (manipInfo)
37850 + {
37851 + case (e_MANIP_HMCT):
37852 + return p_CurManip->p_Hmct;
37853 + case (e_MANIP_HMTD):
37854 + return p_CurManip->h_Ad;
37855 + case (e_MANIP_HANDLER_TABLE_OWNER):
37856 + return (t_Handle)p_CurManip;
37857 + default:
37858 + return NULL;
37859 + }
37860 +}
37861 +
37862 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
37863 +{
37864 + uint16_t size = 0;
37865 + t_FmPcdManip *p_CurManip = p_Manip;
37866 +
37867 + if (!MANIP_IS_UNIFIED(p_Manip))
37868 + return p_Manip->tableSize;
37869 +
37870 + /* accumulate sizes, starting with the first node */
37871 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37872 + p_CurManip = p_CurManip->h_PrevManip;
37873 +
37874 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37875 + {
37876 + size += p_CurManip->tableSize;
37877 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37878 + }
37879 + size += p_CurManip->tableSize; /* add last size */
37880 +
37881 + return (size);
37882 +}
37883 +
37884 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
37885 +{
37886 + uint16_t size = 0;
37887 + t_FmPcdManip *p_CurManip = p_Manip;
37888 +
37889 + if (!MANIP_IS_UNIFIED(p_Manip))
37890 + return p_Manip->dataSize;
37891 +
37892 + /* accumulate sizes, starting with the first node */
37893 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37894 + p_CurManip = p_CurManip->h_PrevManip;
37895 +
37896 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37897 + {
37898 + size += p_CurManip->dataSize;
37899 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37900 + }
37901 + size += p_CurManip->dataSize; /* add last size */
37902 +
37903 + return (size);
37904 +}
37905 +
37906 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
37907 + uint16_t *p_TableSize, uint8_t *p_DataSize)
37908 +{
37909 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
37910 +
37911 + if (p_FmPcdManipParams->u.hdr.rmv)
37912 + {
37913 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
37914 + {
37915 + case (e_FM_PCD_MANIP_RMV_GENERIC):
37916 + tableSize += HMCD_BASIC_SIZE;
37917 + break;
37918 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
37919 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
37920 + {
37921 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
37922 +#if (DPAA_VERSION >= 11)
37923 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
37924 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
37925 +#endif /* (DPAA_VERSION >= 11) */
37926 + tableSize += HMCD_BASIC_SIZE;
37927 + break;
37928 + default:
37929 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37930 + ("Unknown byHdr.type"));
37931 + }
37932 + break;
37933 + default:
37934 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37935 + ("Unknown rmvParams.type"));
37936 + }
37937 + }
37938 +
37939 + if (p_FmPcdManipParams->u.hdr.insrt)
37940 + {
37941 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
37942 + {
37943 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
37944 + remain =
37945 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37946 + % 4);
37947 + if (remain)
37948 + localDataSize =
37949 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37950 + + 4 - remain);
37951 + else
37952 + localDataSize =
37953 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
37954 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
37955 + break;
37956 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
37957 + {
37958 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
37959 + {
37960 +
37961 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
37962 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
37963 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
37964 + {
37965 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
37966 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
37967 + dataSize +=
37968 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
37969 + break;
37970 + default:
37971 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
37972 + }
37973 + break;
37974 +#if (DPAA_VERSION >= 11)
37975 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
37976 + tableSize +=
37977 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
37978 + + HMCD_PARAM_SIZE
37979 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
37980 + dataSize += 2;
37981 + break;
37982 +
37983 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
37984 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
37985 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
37986 +
37987 + break;
37988 +
37989 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
37990 + tableSize +=
37991 + (HMCD_BASIC_SIZE
37992 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
37993 + break;
37994 +#endif /* (DPAA_VERSION >= 11) */
37995 + default:
37996 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37997 + ("Unknown byHdr.type"));
37998 + }
37999 + }
38000 + break;
38001 + default:
38002 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38003 + ("Unknown insrtParams.type"));
38004 + }
38005 + }
38006 +
38007 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38008 + {
38009 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38010 + {
38011 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38012 + tableSize += HMCD_BASIC_SIZE;
38013 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38014 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38015 + {
38016 + tableSize += HMCD_PTR_SIZE;
38017 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
38018 + }
38019 + break;
38020 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38021 + tableSize += HMCD_BASIC_SIZE;
38022 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38023 + & HDR_MANIP_IPV4_ID)
38024 + {
38025 + tableSize += HMCD_PARAM_SIZE;
38026 + dataSize += 2;
38027 + }
38028 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38029 + & HDR_MANIP_IPV4_SRC)
38030 + tableSize += HMCD_IPV4_ADDR_SIZE;
38031 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38032 + & HDR_MANIP_IPV4_DST)
38033 + tableSize += HMCD_IPV4_ADDR_SIZE;
38034 + break;
38035 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38036 + tableSize += HMCD_BASIC_SIZE;
38037 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38038 + & HDR_MANIP_IPV6_SRC)
38039 + tableSize += HMCD_IPV6_ADDR_SIZE;
38040 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38041 + & HDR_MANIP_IPV6_DST)
38042 + tableSize += HMCD_IPV6_ADDR_SIZE;
38043 + break;
38044 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38045 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38046 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38047 + /* we implement this case with the update-checksum descriptor */
38048 + tableSize += HMCD_BASIC_SIZE;
38049 + else
38050 + /* we implement this case with the TCP/UDP-update descriptor */
38051 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38052 + break;
38053 + default:
38054 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38055 + ("Unknown fieldUpdateParams.type"));
38056 + }
38057 + }
38058 +
38059 + if (p_FmPcdManipParams->u.hdr.custom)
38060 + {
38061 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38062 + {
38063 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38064 + {
38065 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
38066 + dataSize +=
38067 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38068 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38069 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38070 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38071 + dataSize += 2;
38072 + }
38073 + break;
38074 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38075 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38076 + break;
38077 + default:
38078 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38079 + ("Unknown customParams.type"));
38080 + }
38081 + }
38082 +
38083 + *p_TableSize = tableSize;
38084 + *p_DataSize = dataSize;
38085 +
38086 + return E_OK;
38087 +}
38088 +
38089 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
38090 + uint8_t *parseArrayOffset)
38091 +{
38092 + e_NetHeaderType hdr = p_HdrInfo->hdr;
38093 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
38094 + bool byField = p_HdrInfo->byField;
38095 + t_FmPcdFields field;
38096 +
38097 + if (byField)
38098 + field = p_HdrInfo->fullField;
38099 +
38100 + if (byField)
38101 + {
38102 + switch (hdr)
38103 + {
38104 + case (HEADER_TYPE_ETH):
38105 + switch (field.eth)
38106 + {
38107 + case (NET_HEADER_FIELD_ETH_TYPE):
38108 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
38109 + break;
38110 + default:
38111 + RETURN_ERROR(
38112 + MAJOR,
38113 + E_NOT_SUPPORTED,
38114 + ("Header manipulation of the type Ethernet with this field not supported"));
38115 + }
38116 + break;
38117 + case (HEADER_TYPE_VLAN):
38118 + switch (field.vlan)
38119 + {
38120 + case (NET_HEADER_FIELD_VLAN_TCI):
38121 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38122 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38123 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
38124 + else
38125 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38126 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
38127 + break;
38128 + default:
38129 + RETURN_ERROR(
38130 + MAJOR,
38131 + E_NOT_SUPPORTED,
38132 + ("Header manipulation of the type VLAN with this field not supported"));
38133 + }
38134 + break;
38135 + default:
38136 + RETURN_ERROR(
38137 + MAJOR,
38138 + E_NOT_SUPPORTED,
38139 + ("Header manipulation of this header by field not supported"));
38140 + }
38141 + }
38142 + else
38143 + {
38144 + switch (hdr)
38145 + {
38146 + case (HEADER_TYPE_ETH):
38147 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
38148 + break;
38149 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
38150 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
38151 + break;
38152 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
38153 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
38154 + break;
38155 + case (HEADER_TYPE_LLC_SNAP):
38156 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
38157 + break;
38158 + case (HEADER_TYPE_PPPoE):
38159 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
38160 + break;
38161 + case (HEADER_TYPE_MPLS):
38162 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38163 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38164 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
38165 + else
38166 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38167 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
38168 + break;
38169 + case (HEADER_TYPE_IPv4):
38170 + case (HEADER_TYPE_IPv6):
38171 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38172 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38173 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
38174 + else
38175 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
38176 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
38177 + break;
38178 + case (HEADER_TYPE_MINENCAP):
38179 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
38180 + break;
38181 + case (HEADER_TYPE_GRE):
38182 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
38183 + break;
38184 + case (HEADER_TYPE_TCP):
38185 + case (HEADER_TYPE_UDP):
38186 + case (HEADER_TYPE_IPSEC_AH):
38187 + case (HEADER_TYPE_IPSEC_ESP):
38188 + case (HEADER_TYPE_DCCP):
38189 + case (HEADER_TYPE_SCTP):
38190 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
38191 + break;
38192 + case (HEADER_TYPE_CAPWAP):
38193 + case (HEADER_TYPE_CAPWAP_DTLS):
38194 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
38195 + break;
38196 + default:
38197 + RETURN_ERROR(
38198 + MAJOR,
38199 + E_NOT_SUPPORTED,
38200 + ("Header manipulation of this header is not supported"));
38201 + }
38202 + }
38203 + return E_OK;
38204 +}
38205 +
38206 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38207 + t_FmPcdManipParams *p_FmPcdManipParams,
38208 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38209 +{
38210 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38211 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38212 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38213 + p_DestData;
38214 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38215 + uint8_t j = 0;
38216 +
38217 + if (p_FmPcdManipParams->u.hdr.rmv)
38218 + {
38219 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38220 + == e_FM_PCD_MANIP_RMV_GENERIC)
38221 + {
38222 + /* initialize HMCD */
38223 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38224 + /* tmp, should be conditional */
38225 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38226 + << HMCD_RMV_OFFSET_SHIFT;
38227 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38228 + << HMCD_RMV_SIZE_SHIFT;
38229 + }
38230 + else
38231 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38232 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38233 + {
38234 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38235 + {
38236 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38237 + {
38238 + uint8_t hmcdOpt;
38239 +
38240 + /* initialize HMCD */
38241 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38242 +
38243 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38244 + {
38245 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38246 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38247 + break;
38248 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38249 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38250 + break;
38251 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38252 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38253 + break;
38254 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38255 + hmcdOpt = HMCD_RMV_L2_MPLS;
38256 + break;
38257 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38258 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38259 + break;
38260 + default:
38261 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38262 + }
38263 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38264 + break;
38265 + }
38266 +#if (DPAA_VERSION >= 11)
38267 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38268 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38269 + << HMCD_OC_SHIFT;
38270 + break;
38271 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38272 + {
38273 + uint8_t prsArrayOffset;
38274 + t_Error err = E_OK;
38275 +
38276 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38277 + << HMCD_OC_SHIFT;
38278 +
38279 + err =
38280 + GetPrOffsetByHeaderOrField(
38281 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38282 + &prsArrayOffset);
38283 + ASSERT_COND(!err);
38284 + /* was previously checked */
38285 +
38286 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38287 + }
38288 + break;
38289 +#endif /* (DPAA_VERSION >= 11) */
38290 + default:
38291 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38292 + ("manip header remove by hdr type!"));
38293 + }
38294 + }
38295 +
38296 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38297 + /* save a pointer to the "last" indication word */
38298 + p_Last = p_TmpHmct;
38299 + /* advance to next command */
38300 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38301 + }
38302 +
38303 + if (p_FmPcdManipParams->u.hdr.insrt)
38304 + {
38305 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38306 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38307 + {
38308 + /* initialize HMCD */
38309 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38310 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38311 + << HMCD_OC_SHIFT;
38312 + else
38313 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38314 +
38315 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38316 + << HMCD_INSRT_OFFSET_SHIFT;
38317 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38318 + << HMCD_INSRT_SIZE_SHIFT;
38319 +
38320 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38321 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38322 +
38323 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38324 + /* save a pointer to the "last" indication word */
38325 + p_Last = p_TmpHmct;
38326 +
38327 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38328 +
38329 + /* initialize data to be inserted */
38330 + /* if size is not a multiple of 4, padd with 0's */
38331 + origSize = size;
38332 + remain = (uint8_t)(size % 4);
38333 + if (remain)
38334 + {
38335 + size += (uint8_t)(4 - remain);
38336 + p_LocalData = (uint32_t *)XX_Malloc(size);
38337 + memset((uint8_t *)p_LocalData, 0, size);
38338 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38339 + }
38340 + else
38341 + p_LocalData = (uint32_t*)p_UsrData;
38342 +
38343 + /* initialize data and advance pointer to next command */
38344 + MemCpy8(p_TmpHmct, p_LocalData, size);
38345 + p_TmpHmct += size / sizeof(uint32_t);
38346 +
38347 + if (remain)
38348 + XX_Free(p_LocalData);
38349 + }
38350 +
38351 + else
38352 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38353 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38354 + {
38355 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38356 + {
38357 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38358 + {
38359 + uint8_t hmcdOpt;
38360 +
38361 + /* initialize HMCD */
38362 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38363 + << HMCD_OC_SHIFT;
38364 +
38365 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38366 + {
38367 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38368 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38369 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38370 + else
38371 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38372 + break;
38373 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38374 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38375 + break;
38376 + default:
38377 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38378 + }
38379 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38380 +
38381 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38382 + /* save a pointer to the "last" indication word */
38383 + p_Last = p_TmpHmct;
38384 +
38385 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38386 +
38387 + /* set size and pointer of user's data */
38388 + size =
38389 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38390 +
38391 + ASSERT_COND(p_TmpData);
38392 + MemCpy8(
38393 + p_TmpData,
38394 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38395 + size);
38396 + tmpReg =
38397 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38398 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38399 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38400 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38401 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38402 + p_TmpData += size;
38403 + }
38404 + break;
38405 +#if (DPAA_VERSION >= 11)
38406 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38407 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38408 + << HMCD_OC_SHIFT;
38409 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38410 + tmpReg |= HMCD_IP_L4_CS_CALC;
38411 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38412 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38413 + tmpReg |= HMCD_IP_OR_QOS;
38414 + tmpReg |=
38415 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38416 + & HMCD_IP_LAST_PID_MASK;
38417 + tmpReg |=
38418 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38419 + << HMCD_IP_SIZE_SHIFT)
38420 + & HMCD_IP_SIZE_MASK);
38421 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38422 + tmpReg |= HMCD_IP_DF_MODE;
38423 +
38424 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38425 +
38426 + /* save a pointer to the "last" indication word */
38427 + p_Last = p_TmpHmct;
38428 +
38429 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38430 +
38431 + /* set IP id */
38432 + ASSERT_COND(p_TmpData);
38433 + WRITE_UINT16(
38434 + *(uint16_t*)p_TmpData,
38435 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38436 + WRITE_UINT32(
38437 + *p_TmpHmct,
38438 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38439 + p_TmpData += 2;
38440 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38441 +
38442 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38443 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38444 +
38445 + MemCpy8(
38446 + p_TmpHmct,
38447 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38448 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38449 + p_TmpHmct +=
38450 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38451 + / 4;
38452 + break;
38453 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38454 + tmpReg = HMCD_INSRT_UDP_LITE;
38455 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38456 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38457 + << HMCD_OC_SHIFT;
38458 +
38459 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38460 +
38461 + /* save a pointer to the "last" indication word */
38462 + p_Last = p_TmpHmct;
38463 +
38464 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38465 +
38466 + MemCpy8(
38467 + p_TmpHmct,
38468 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38469 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38470 + p_TmpHmct +=
38471 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38472 + / 4;
38473 + break;
38474 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38475 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38476 + << HMCD_OC_SHIFT;
38477 + tmpReg |= HMCD_CAPWAP_INSRT;
38478 +
38479 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38480 +
38481 + /* save a pointer to the "last" indication word */
38482 + p_Last = p_TmpHmct;
38483 +
38484 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38485 +
38486 + MemCpy8(
38487 + p_TmpHmct,
38488 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38489 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38490 + p_TmpHmct +=
38491 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38492 + / 4;
38493 + break;
38494 +#endif /* (DPAA_VERSION >= 11) */
38495 + default:
38496 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38497 + ("manip header insert by header type!"));
38498 +
38499 + }
38500 + }
38501 + }
38502 +
38503 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38504 + {
38505 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38506 + {
38507 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38508 + /* set opcode */
38509 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38510 + << HMCD_OC_SHIFT;
38511 +
38512 + /* set mode & table pointer */
38513 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38514 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38515 + {
38516 + /* set Mode */
38517 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38518 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38519 + /* set VPRI default */
38520 + tmpReg |=
38521 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38522 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38523 + /* save a pointer to the "last" indication word */
38524 + p_Last = p_TmpHmct;
38525 + /* write the table pointer into the Manip descriptor */
38526 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38527 +
38528 + tmpReg = 0;
38529 + ASSERT_COND(p_TmpData);
38530 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38531 + {
38532 + /* first we build from each 8 values a 32bit register */
38533 + tmpReg |=
38534 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38535 + << (32 - 4 * (j + 1));
38536 + j++;
38537 + /* Than we write this register to the next table word
38538 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38539 + if ((i % 8) == 7)
38540 + {
38541 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38542 + tmpReg);
38543 + tmpReg = 0;
38544 + j = 0;
38545 + }
38546 + }
38547 +
38548 + WRITE_UINT32(
38549 + *p_TmpHmct,
38550 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38551 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38552 +
38553 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38554 + }
38555 + else
38556 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38557 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38558 + {
38559 + /* set Mode */
38560 + /* line commented out as it has no-side-effect ('0' value). */
38561 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38562 + /* set VPRI parameter */
38563 + tmpReg |=
38564 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38565 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38566 + /* save a pointer to the "last" indication word */
38567 + p_Last = p_TmpHmct;
38568 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38569 + }
38570 + break;
38571 +
38572 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38573 + /* set opcode */
38574 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38575 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38576 + & HDR_MANIP_IPV4_TTL)
38577 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38578 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38579 + & HDR_MANIP_IPV4_TOS)
38580 + {
38581 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38582 + tmpReg |=
38583 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38584 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38585 + }
38586 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38587 + & HDR_MANIP_IPV4_ID)
38588 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38589 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38590 + & HDR_MANIP_IPV4_SRC)
38591 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38592 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38593 + & HDR_MANIP_IPV4_DST)
38594 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38595 + /* write the first 4 bytes of the descriptor */
38596 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38597 + /* save a pointer to the "last" indication word */
38598 + p_Last = p_TmpHmct;
38599 +
38600 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38601 +
38602 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38603 + & HDR_MANIP_IPV4_ID)
38604 + {
38605 + ASSERT_COND(p_TmpData);
38606 + WRITE_UINT16(
38607 + *(uint16_t*)p_TmpData,
38608 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38609 + WRITE_UINT32(
38610 + *p_TmpHmct,
38611 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38612 + p_TmpData += 2;
38613 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38614 + }
38615 +
38616 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38617 + & HDR_MANIP_IPV4_SRC)
38618 + {
38619 + WRITE_UINT32(
38620 + *p_TmpHmct,
38621 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38622 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38623 + }
38624 +
38625 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38626 + & HDR_MANIP_IPV4_DST)
38627 + {
38628 + WRITE_UINT32(
38629 + *p_TmpHmct,
38630 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38631 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38632 + }
38633 + break;
38634 +
38635 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38636 + /* set opcode */
38637 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38638 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38639 + & HDR_MANIP_IPV6_HL)
38640 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38641 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38642 + & HDR_MANIP_IPV6_TC)
38643 + {
38644 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38645 + tmpReg |=
38646 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38647 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38648 + }
38649 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38650 + & HDR_MANIP_IPV6_SRC)
38651 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38652 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38653 + & HDR_MANIP_IPV6_DST)
38654 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38655 + /* write the first 4 bytes of the descriptor */
38656 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38657 + /* save a pointer to the "last" indication word */
38658 + p_Last = p_TmpHmct;
38659 +
38660 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38661 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38662 + & HDR_MANIP_IPV6_SRC)
38663 + {
38664 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38665 + {
38666 + memcpy(&tmp_ipv6_addr,
38667 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38668 + sizeof(uint32_t));
38669 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38670 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38671 + }
38672 + }
38673 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38674 + & HDR_MANIP_IPV6_DST)
38675 + {
38676 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38677 + {
38678 + memcpy(&tmp_ipv6_addr,
38679 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38680 + sizeof(uint32_t));
38681 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38682 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38683 + }
38684 + }
38685 + break;
38686 +
38687 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38688 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38689 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38690 + {
38691 + /* we implement this case with the update-checksum descriptor */
38692 + /* set opcode */
38693 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38694 + << HMCD_OC_SHIFT;
38695 + /* write the first 4 bytes of the descriptor */
38696 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38697 + /* save a pointer to the "last" indication word */
38698 + p_Last = p_TmpHmct;
38699 +
38700 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38701 + }
38702 + else
38703 + {
38704 + /* we implement this case with the TCP/UDP update descriptor */
38705 + /* set opcode */
38706 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38707 + << HMCD_OC_SHIFT;
38708 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38709 + & HDR_MANIP_TCP_UDP_DST)
38710 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38711 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38712 + & HDR_MANIP_TCP_UDP_SRC)
38713 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38714 + /* write the first 4 bytes of the descriptor */
38715 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38716 + /* save a pointer to the "last" indication word */
38717 + p_Last = p_TmpHmct;
38718 +
38719 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38720 +
38721 + tmpReg = 0;
38722 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38723 + & HDR_MANIP_TCP_UDP_SRC)
38724 + tmpReg |=
38725 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38726 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38727 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38728 + & HDR_MANIP_TCP_UDP_DST)
38729 + tmpReg |=
38730 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38731 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38732 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38733 + }
38734 + break;
38735 +
38736 + default:
38737 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38738 + ("Unknown fieldUpdateParams.type"));
38739 + }
38740 + }
38741 +
38742 + if (p_FmPcdManipParams->u.hdr.custom)
38743 + {
38744 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38745 + {
38746 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38747 + /* set opcode */
38748 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38749 +
38750 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38751 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38752 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38753 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38754 + /* line commented out as it has no-side-effect ('0' value). */
38755 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38756 + else
38757 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38758 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38759 + {
38760 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38761 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38762 + tmpReg |= HMCD_IP_REPLACE_ID;
38763 + }
38764 + else
38765 + RETURN_ERROR(
38766 + MINOR,
38767 + E_NOT_SUPPORTED,
38768 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38769 +
38770 + /* write the first 4 bytes of the descriptor */
38771 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38772 + /* save a pointer to the "last" indication word */
38773 + p_Last = p_TmpHmct;
38774 +
38775 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38776 +
38777 + size =
38778 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38779 + ASSERT_COND(p_TmpData);
38780 + MemCpy8(
38781 + p_TmpData,
38782 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38783 + size);
38784 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38785 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38786 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38787 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38788 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38789 + p_TmpData += size;
38790 +
38791 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38792 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38793 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38794 + {
38795 + WRITE_UINT16(
38796 + *(uint16_t*)p_TmpData,
38797 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38798 + WRITE_UINT32(
38799 + *p_TmpHmct,
38800 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38801 + p_TmpData += 2;
38802 + }
38803 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38804 + break;
38805 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38806 + /* set opcode */
38807 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38808 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38809 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38810 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38811 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38812 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38813 +
38814 + /* write the first 4 bytes of the descriptor */
38815 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38816 + /* save a pointer to the "last" indication word */
38817 + p_Last = p_TmpHmct;
38818 +
38819 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38820 +
38821 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38822 + {
38823 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38824 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38825 + /* write the next 4 bytes of the descriptor */
38826 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38827 + }
38828 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38829 + break;
38830 + default:
38831 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38832 + ("Unknown customParams.type"));
38833 + }
38834 + }
38835 +
38836 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38837 + the old table and should be freed */
38838 + if (p_FmPcdManipParams->h_NextManip
38839 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38840 + && (MANIP_DONT_REPARSE(p_Manip)))
38841 + {
38842 + if (new)
38843 + {
38844 + /* If this is the first time this manip is created we need to free unused memory. If it
38845 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
38846 + * table - no allocation, no free */
38847 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
38848 +
38849 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
38850 + }
38851 + }
38852 + else
38853 + {
38854 + ASSERT_COND(p_Last);
38855 + /* set the "last" indication on the last command of the current table */
38856 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
38857 + }
38858 +
38859 + return E_OK;
38860 +}
38861 +
38862 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
38863 + t_FmPcdManipParams *p_FmPcdManipParams)
38864 +{
38865 + t_FmPcdManip *p_CurManip;
38866 + t_Error err;
38867 + uint32_t nextSize = 0, totalSize;
38868 + uint16_t tmpReg;
38869 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
38870 +
38871 + /* set Manip structure */
38872 +
38873 + p_Manip->dontParseAfterManip =
38874 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
38875 +
38876 + if (p_FmPcdManipParams->h_NextManip)
38877 + { /* Next Header manipulation exists */
38878 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
38879 +
38880 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
38881 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
38882 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
38883 + else /* either parsing is required or next manip is Frag; no table merging. */
38884 + p_Manip->cascaded = TRUE;
38885 + /* pass up the "cascaded" attribute. The whole chain is cascaded
38886 + * if something is cascaded along the way. */
38887 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
38888 + p_Manip->cascaded = TRUE;
38889 + }
38890 +
38891 + /* Allocate new table */
38892 + /* calculate table size according to manip parameters */
38893 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
38894 + &p_Manip->dataSize);
38895 + if (err)
38896 + RETURN_ERROR(MINOR, err, NO_MSG);
38897 +
38898 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
38899 +
38900 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
38901 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
38902 + if (!p_Manip->p_Hmct)
38903 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
38904 +
38905 + if (p_Manip->dataSize)
38906 + p_Manip->p_Data =
38907 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
38908 +
38909 + /* update shadow size to allow runtime replacement of Header manipulation */
38910 + /* The allocated shadow is divided as follows:
38911 + 0 . . . 16 . . .
38912 + --------------------------------
38913 + | Shadow | Shadow HMTD |
38914 + | HMTD | Match Table |
38915 + | (16 bytes) | (maximal size) |
38916 + --------------------------------
38917 + */
38918 +
38919 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
38920 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
38921 + if (err != E_OK)
38922 + {
38923 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38924 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
38925 + ("MURAM allocation for HdrManip node shadow"));
38926 + }
38927 +
38928 + if (p_FmPcdManipParams->h_NextManip
38929 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38930 + && (MANIP_DONT_REPARSE(p_Manip)))
38931 + {
38932 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
38933 + e_MANIP_HMCT);
38934 + p_CurManip = p_FmPcdManipParams->h_NextManip;
38935 + /* Run till the last Manip (which is the first to configure) */
38936 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38937 + p_CurManip = p_CurManip->h_NextManip;
38938 +
38939 + while (p_CurManip)
38940 + {
38941 + /* If this is a unified table, point to the part of the table
38942 + * which is the relative offset in HMCT.
38943 + */
38944 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38945 + (p_Manip->tableSize +
38946 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
38947 + PTR_TO_UINT(p_OldHmct))));
38948 + if (p_CurManip->p_Data)
38949 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38950 + (p_Manip->tableSize +
38951 + (PTR_TO_UINT(p_CurManip->p_Data) -
38952 + PTR_TO_UINT(p_OldHmct))));
38953 + else
38954 + p_TmpDataPtr = NULL;
38955 +
38956 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38957 + p_TmpDataPtr, FALSE);
38958 + /* update old manip table pointer */
38959 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
38960 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
38961 +
38962 + p_CurManip = p_CurManip->h_PrevManip;
38963 + }
38964 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
38965 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
38966 + p_OldHmct);
38967 + }
38968 +
38969 + /* Fill table */
38970 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
38971 + p_Manip->p_Data, TRUE);
38972 + if (err)
38973 + {
38974 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38975 + RETURN_ERROR(MINOR, err, NO_MSG);
38976 + }
38977 +
38978 + /* Build HMTD (table descriptor) */
38979 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
38980 +
38981 + /* add parseAfterManip */
38982 + if (!p_Manip->dontParseAfterManip)
38983 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
38984 +
38985 + /* create cascade */
38986 + /*if (p_FmPcdManipParams->h_NextManip
38987 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
38988 + if (p_Manip->cascaded)
38989 + {
38990 + uint16_t nextAd;
38991 + /* indicate that there's another HM table descriptor */
38992 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
38993 + /* get address of next HMTD (table descriptor; h_Ad).
38994 + * If the next HMTD was removed due to table unifing, get the address
38995 + * of the "next next" as written in the h_Ad of the next h_Manip node.
38996 + */
38997 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
38998 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
38999 + else
39000 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
39001 +
39002 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
39003 + }
39004 +
39005 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
39006 + WRITE_UINT32(
39007 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
39008 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
39009 +
39010 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
39011 +
39012 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
39013 + {
39014 + /* The HMTD of the next Manip is never going to be used */
39015 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
39016 + FM_MURAM_FreeMem(
39017 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
39018 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39019 + else
39020 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39021 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
39022 + }
39023 +
39024 + return E_OK;
39025 +}
39026 +
39027 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
39028 + t_FmPcdManipParams *p_FmPcdManipParams)
39029 +{
39030 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
39031 + uint16_t newSize;
39032 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39033 + t_Error err;
39034 + t_FmPcdManip *p_CurManip = p_Manip;
39035 +
39036 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
39037 + if (err)
39038 + RETURN_ERROR(MINOR, err, NO_MSG);
39039 +
39040 + /* check coherency of new table parameters */
39041 + if (newSize > p_Manip->tableSize)
39042 + RETURN_ERROR(
39043 + MINOR,
39044 + E_INVALID_VALUE,
39045 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
39046 + if (newDataSize > p_Manip->dataSize)
39047 + RETURN_ERROR(
39048 + MINOR,
39049 + E_INVALID_VALUE,
39050 + ("New Hdr Manip configuration requires larger size than current one (data)."));
39051 + if (p_FmPcdManipParams->h_NextManip)
39052 + RETURN_ERROR(
39053 + MINOR, E_INVALID_VALUE,
39054 + ("New Hdr Manip configuration can not contain h_NextManip."));
39055 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
39056 + RETURN_ERROR(
39057 + MINOR,
39058 + E_INVALID_VALUE,
39059 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
39060 + if (p_Manip->dontParseAfterManip
39061 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
39062 + RETURN_ERROR(
39063 + MINOR,
39064 + E_INVALID_VALUE,
39065 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
39066 +
39067 + p_Manip->tableSize = newSize;
39068 + p_Manip->dataSize = newDataSize;
39069 +
39070 + /* Build the new table in the shadow */
39071 + if (!MANIP_IS_UNIFIED(p_Manip))
39072 + {
39073 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
39074 + if (p_Manip->p_Data)
39075 + p_TmpDataPtr =
39076 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
39077 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
39078 +
39079 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
39080 + FALSE);
39081 + }
39082 + else
39083 + {
39084 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39085 + ASSERT_COND(p_WholeHmct);
39086 +
39087 + /* Run till the last Manip (which is the first to configure) */
39088 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39089 + p_CurManip = p_CurManip->h_NextManip;
39090 +
39091 + while (p_CurManip)
39092 + {
39093 + /* If this is a non-head node in a unified table, point to the part of the shadow
39094 + * which is the relative offset in HMCT.
39095 + * else, point to the beginning of the
39096 + * shadow table (we save 16 for the HMTD.
39097 + */
39098 + p_TmpHmctPtr =
39099 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39100 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
39101 + if (p_CurManip->p_Data)
39102 + p_TmpDataPtr =
39103 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39104 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
39105 +
39106 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39107 + p_TmpDataPtr, FALSE);
39108 + p_CurManip = p_CurManip->h_PrevManip;
39109 + }
39110 + }
39111 +
39112 + return E_OK;
39113 +}
39114 +
39115 +static t_Error CreateManipActionBackToOrig(
39116 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
39117 +{
39118 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
39119 + t_FmPcdManip *p_CurManip = p_Manip;
39120 +
39121 + /* Build the new table in the shadow */
39122 + if (!MANIP_IS_UNIFIED(p_Manip))
39123 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
39124 + FALSE);
39125 + else
39126 + {
39127 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39128 + ASSERT_COND(p_WholeHmct);
39129 +
39130 + /* Run till the last Manip (which is the first to configure) */
39131 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39132 + p_CurManip = p_CurManip->h_NextManip;
39133 +
39134 + while (p_CurManip)
39135 + {
39136 + /* If this is a unified table, point to the part of the table
39137 + * which is the relative offset in HMCT.
39138 + */
39139 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
39140 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
39141 +
39142 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39143 + p_TmpDataPtr, FALSE);
39144 +
39145 + p_CurManip = p_CurManip->h_PrevManip;
39146 + }
39147 + }
39148 +
39149 + return E_OK;
39150 +}
39151 +
39152 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
39153 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
39154 +{
39155 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
39156 + t_Handle p_Ad;
39157 + uint32_t tmpReg32 = 0;
39158 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
39159 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
39160 +
39161 + switch (p_Manip->opcode)
39162 + {
39163 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
39164 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39165 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39166 + {
39167 + tmpReg32 =
39168 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
39169 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39170 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
39171 + tmpReg32;
39172 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39173 + p_Manip->icOffset = icOffset;
39174 + }
39175 + else
39176 + {
39177 + if (p_Manip->icOffset != icOffset)
39178 + RETURN_ERROR(
39179 + MAJOR,
39180 + E_INVALID_VALUE,
39181 + ("this manipulation was updated previously by different value"););
39182 + }
39183 + break;
39184 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
39185 + if (p_Manip->h_Frag)
39186 + {
39187 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39188 + {
39189 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39190 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
39191 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39192 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
39193 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39194 + p_Manip->icOffset = icOffset;
39195 + }
39196 + else
39197 + {
39198 + if (p_Manip->icOffset != icOffset)
39199 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
39200 + }
39201 + }
39202 + break;
39203 + }
39204 +
39205 + return E_OK;
39206 +}
39207 +
39208 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39209 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39210 +{
39211 +
39212 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39213 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39214 + t_Error err;
39215 + uint32_t tmpReg32;
39216 +
39217 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39218 +
39219 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39220 + SANITY_CHECK_RETURN_ERROR(
39221 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39222 + E_INVALID_STATE);
39223 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39224 +
39225 + if (p_Manip->updateParams)
39226 + {
39227 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39228 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39229 + RETURN_ERROR(
39230 + MAJOR, E_INVALID_STATE,
39231 + ("in this stage parameters from Port has not be updated"));
39232 +
39233 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39234 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39235 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39236 +
39237 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39238 + if (err)
39239 + RETURN_ERROR(MAJOR, err, NO_MSG);
39240 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39241 + RETURN_ERROR(
39242 + MAJOR, E_INVALID_STATE,
39243 + ("Parser result offset wasn't configured previousely"));
39244 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39245 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39246 +#endif
39247 + }
39248 + else
39249 + if (validate)
39250 + {
39251 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39252 + || (p_Manip->updateParams & OFFSET_OF_PR))
39253 + RETURN_ERROR(
39254 + MAJOR, E_INVALID_STATE,
39255 + ("in this stage parameters from Port has be updated"));
39256 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39257 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39258 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39259 +
39260 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39261 + if (err)
39262 + RETURN_ERROR(MAJOR, err, NO_MSG);
39263 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39264 + RETURN_ERROR(
39265 + MAJOR, E_INVALID_STATE,
39266 + ("Parser result offset wasn't configured previousely"));
39267 +
39268 + }
39269 +
39270 + ASSERT_COND(p_Ad);
39271 +
39272 + if (p_Manip->updateParams & OFFSET_OF_PR)
39273 + {
39274 + tmpReg32 = 0;
39275 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39276 + WRITE_UINT32(p_Ad->matchTblPtr,
39277 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39278 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39279 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39280 + }
39281 + else
39282 + if (validate)
39283 + {
39284 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39285 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39286 + RETURN_ERROR(
39287 + MAJOR,
39288 + E_INVALID_STATE,
39289 + ("this manipulation was updated previousely by different value"););
39290 + }
39291 +
39292 + return E_OK;
39293 +}
39294 +
39295 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39296 +{
39297 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39298 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39299 + uint32_t tmpReg32 = 0;
39300 +
39301 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39302 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39303 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39304 + 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);
39305 +
39306 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39307 +
39308 + if (p_Manip->updateParams)
39309 + {
39310 +
39311 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39312 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39313 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39314 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39315 + if (!p_SavedManipParams)
39316 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39317 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39318 +
39319 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39320 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39321 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39322 +
39323 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39324 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39325 + }
39326 + else if (validate)
39327 + {
39328 +
39329 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39330 + if (!p_SavedManipParams)
39331 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39332 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39333 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39334 + }
39335 +
39336 + return E_OK;
39337 +}
39338 +
39339 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39340 + t_FmPcdManip *p_Manip,
39341 + t_Handle h_Ad,
39342 + bool validate,
39343 + t_Handle h_FmTree)
39344 +{
39345 + t_AdOfTypeContLookup *p_Ad;
39346 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39347 + t_Error err;
39348 + uint32_t tmpReg32 = 0;
39349 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39350 +
39351 + UNUSED(h_Ad);
39352 +
39353 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39354 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39355 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39356 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39357 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39358 +
39359 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39360 +
39361 + if (p_Manip->updateParams)
39362 + {
39363 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39364 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39365 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39366 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39367 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39368 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39369 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39370 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39371 +
39372 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39373 + if (err)
39374 + RETURN_ERROR(MAJOR, err, NO_MSG);
39375 +
39376 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39377 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39378 +
39379 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39380 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39381 +
39382 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39383 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39384 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39385 +
39386 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39387 + }
39388 + else if (validate)
39389 + {
39390 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39391 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39392 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39393 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39394 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39395 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39396 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39397 + if (err)
39398 + RETURN_ERROR(MAJOR, err, NO_MSG);
39399 +
39400 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39401 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39402 + }
39403 +
39404 + if (p_Manip->updateParams)
39405 + {
39406 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39407 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39408 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39409 +
39410 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39411 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39412 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39413 + }
39414 + else if (validate)
39415 + {
39416 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39417 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39418 + }
39419 +
39420 + return E_OK;
39421 +}
39422 +
39423 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39424 + t_Handle h_FmPort,
39425 + t_FmPcdManip *p_Manip,
39426 + t_Handle h_Ad,
39427 + bool validate)
39428 +{
39429 + t_CapwapReasmPram *p_ReassmTbl;
39430 + t_Error err;
39431 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39432 + uint8_t i = 0;
39433 + uint16_t size;
39434 + uint32_t tmpReg32;
39435 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39436 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39437 +
39438 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39439 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39440 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39441 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39442 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39443 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39444 +
39445 + if (p_Manip->h_FmPcd != h_FmPcd)
39446 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39447 + ("handler of PCD previously was initiated by different value"));
39448 +
39449 + UNUSED(h_Ad);
39450 +
39451 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39452 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39453 +
39454 + if (p_Manip->updateParams)
39455 + {
39456 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39457 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39458 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39459 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39460 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39461 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39462 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39463 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39464 +
39465 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39466 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39467 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39468 +
39469 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39470 + if (err)
39471 + RETURN_ERROR(MAJOR, err, NO_MSG);
39472 +
39473 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39474 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39475 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39476 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39477 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39478 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39479 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39480 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39481 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39482 + }
39483 + else if (validate)
39484 + {
39485 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39486 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39487 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39488 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39489 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39490 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39491 + (p_Manip->updateParams & HW_PORT_ID)))
39492 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39493 +
39494 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39495 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39496 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39497 +
39498 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39499 + if (err)
39500 + RETURN_ERROR(MAJOR, err, NO_MSG);
39501 +
39502 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39503 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39504 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39505 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39506 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39507 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39508 + }
39509 +
39510 + if (p_Manip->updateParams)
39511 + {
39512 + if (p_Manip->updateParams & NUM_OF_TASKS)
39513 + {
39514 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39515 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39516 + if (size > 255)
39517 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39518 +
39519 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39520 +
39521 + /*p_ReassmFrmDescrIndxPoolTbl*/
39522 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39523 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39524 + (uint32_t)(size + 1),
39525 + 4);
39526 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39527 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39528 +
39529 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39530 +
39531 + for ( i = 0; i < size; i++)
39532 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39533 +
39534 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39535 +
39536 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39537 +
39538 + /*p_ReassmFrmDescrPoolTbl*/
39539 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39540 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39541 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39542 + 4);
39543 +
39544 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39545 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39546 +
39547 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39548 +
39549 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39550 +
39551 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39552 +
39553 + /*p_TimeOutTbl*/
39554 +
39555 + p_Manip->capwapFragParams.p_TimeOutTbl =
39556 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39557 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39558 + 4);
39559 +
39560 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39561 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39562 +
39563 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39564 +
39565 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39566 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39567 +
39568 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39569 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39570 + }
39571 +
39572 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39573 + {
39574 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39575 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39576 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39577 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39578 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39579 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39580 + }
39581 +
39582 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39583 + {
39584 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39585 +
39586 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39587 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39588 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39589 +
39590 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39591 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39592 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39593 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39594 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39595 + }
39596 + else
39597 + {
39598 + p_Manip->capwapFragParams.prOffset = 0xff;
39599 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39600 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39601 + }
39602 +
39603 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39604 + p_Manip->updateParams &= ~HW_PORT_ID;
39605 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39606 +
39607 + /*timeout hc */
39608 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39609 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39610 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39611 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39612 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39613 + }
39614 +
39615 + else if (validate)
39616 + {
39617 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39618 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39619 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39620 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39621 +
39622 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39623 + {
39624 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39625 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39626 + }
39627 + else
39628 + {
39629 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39630 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39631 + }
39632 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39633 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39634 + }
39635 +
39636 + return E_OK;
39637 +}
39638 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39639 +
39640 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39641 +{
39642 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39643 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39644 + t_Error err = E_OK;
39645 + uint8_t result;
39646 + uint32_t bitFor1Micro, tsbs, log2num;
39647 +
39648 + ASSERT_COND(p_FmPcd);
39649 + ASSERT_COND(h_ReasmCommonPramTbl);
39650 +
39651 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39652 + if (bitFor1Micro == 0)
39653 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39654 +
39655 + bitFor1Micro = 32 - bitFor1Micro;
39656 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39657 + tsbs = bitFor1Micro - log2num;
39658 +
39659 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39660 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39661 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39662 + ccReassmTimeoutParams.activate = TRUE;
39663 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39664 + &result)) != E_OK)
39665 + RETURN_ERROR(MAJOR, err, NO_MSG);
39666 +
39667 + switch (result)
39668 + {
39669 + case (0):
39670 + return E_OK;
39671 + case (1):
39672 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39673 + case (2):
39674 + RETURN_ERROR(
39675 + MAJOR, E_NO_MEMORY,
39676 + ("failed to allocate internal buffer from the HC-Port"));
39677 + case (3):
39678 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39679 + ("'Disable Timeout Task' with invalid IPRCPT"));
39680 + case (4):
39681 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39682 + case (5):
39683 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39684 + default:
39685 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39686 + }
39687 + return E_OK;
39688 +}
39689 +
39690 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39691 +{
39692 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39693 + uint64_t tmpReg64, size;
39694 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39695 + t_Error err = E_OK;
39696 +
39697 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39698 + if (bitFor1Micro == 0)
39699 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39700 +
39701 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39702 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39703 + p_Manip->reassmParams.p_ReassCommonTbl =
39704 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39705 + p_FmPcd->h_FmMuram,
39706 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39707 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39708 +
39709 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39710 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39711 + ("MURAM alloc for Reassembly common parameters table"));
39712 +
39713 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39714 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39715 +
39716 + /* Setting the TimeOut Mode.*/
39717 + tmpReg32 = 0;
39718 + if (p_Manip->reassmParams.timeOutMode
39719 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39720 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39721 +
39722 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39723 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39724 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39725 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39726 + tmpReg32);
39727 +
39728 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39729 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39730 +
39731 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39732 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39733 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39734 + (uint32_t)(size * 2),
39735 + 256));
39736 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39737 + RETURN_ERROR(
39738 + MAJOR, E_NO_MEMORY,
39739 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39740 +
39741 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39742 + 0, (uint32_t)(size * 2));
39743 +
39744 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39745 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39746 + The last entry in this pool must contain the index zero*/
39747 + for (i = 0; i < (size - 1); i++)
39748 + WRITE_UINT16(
39749 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39750 + (uint16_t)(i+1));
39751 +
39752 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39753 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39754 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39755 + - p_FmPcd->physicalMuramBase);
39756 + WRITE_UINT32(
39757 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39758 + tmpReg32);
39759 +
39760 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39761 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39762 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39763 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39764 +
39765 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39766 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39767 +
39768 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39769 + (uint32_t)(size * 64));
39770 +
39771 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39772 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39773 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39774 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39775 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39776 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39777 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39778 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39779 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39780 + WRITE_UINT32(
39781 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39782 + (uint32_t)(tmpReg64 >> 32));
39783 + WRITE_UINT32(
39784 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39785 + (uint32_t)tmpReg64);
39786 +
39787 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39788 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39789 + p_Manip->reassmParams.timeOutTblAddr =
39790 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39791 +
39792 + if (!p_Manip->reassmParams.timeOutTblAddr)
39793 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39794 + ("MURAM alloc for Reassembly timeout table"));
39795 +
39796 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39797 + (uint16_t)(size * 8));
39798 +
39799 + /* Sets the TimeOut table offset from MURAM */
39800 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39801 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39802 + - p_FmPcd->physicalMuramBase);
39803 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39804 + tmpReg32);
39805 +
39806 + /* Sets the Expiration Delay */
39807 + tmpReg32 = 0;
39808 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39809 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39810 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39811 + tmpReg32);
39812 +
39813 + err = FmPcdRegisterReassmPort(p_FmPcd,
39814 + p_Manip->reassmParams.p_ReassCommonTbl);
39815 + if (err != E_OK)
39816 + {
39817 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39818 + p_Manip->reassmParams.p_ReassCommonTbl);
39819 + RETURN_ERROR(MAJOR, err, ("port registration"));
39820 + }
39821 +
39822 + return err;
39823 +}
39824 +
39825 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39826 +{
39827 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39828 + uint32_t tmpReg32, autoLearnHashTblSize;
39829 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39830 + uint32_t waySize, numOfSets, numOfEntries;
39831 + uint64_t tmpReg64;
39832 + uint16_t minFragSize;
39833 + uint16_t maxReassemSize;
39834 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39835 + t_ReassTbl **p_ReassTbl;
39836 +
39837 + switch (hdr)
39838 + {
39839 + case HEADER_TYPE_IPv4:
39840 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39841 + p_AutoLearnHashTblAddr =
39842 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39843 + p_AutoLearnSetLockTblAddr =
39844 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
39845 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
39846 + maxReassemSize = 0;
39847 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
39848 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
39849 + break;
39850 + case HEADER_TYPE_IPv6:
39851 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
39852 + p_AutoLearnHashTblAddr =
39853 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
39854 + p_AutoLearnSetLockTblAddr =
39855 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
39856 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
39857 + maxReassemSize = 0;
39858 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
39859 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
39860 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
39861 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
39862 + break;
39863 + case HEADER_TYPE_CAPWAP:
39864 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
39865 + p_AutoLearnHashTblAddr =
39866 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
39867 + p_AutoLearnSetLockTblAddr =
39868 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
39869 + minFragSize = 0;
39870 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
39871 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
39872 + keySize = 4;
39873 + break;
39874 + default:
39875 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
39876 + }
39877 + keySize += 2; /* 2 bytes reserved for RFDIndex */
39878 +#if (DPAA_VERSION >= 11)
39879 + keySize += 2; /* 2 bytes reserved */
39880 +#endif /* (DPAA_VERSION >= 11) */
39881 + waySize = ROUND_UP(keySize, 8);
39882 +
39883 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
39884 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
39885 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
39886 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
39887 + if (!*p_ReassTbl)
39888 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
39889 + ("MURAM alloc for Reassembly specific parameters table"));
39890 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
39891 +
39892 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
39893 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
39894 + - p_FmPcd->physicalMuramBase);
39895 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
39896 +
39897 + /* Calculate set size (set size is rounded-up to next power of 2) */
39898 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
39899 +
39900 + /* Get set size code */
39901 + LOG2(setSize, setSizeCode);
39902 +
39903 + /* Sets ways number and set size code */
39904 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
39905 + (uint16_t)((numOfWays << 8) | setSizeCode));
39906 +
39907 + /* It is recommended that the total number of entries in this table
39908 + (number of sets * number of ways) will be twice the number of frames that
39909 + are expected to be reassembled simultaneously.*/
39910 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
39911 +
39912 + /* sets number calculation - number of entries = number of sets * number of ways */
39913 + numOfSets = numOfEntries / numOfWays;
39914 +
39915 + /* Sets AutoLearnHashKeyMask*/
39916 + NEXT_POWER_OF_2(numOfSets, numOfSets);
39917 +
39918 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
39919 + (uint16_t)(numOfSets - 1));
39920 +
39921 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
39922 + The size of this table is determined by the number of sets and the set size.
39923 + Table size = set size * number of sets
39924 + This table base address should be aligned to SetSize.*/
39925 + autoLearnHashTblSize = numOfSets * setSize;
39926 +
39927 + *p_AutoLearnHashTblAddr =
39928 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
39929 + if (!*p_AutoLearnHashTblAddr)
39930 + {
39931 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39932 + *p_ReassTbl = NULL;
39933 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39934 + }
39935 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
39936 +
39937 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
39938 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39939 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39940 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39941 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39942 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39943 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39944 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39945 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
39946 + (uint32_t)(tmpReg64 >> 32));
39947 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
39948 +
39949 + /* Allocation of the Set Lock table - This table resides in external memory
39950 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
39951 + This table resides in external memory and its base address should be 4-byte aligned */
39952 + *p_AutoLearnSetLockTblAddr =
39953 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
39954 + if (!*p_AutoLearnSetLockTblAddr)
39955 + {
39956 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39957 + *p_ReassTbl = NULL;
39958 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39959 + *p_AutoLearnHashTblAddr = 0;
39960 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39961 + }
39962 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
39963 +
39964 + /* sets Set Lock table pointer and liodn offset*/
39965 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39966 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39967 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39968 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39969 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39970 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39971 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
39972 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
39973 + (uint32_t)(tmpReg64 >> 32));
39974 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
39975 +
39976 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
39977 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
39978 +
39979 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
39980 +
39981 + return E_OK;
39982 +}
39983 +
39984 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
39985 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
39986 + t_Handle h_Ad, bool validate)
39987 +{
39988 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39989 + uint32_t tmpReg32;
39990 + t_Error err;
39991 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
39992 +#if (DPAA_VERSION >= 11)
39993 + t_FmPcdCtrlParamsPage *p_ParamsPage;
39994 +#endif /* (DPAA_VERSION >= 11) */
39995 +
39996 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39997 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
39998 + SANITY_CHECK_RETURN_ERROR(
39999 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
40000 + E_INVALID_STATE);
40001 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
40002 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
40003 + E_INVALID_HANDLE);
40004 +
40005 + UNUSED(h_Ad);
40006 +
40007 + if (!p_Manip->updateParams)
40008 + return E_OK;
40009 +
40010 + if (p_Manip->h_FmPcd != h_FmPcd)
40011 + RETURN_ERROR(
40012 + MAJOR, E_INVALID_STATE,
40013 + ("handler of PCD previously was initiated by different value"));
40014 +
40015 + if (p_Manip->updateParams)
40016 + {
40017 + if ((!(p_Manip->updateParams
40018 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
40019 + || ((p_Manip->shadowUpdateParams
40020 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
40021 + RETURN_ERROR(
40022 + MAJOR, E_INVALID_STATE,
40023 + ("in this stage parameters from Port has not be updated"));
40024 +
40025 + fmPortGetSetCcParams.setCcParams.type = 0;
40026 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40027 + {
40028 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
40029 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
40030 + }
40031 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
40032 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
40033 + != E_OK)
40034 + RETURN_ERROR(MAJOR, err, NO_MSG);
40035 + if (fmPortGetSetCcParams.getCcParams.type
40036 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
40037 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40038 + ("offset of the data wasn't configured previously"));
40039 + if (p_Manip->updateParams
40040 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
40041 + {
40042 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40043 + uint8_t *p_Ptr, i, totalNumOfTnums;
40044 +
40045 + totalNumOfTnums =
40046 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
40047 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
40048 +
40049 + p_Manip->reassmParams.internalBufferPoolAddr =
40050 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40051 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
40052 + BMI_FIFO_UNITS));
40053 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
40054 + RETURN_ERROR(
40055 + MAJOR, E_NO_MEMORY,
40056 + ("MURAM alloc for Reassembly internal buffers pool"));
40057 + MemSet8(
40058 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
40059 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
40060 +
40061 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
40062 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40063 + (uint32_t)(5 + totalNumOfTnums),
40064 + 4));
40065 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40066 + RETURN_ERROR(
40067 + MAJOR,
40068 + E_NO_MEMORY,
40069 + ("MURAM alloc for Reassembly internal buffers management"));
40070 +
40071 + p_Ptr =
40072 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
40073 + WRITE_UINT32(
40074 + *(uint32_t*)p_Ptr,
40075 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
40076 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
40077 + WRITE_UINT8(*p_Ptr, i);
40078 + WRITE_UINT8(*p_Ptr, 0xFF);
40079 +
40080 + tmpReg32 =
40081 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
40082 + | ((uint32_t)(XX_VirtToPhys(
40083 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
40084 + - p_FmPcd->physicalMuramBase));
40085 + WRITE_UINT32(
40086 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
40087 + tmpReg32);
40088 +
40089 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40090 + | DISCARD_MASK);
40091 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40092 + | DISCARD_MASK);
40093 + }
40094 + }
40095 +
40096 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40097 + {
40098 + if (p_Manip->reassmParams.capwap.h_Scheme)
40099 + {
40100 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40101 + p_Manip->reassmParams.capwap.h_Scheme;
40102 + p_PcdParams->p_KgParams->numOfSchemes++;
40103 + }
40104 +
40105 + }
40106 + else
40107 + {
40108 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40109 + {
40110 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40111 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
40112 + p_PcdParams->p_KgParams->numOfSchemes++;
40113 + }
40114 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40115 + {
40116 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40117 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
40118 + p_PcdParams->p_KgParams->numOfSchemes++;
40119 + }
40120 +#if (DPAA_VERSION >= 11)
40121 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
40122 + {
40123 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
40124 + (void**)&p_ParamsPage)) != E_OK)
40125 + RETURN_ERROR(MAJOR, err, NO_MSG);
40126 +
40127 + tmpReg32 = NIA_ENG_KG;
40128 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40129 + {
40130 + tmpReg32 |= NIA_KG_DIRECT;
40131 + tmpReg32 |= NIA_KG_CC_EN;
40132 + tmpReg32 |= FmPcdKgGetSchemeId(
40133 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
40134 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
40135 + }
40136 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40137 + {
40138 + tmpReg32 &= ~NIA_AC_MASK;
40139 + tmpReg32 |= NIA_KG_DIRECT;
40140 + tmpReg32 |= NIA_KG_CC_EN;
40141 + tmpReg32 |= FmPcdKgGetSchemeId(
40142 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
40143 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
40144 + }
40145 + }
40146 +#else
40147 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
40148 + {
40149 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
40150 + fmPortGetSetCcParams.getCcParams.discardMask);
40151 + }
40152 +#endif /* (DPAA_VERSION >= 11) */
40153 + }
40154 + return E_OK;
40155 +}
40156 +
40157 +#if (DPAA_VERSION == 10)
40158 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
40159 +{
40160 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40161 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40162 + t_Error err;
40163 +
40164 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40165 +
40166 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40167 +
40168 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
40169 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40170 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40171 + RETURN_ERROR(MAJOR, err, NO_MSG);
40172 +
40173 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
40174 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
40175 + "Failed to release %d buffers to the BM (missing FBPRs)",
40176 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
40177 +
40178 + return E_OK;
40179 +}
40180 +
40181 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
40182 +{
40183 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40184 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40185 + t_Error err;
40186 +
40187 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40188 +
40189 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40190 +
40191 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40192 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40193 + RETURN_ERROR(MAJOR, err, NO_MSG);
40194 +
40195 + return E_OK;
40196 +}
40197 +#endif /* (DPAA_VERSION == 10) */
40198 +
40199 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40200 +{
40201 + if (p_Manip->h_Ad)
40202 + {
40203 + if (p_Manip->muramAllocate)
40204 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40205 + else
40206 + XX_Free(p_Manip->h_Ad);
40207 + p_Manip->h_Ad = NULL;
40208 + }
40209 + if (p_Manip->p_Template)
40210 + {
40211 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40212 + p_Manip->p_Template = NULL;
40213 + }
40214 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40215 + if (p_Manip->h_Frag)
40216 + {
40217 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40218 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40219 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40220 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40221 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40222 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40223 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40224 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40225 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40226 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40227 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40228 + p_Manip->capwapFragParams.p_TimeOutTbl);
40229 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40230 +
40231 + }
40232 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40233 + if (p_Manip->frag)
40234 + {
40235 + if (p_Manip->fragParams.p_Frag)
40236 + {
40237 +#if (DPAA_VERSION == 10)
40238 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40239 +#endif /* (DPAA_VERSION == 10) */
40240 +
40241 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40242 + }
40243 + }
40244 + else
40245 + if (p_Manip->reassm)
40246 + {
40247 + FmPcdUnregisterReassmPort(p_FmPcd,
40248 + p_Manip->reassmParams.p_ReassCommonTbl);
40249 +
40250 + if (p_Manip->reassmParams.timeOutTblAddr)
40251 + FM_MURAM_FreeMem(
40252 + p_FmPcd->h_FmMuram,
40253 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40254 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40255 + XX_FreeSmart(
40256 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40257 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40258 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40259 + p_Manip->reassmParams.p_ReassCommonTbl);
40260 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40261 + FM_MURAM_FreeMem(
40262 + p_FmPcd->h_FmMuram,
40263 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40264 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40265 + FM_MURAM_FreeMem(
40266 + p_FmPcd->h_FmMuram,
40267 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40268 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40269 + FM_MURAM_FreeMem(
40270 + p_FmPcd->h_FmMuram,
40271 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40272 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40273 + {
40274 +
40275 + }
40276 + else
40277 + {
40278 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40279 + XX_FreeSmart(
40280 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40281 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40282 + XX_FreeSmart(
40283 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40284 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40285 + XX_FreeSmart(
40286 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40287 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40288 + XX_FreeSmart(
40289 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40290 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40291 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40292 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40293 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40294 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40295 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40296 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40297 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40298 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40299 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40300 + }
40301 + }
40302 +
40303 + if (p_Manip->p_StatsTbl)
40304 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40305 +}
40306 +
40307 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40308 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40309 +{
40310 + if (p_ManipParams->u.hdr.rmv)
40311 + {
40312 + switch (p_ManipParams->u.hdr.rmvParams.type)
40313 + {
40314 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40315 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40316 + {
40317 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40318 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40319 + {
40320 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40321 + {
40322 + case (HEADER_TYPE_CAPWAP_DTLS) :
40323 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40324 + p_Manip->muramAllocate = TRUE;
40325 + if (p_ManipParams->u.hdr.insrt)
40326 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40327 + if (p_ManipParams->fragOrReasm)
40328 + {
40329 + if (!p_ManipParams->fragOrReasmParams.frag)
40330 + {
40331 + switch (p_ManipParams->fragOrReasmParams.hdr)
40332 + {
40333 + case (HEADER_TYPE_CAPWAP):
40334 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40335 + break;
40336 + default:
40337 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40338 + }
40339 + }
40340 + else
40341 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40342 + }
40343 + break;
40344 + default:
40345 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40346 + }
40347 + }
40348 + else
40349 + {
40350 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40351 + {
40352 + case (HEADER_TYPE_CAPWAP_DTLS) :
40353 + case (HEADER_TYPE_CAPWAP) :
40354 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40355 + 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"));
40356 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40357 + p_Manip->muramAllocate = TRUE;
40358 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40359 + break;
40360 + default :
40361 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40362 + }
40363 + }
40364 + break;
40365 + default :
40366 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40367 + }
40368 + break;
40369 + default:
40370 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40371 + }
40372 + }
40373 + else if (p_ManipParams->u.hdr.insrt)
40374 + {
40375 + switch (p_ManipParams->u.hdr.insrtParams.type)
40376 + {
40377 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40378 +
40379 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40380 + p_Manip->muramAllocate = FALSE;
40381 + if (p_ManipParams->fragOrReasm)
40382 + {
40383 + if (p_ManipParams->fragOrReasmParams.frag)
40384 + {
40385 + switch (p_ManipParams->fragOrReasmParams.hdr)
40386 + {
40387 + case (HEADER_TYPE_CAPWAP):
40388 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40389 + break;
40390 + default:
40391 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40392 + }
40393 + }
40394 + else
40395 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40396 + }
40397 + break;
40398 +
40399 + default:
40400 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40401 + }
40402 + }
40403 + else if (p_ManipParams->fragOrReasm)
40404 + {
40405 + if (p_ManipParams->fragOrReasmParams.frag)
40406 + {
40407 + switch (p_ManipParams->fragOrReasmParams.hdr)
40408 + {
40409 + case (HEADER_TYPE_CAPWAP):
40410 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40411 + p_Manip->muramAllocate = FALSE;
40412 + break;
40413 + default:
40414 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40415 + }
40416 + }
40417 + else
40418 + {
40419 + switch (p_ManipParams->fragOrReasmParams.hdr)
40420 + {
40421 + case (HEADER_TYPE_CAPWAP):
40422 + 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"));
40423 + default:
40424 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40425 + }
40426 + }
40427 +
40428 + }
40429 + else
40430 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40431 +
40432 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40433 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40434 +
40435 + return E_OK;
40436 +}
40437 +
40438 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40439 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40440 + t_FmPcdManipParams *p_ManipParams)
40441 +{
40442 + switch (p_ManipParams->type)
40443 + {
40444 + case e_FM_PCD_MANIP_HDR:
40445 + /* Check that next-manip is not already used */
40446 + if (p_ManipParams->h_NextManip)
40447 + {
40448 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40449 + RETURN_ERROR(
40450 + MAJOR, E_INVALID_STATE,
40451 + ("h_NextManip is already a part of another chain"));
40452 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40453 + != e_FM_PCD_MANIP_HDR) &&
40454 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40455 + != e_FM_PCD_MANIP_FRAG))
40456 + RETURN_ERROR(
40457 + MAJOR,
40458 + E_NOT_SUPPORTED,
40459 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40460 + }
40461 +
40462 + if (p_ManipParams->u.hdr.rmv)
40463 + {
40464 + switch (p_ManipParams->u.hdr.rmvParams.type)
40465 + {
40466 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40467 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40468 + {
40469 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40470 + break;
40471 +#if (DPAA_VERSION >= 11)
40472 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40473 + break;
40474 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40475 + {
40476 + t_Error err;
40477 + uint8_t prsArrayOffset;
40478 +
40479 + err =
40480 + GetPrOffsetByHeaderOrField(
40481 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40482 + &prsArrayOffset);
40483 + if (err)
40484 + RETURN_ERROR(MAJOR, err, NO_MSG);
40485 + break;
40486 + }
40487 +#endif /* (DPAA_VERSION >= 11) */
40488 + default:
40489 + RETURN_ERROR(
40490 + MAJOR,
40491 + E_INVALID_STATE,
40492 + ("invalid type of remove manipulation"));
40493 + }
40494 + break;
40495 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40496 + break;
40497 + default:
40498 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40499 + ("invalid type of remove manipulation"));
40500 + }
40501 + p_Manip->opcode = HMAN_OC;
40502 + p_Manip->muramAllocate = TRUE;
40503 + p_Manip->rmv = TRUE;
40504 + }
40505 + else
40506 + if (p_ManipParams->u.hdr.insrt)
40507 + {
40508 + switch (p_ManipParams->u.hdr.insrtParams.type)
40509 + {
40510 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40511 + {
40512 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40513 + {
40514 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40515 + /* nothing to check */
40516 + break;
40517 +#if (DPAA_VERSION >= 11)
40518 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40519 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40520 + % 4)
40521 + RETURN_ERROR(
40522 + MAJOR,
40523 + E_INVALID_VALUE,
40524 + ("IP inserted header must be of size which is a multiple of four bytes"));
40525 + break;
40526 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40527 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40528 + % 4)
40529 + RETURN_ERROR(
40530 + MAJOR,
40531 + E_INVALID_VALUE,
40532 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40533 + break;
40534 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40535 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40536 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40537 + != 8)
40538 + RETURN_ERROR(
40539 + MAJOR,
40540 + E_INVALID_VALUE,
40541 + ("Inserted header must be of size 8"));
40542 + break;
40543 +#endif /* (DPAA_VERSION >= 11) */
40544 + default:
40545 + RETURN_ERROR(
40546 + MAJOR,
40547 + E_INVALID_STATE,
40548 + ("unsupported insert by header type"));
40549 + }
40550 + }
40551 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40552 + break;
40553 + default:
40554 + RETURN_ERROR(
40555 + MAJOR,
40556 + E_INVALID_STATE,
40557 + ("for only insert manipulation unsupported type"));
40558 + }
40559 + p_Manip->opcode = HMAN_OC;
40560 + p_Manip->muramAllocate = TRUE;
40561 + p_Manip->insrt = TRUE;
40562 + }
40563 + else
40564 + if (p_ManipParams->u.hdr.fieldUpdate)
40565 + {
40566 + /* Check parameters */
40567 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40568 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40569 + {
40570 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40571 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40572 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40573 + > 7))
40574 + RETURN_ERROR(
40575 + MAJOR, E_INVALID_VALUE,
40576 + ("vpri should get values of 0-7 "));
40577 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40578 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40579 + {
40580 + int i;
40581 +
40582 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40583 + > 7)
40584 + RETURN_ERROR(
40585 + MAJOR,
40586 + E_INVALID_VALUE,
40587 + ("vpriDefVal should get values of 0-7 "));
40588 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40589 + i++)
40590 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40591 + & 0xf0)
40592 + RETURN_ERROR(
40593 + MAJOR,
40594 + E_INVALID_VALUE,
40595 + ("dscpToVpriTabl value out of range (0-15)"));
40596 + }
40597 +
40598 + }
40599 +
40600 + p_Manip->opcode = HMAN_OC;
40601 + p_Manip->muramAllocate = TRUE;
40602 + p_Manip->fieldUpdate = TRUE;
40603 + }
40604 + else
40605 + if (p_ManipParams->u.hdr.custom)
40606 + {
40607 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40608 + {
40609 +
40610 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40611 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40612 + RETURN_ERROR(
40613 + MAJOR, E_INVALID_VALUE,
40614 + ("size should get values of 1-8 "));
40615 +
40616 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40617 + RETURN_ERROR(
40618 + MAJOR, E_INVALID_VALUE,
40619 + ("srcOffset should be <= 7"));
40620 +
40621 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40622 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40623 + RETURN_ERROR(
40624 + MAJOR, E_INVALID_VALUE,
40625 + ("(srcOffset + size) should be <= 8"));
40626 +
40627 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40628 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40629 + RETURN_ERROR(
40630 + MAJOR, E_INVALID_VALUE,
40631 + ("(dstOffset + size) should be <= 256"));
40632 +
40633 + }
40634 +
40635 + p_Manip->opcode = HMAN_OC;
40636 + p_Manip->muramAllocate = TRUE;
40637 + p_Manip->custom = TRUE;
40638 + }
40639 + break;
40640 + case e_FM_PCD_MANIP_REASSEM:
40641 + if (p_ManipParams->h_NextManip)
40642 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40643 + ("next manip with reassembly"));
40644 + switch (p_ManipParams->u.reassem.hdr)
40645 + {
40646 + case (HEADER_TYPE_IPv4):
40647 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40648 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40649 + break;
40650 + case (HEADER_TYPE_IPv6):
40651 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40652 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40653 + break;
40654 +#if (DPAA_VERSION >= 11)
40655 + case (HEADER_TYPE_CAPWAP):
40656 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40657 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40658 + break;
40659 +#endif /* (DPAA_VERSION >= 11) */
40660 + default:
40661 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40662 + ("header for reassembly"));
40663 + }
40664 + break;
40665 + case e_FM_PCD_MANIP_FRAG:
40666 + if (p_ManipParams->h_NextManip)
40667 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40668 + ("next manip with fragmentation"));
40669 + switch (p_ManipParams->u.frag.hdr)
40670 + {
40671 + case (HEADER_TYPE_IPv4):
40672 + case (HEADER_TYPE_IPv6):
40673 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40674 + break;
40675 +#if (DPAA_VERSION >= 11)
40676 + case (HEADER_TYPE_CAPWAP):
40677 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40678 + break;
40679 +#endif /* (DPAA_VERSION >= 11) */
40680 + default:
40681 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40682 + ("header for fragmentation"));
40683 + }
40684 + p_Manip->muramAllocate = TRUE;
40685 + break;
40686 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40687 + switch (p_ManipParams->u.specialOffload.type)
40688 + {
40689 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40690 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40691 + p_Manip->muramAllocate = TRUE;
40692 + break;
40693 +#if (DPAA_VERSION >= 11)
40694 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40695 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40696 + p_Manip->muramAllocate = TRUE;
40697 + break;
40698 +#endif /* (DPAA_VERSION >= 11) */
40699 + default:
40700 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40701 + ("special offload type"));
40702 + }
40703 + break;
40704 + default:
40705 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40706 + }
40707 +
40708 + return E_OK;
40709 +}
40710 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40711 +
40712 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40713 +
40714 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40715 + t_Handle h_FmPort,
40716 + t_FmPcdManip *p_Manip)
40717 +{
40718 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40719 + uint32_t tmpReg32 = 0;
40720 + t_AdOfTypeContLookup *p_Ad;
40721 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40722 + t_Error err;
40723 +
40724 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40725 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40726 +
40727 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40728 + if (p_Manip->h_FmPcd != h_FmPcd)
40729 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40730 + ("handler of PCD previously was initiated by different value"));
40731 +
40732 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40733 +
40734 + if (!p_Manip->p_StatsTbl)
40735 + {
40736 +
40737 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40738 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40739 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40740 + if (err)
40741 + RETURN_ERROR(MAJOR, err, NO_MSG);
40742 +
40743 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40744 +
40745 + p_Manip->p_StatsTbl =
40746 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40747 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40748 + 4);
40749 + if (!p_Manip->p_StatsTbl)
40750 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40751 +
40752 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40753 +
40754 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40755 +
40756 + if (p_Manip->cnia)
40757 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40758 +
40759 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40760 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40761 + }
40762 + else
40763 + {
40764 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40765 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40766 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40767 + if (err)
40768 + RETURN_ERROR(MAJOR, err, NO_MSG);
40769 + }
40770 +
40771 + return E_OK;
40772 +}
40773 +
40774 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40775 +{
40776 + t_AdOfTypeContLookup *p_Ad;
40777 + uint32_t tmpReg32 = 0;
40778 + uint8_t prsArrayOffset = 0;
40779 + t_Error err;
40780 +
40781 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40782 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40783 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40784 +
40785 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40786 + if (p_Manip->rmv)
40787 + {
40788 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40789 + if (err)
40790 + RETURN_ERROR(MAJOR, err, NO_MSG);
40791 +
40792 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40793 + tmpReg32 |= HMAN_RMV_HDR;
40794 + }
40795 +
40796 + if (p_Manip->insrt)
40797 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40798 +
40799 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40800 +
40801 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40802 +
40803 + tmpReg32 = 0;
40804 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40805 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40806 +
40807 + return E_OK;
40808 +}
40809 +
40810 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40811 + bool caamUsed)
40812 +{
40813 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40814 + uint32_t tmpReg32 = 0;
40815 +
40816 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40817 +
40818 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40819 +
40820 + tmpReg32 = 0;
40821 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40822 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40823 +
40824 + tmpReg32 = 0;
40825 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40826 + tmpReg32 |= (uint32_t)0x16 << 16;
40827 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40828 +
40829 + if (caamUsed)
40830 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40831 +
40832 + return E_OK;
40833 +}
40834 +
40835 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40836 +{
40837 + t_AdOfTypeContLookup *p_Ad;
40838 + uint32_t tmpReg32 = 0;
40839 + t_Error err = E_OK;
40840 +
40841 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40842 +
40843 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40844 +
40845 + tmpReg32 = 0;
40846 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40847 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40848 +
40849 + tmpReg32 = 0;
40850 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40851 +
40852 +
40853 + if (p_Manip->h_Frag)
40854 + {
40855 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
40856 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
40857 + }
40858 +
40859 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40860 +
40861 + return err;
40862 +}
40863 +
40864 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
40865 + t_FmPcdManip *p_Manip,
40866 + t_FmPcd *p_FmPcd,
40867 + uint8_t poolId)
40868 +{
40869 + t_Handle p_Table;
40870 + uint32_t tmpReg32 = 0;
40871 + int i = 0;
40872 + uint8_t log2Num;
40873 + uint8_t numOfSets;
40874 + uint32_t j = 0;
40875 + uint32_t bitFor1Micro;
40876 +
40877 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40878 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
40879 +
40880 + if (!p_FmPcd->h_Hc)
40881 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
40882 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
40883 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
40884 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
40885 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
40886 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
40887 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
40888 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
40889 + {
40890 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
40891 + (p_ManipParams->maxNumFramesInProcess > 512))
40892 + 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"));
40893 + }
40894 + else
40895 + {
40896 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
40897 + (p_ManipParams->maxNumFramesInProcess > 2048))
40898 + 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"));
40899 + }
40900 +
40901 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
40902 + if (bitFor1Micro == 0)
40903 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
40904 +
40905 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
40906 +
40907 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40908 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
40909 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40910 + if (!p_Manip->h_Frag)
40911 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
40912 +
40913 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
40914 +
40915 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
40916 +
40917 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
40918 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40919 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
40920 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40921 +
40922 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40923 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
40924 +
40925 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
40926 +
40927 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
40928 +
40929 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
40930 +
40931 + tmpReg32 = 0;
40932 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
40933 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
40934 + if (p_ManipParams->haltOnDuplicationFrag)
40935 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
40936 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
40937 + {
40938 + i = 8;
40939 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
40940 + }
40941 + else
40942 + i = 4;
40943 +
40944 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
40945 + LOG2(numOfSets, log2Num);
40946 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
40947 +
40948 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
40949 +
40950 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
40951 + if (((j / i) % 2)== 0)
40952 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
40953 +
40954 + tmpReg32 = 0x00008000;
40955 + tmpReg32 |= (uint32_t)poolId << 16;
40956 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
40957 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
40958 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
40959 +
40960 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
40961 +
40962 + p_Manip->capwapFragParams.sgBpid = poolId;
40963 +
40964 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
40965 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
40966 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
40967 +
40968 + tmpReg32 = 0;
40969 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
40970 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
40971 +
40972 + return E_OK;
40973 +}
40974 +
40975 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
40976 + t_FmPcdManip *p_Manip,
40977 + t_FmPcd *p_FmPcd,
40978 + uint8_t poolId)
40979 +{
40980 + t_AdOfTypeContLookup *p_Ad;
40981 + uint32_t tmpReg32 = 0;
40982 +
40983 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40984 +
40985 + p_Manip->updateParams |= OFFSET_OF_DATA;
40986 +
40987 + p_Manip->frag = TRUE;
40988 +
40989 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40990 + FM_PCD_CC_AD_ENTRY_SIZE,
40991 + FM_PCD_CC_AD_TABLE_ALIGN);
40992 + if (!p_Manip->h_Frag)
40993 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
40994 +
40995 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
40996 +
40997 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40998 +
40999 + tmpReg32 = 0;
41000 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
41001 +
41002 + if (p_ManipParams->headerOptionsCompr)
41003 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
41004 + tmpReg32 |= ((uint32_t)poolId << 8);
41005 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41006 +
41007 + tmpReg32 = 0;
41008 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41009 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41010 +
41011 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41012 + p_Manip->capwapFragParams.sgBpid = poolId;
41013 +
41014 + return E_OK;
41015 +}
41016 +
41017 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
41018 +{
41019 + t_AdOfTypeContLookup *p_Ad;
41020 + uint32_t tmpReg32 = 0;
41021 +
41022 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41023 +
41024 + UNUSED(p_FmPcd);
41025 +
41026 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41027 +
41028 + tmpReg32 = 0;
41029 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
41030 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
41031 + tmpReg32 |= (uint32_t)0x16 << 16;
41032 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41033 +
41034 + tmpReg32 = 0;
41035 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41036 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41037 +
41038 + return E_OK;
41039 +}
41040 +
41041 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
41042 +{
41043 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
41044 + uint8_t tmpReg8 = 0xff;
41045 + t_AdOfTypeContLookup *p_Ad;
41046 + bool ipModify = FALSE;
41047 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41048 + uint16_t tmpReg16 = 0;
41049 + t_Error err = E_OK;
41050 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
41051 + uint8_t *p_Template = NULL;
41052 +
41053 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
41054 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
41055 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41056 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
41057 +
41058 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41059 + if (p_Manip->insrt)
41060 + {
41061 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
41062 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
41063 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
41064 +
41065 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
41066 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
41067 +
41068 + if (p_InsrtByTemplate->size > 128)
41069 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
41070 +
41071 + if (p_InsrtByTemplate->size)
41072 + {
41073 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41074 + p_InsrtByTemplate->size,
41075 + FM_PCD_CC_AD_TABLE_ALIGN);
41076 + if(!p_Manip->p_Template)
41077 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
41078 +
41079 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
41080 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
41081 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
41082 + }
41083 +
41084 + tmpReg32 = 0;
41085 +
41086 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
41087 +
41088 + if (!p_Template)
41089 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
41090 +
41091 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
41092 +
41093 + if (p_InsrtByTemplate->modifyOuterIp)
41094 + {
41095 + ipModify = TRUE;
41096 +
41097 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
41098 +
41099 + if((tmpReg8 & 0xf0) == 0x40)
41100 + tmpReg8 = 4;
41101 + else if((tmpReg8 & 0xf0) == 0x60)
41102 + tmpReg8 = 6;
41103 + else
41104 + tmpReg8 = 0xff;
41105 +
41106 + if (tmpReg8 != 0xff)
41107 + {
41108 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
41109 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
41110 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
41111 + {
41112 +
41113 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
41114 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
41115 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
41116 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
41117 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
41118 + /*IP header template - IP totalLength -
41119 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
41120 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
41121 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
41122 + }
41123 + if (blockSize)
41124 + {
41125 + if (!POWER_OF_2(blockSize))
41126 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
41127 + }
41128 +
41129 + }
41130 + if (tmpReg8 == 4)
41131 + {
41132 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
41133 + 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"));
41134 +
41135 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
41136 +
41137 + if (blockSize)
41138 + blockSize -= 1;
41139 +
41140 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
41141 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
41142 +
41143 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
41144 + 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
41145 +
41146 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
41147 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41148 +
41149 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
41150 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
41151 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
41152 +
41153 + /*UDP checksum has to be 0*/
41154 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41155 + {
41156 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41157 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41158 +
41159 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
41160 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41161 +
41162 + }
41163 +
41164 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
41165 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
41166 +
41167 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
41168 + }
41169 + else if (tmpReg8 == 6)
41170 + {
41171 + /*TODO - add check for maximum value of blockSize;*/
41172 + if (blockSize)
41173 + LOG2(blockSize, log2Num);
41174 + tmpRegNia |= (uint32_t)log2Num << 24;
41175 +
41176 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
41177 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
41178 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41179 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41180 + {
41181 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41182 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41183 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
41184 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
41185 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
41186 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
41187 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
41188 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41189 + }
41190 + }
41191 + else
41192 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
41193 + }
41194 +
41195 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
41196 + /*TODO - check it*/
41197 + if (p_InsrtByTemplate->modifyOuterVlan)
41198 + {
41199 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
41200 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41201 +
41202 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41203 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41204 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41205 +
41206 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41207 + tmpReg8 &= 0x1f;
41208 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41209 +
41210 + p_Template[14] = tmpReg8;
41211 + }
41212 +
41213 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41214 +
41215 + XX_Free(p_Template);
41216 + }
41217 +
41218 + tmpReg32 = 0;
41219 + if (p_Manip->h_Frag)
41220 + {
41221 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41222 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41223 + }
41224 + else
41225 + tmpReg32 = 0xffff0000;
41226 +
41227 + if (ipModify)
41228 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41229 + else
41230 + tmpReg32 |= (uint32_t)0x0000ff00;
41231 +
41232 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41233 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41234 +
41235 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41236 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41237 +
41238 + return err;
41239 +}
41240 +
41241 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41242 +{
41243 +
41244 + switch (p_StatsParams->type)
41245 + {
41246 + case (e_FM_PCD_STATS_PER_FLOWID):
41247 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41248 + p_Manip->muramAllocate = TRUE;
41249 + break;
41250 + default:
41251 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41252 + }
41253 +
41254 + return E_OK;
41255 +}
41256 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41257 +
41258 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41259 +{
41260 + t_AdOfTypeContLookup *p_Ad;
41261 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41262 + uint32_t tmpReg32;
41263 + t_Error err = E_OK;
41264 +
41265 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41266 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41267 + two separate IP Reassembly Parameter tables are required.*/
41268 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41269 + RETURN_ERROR(MAJOR, err, NO_MSG);
41270 +
41271 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41272 + tmpReg32 = 0;
41273 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41274 +
41275 + /* Gets the required Action descriptor table pointer */
41276 + switch (hdr)
41277 + {
41278 + case HEADER_TYPE_IPv4:
41279 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41280 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41281 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41282 + - (p_FmPcd->physicalMuramBase));
41283 + break;
41284 + case HEADER_TYPE_IPv6:
41285 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41286 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41287 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41288 + - (p_FmPcd->physicalMuramBase));
41289 + break;
41290 + case HEADER_TYPE_CAPWAP:
41291 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41292 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41293 + p_Manip->reassmParams.capwap.p_ReassTbl)
41294 + - (p_FmPcd->physicalMuramBase));
41295 + break;
41296 + default:
41297 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41298 + }
41299 +
41300 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41301 +
41302 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41303 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41304 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41305 +
41306 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41307 + {
41308 +#if (DPAA_VERSION == 10)
41309 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41310 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41311 +#endif /* (DPAA_VERSION == 10) */
41312 +#if (DPAA_VERSION >= 11)
41313 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41314 + {
41315 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41316 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41317 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41318 + }
41319 +#endif /* (DPAA_VERSION >= 11) */
41320 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41321 + tmpReg32 = 0;
41322 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41323 + }
41324 +#if (DPAA_VERSION >= 11)
41325 + else
41326 + if (hdr == HEADER_TYPE_CAPWAP)
41327 + {
41328 + tmpReg32 = 0;
41329 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41330 + }
41331 +#endif /* (DPAA_VERSION >= 11) */
41332 +
41333 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41334 +
41335 + p_Manip->reassm = TRUE;
41336 +
41337 + return E_OK;
41338 +}
41339 +
41340 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41341 +{
41342 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41343 +
41344 + /* Allocation if IPv4 Action descriptor */
41345 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41346 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41347 + FM_PCD_CC_AD_TABLE_ALIGN);
41348 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41349 + {
41350 + ReleaseManipHandler(p_Manip, p_FmPcd);
41351 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41352 + ("Allocation of IPv4 table descriptor"));
41353 + }
41354 +
41355 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41356 +
41357 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41358 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41359 +}
41360 +
41361 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41362 +{
41363 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41364 +
41365 + /* Allocation if IPv6 Action descriptor */
41366 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41367 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41368 + FM_PCD_CC_AD_TABLE_ALIGN);
41369 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41370 + {
41371 + ReleaseManipHandler(p_Manip, p_FmPcd);
41372 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41373 + ("Allocation of IPv6 table descriptor"));
41374 + }
41375 +
41376 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41377 +
41378 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41379 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41380 +}
41381 +
41382 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41383 + t_FmPcdManip *p_Manip)
41384 +{
41385 + uint32_t maxSetNumber = 10000;
41386 + t_FmPcdManipReassemIpParams reassmManipParams =
41387 + p_ManipReassmParams->u.ipReassem;
41388 + t_Error res;
41389 +
41390 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41391 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41392 + E_INVALID_HANDLE);
41393 +
41394 + /* Check validation of user's parameter.*/
41395 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41396 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41397 + RETURN_ERROR(
41398 + MAJOR, E_INVALID_VALUE,
41399 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41400 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41401 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41402 + if (reassmManipParams.maxNumFramesInProcess
41403 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41404 + RETURN_ERROR(
41405 + MAJOR,
41406 + E_INVALID_VALUE,
41407 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41408 +
41409 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41410 + && (reassmManipParams.minFragSize[1] < 256))
41411 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41412 +
41413 + /* Saves user's reassembly manipulation parameters */
41414 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41415 + reassmManipParams.relativeSchemeId[0];
41416 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41417 + reassmManipParams.relativeSchemeId[1];
41418 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41419 + reassmManipParams.numOfFramesPerHashEntry[0];
41420 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41421 + reassmManipParams.numOfFramesPerHashEntry[1];
41422 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41423 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41424 + p_Manip->reassmParams.maxNumFramesInProcess =
41425 + reassmManipParams.maxNumFramesInProcess;
41426 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41427 + p_Manip->reassmParams.fqidForTimeOutFrames =
41428 + reassmManipParams.fqidForTimeOutFrames;
41429 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41430 + reassmManipParams.timeoutThresholdForReassmProcess;
41431 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41432 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41433 +#if (DPAA_VERSION == 10)
41434 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41435 +#endif /* (DPAA_VERSION == 10) */
41436 +#if (DPAA_VERSION >= 11)
41437 + if (reassmManipParams.nonConsistentSpFqid != 0)
41438 + {
41439 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41440 + reassmManipParams.nonConsistentSpFqid;
41441 + }
41442 +#endif /* (DPAA_VERSION >= 11) */
41443 +
41444 + /* Creates and initializes the IP Reassembly common parameter table */
41445 + CreateReassCommonTable(p_Manip);
41446 +
41447 + /* Creation of IPv4 reassembly manipulation */
41448 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41449 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41450 + {
41451 + res = SetIpv4ReassmManip(p_Manip);
41452 + if (res != E_OK)
41453 + return res;
41454 + }
41455 +
41456 + /* Creation of IPv6 reassembly manipulation */
41457 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41458 + {
41459 + res = SetIpv6ReassmManip(p_Manip);
41460 + if (res != E_OK)
41461 + return res;
41462 + }
41463 +
41464 + return E_OK;
41465 +}
41466 +
41467 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41468 + t_FmPcdKgSchemeParams *p_Scheme,
41469 + t_Handle h_CcTree, bool ipv4,
41470 + uint8_t groupId)
41471 +{
41472 + uint32_t j;
41473 + uint8_t res;
41474 +
41475 + /* Configures scheme's network environment parameters */
41476 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41477 + if (ipv4)
41478 + res = FmPcdNetEnvGetUnitId(
41479 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41480 + HEADER_TYPE_IPv4, FALSE, 0);
41481 + else
41482 + res = FmPcdNetEnvGetUnitId(
41483 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41484 + HEADER_TYPE_IPv6, FALSE, 0);
41485 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41486 + p_Scheme->netEnvParams.unitIds[0] = res;
41487 +
41488 + res = FmPcdNetEnvGetUnitId(
41489 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41490 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41491 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41492 + p_Scheme->netEnvParams.unitIds[1] = res;
41493 +
41494 + /* Configures scheme's next engine parameters*/
41495 + p_Scheme->nextEngine = e_FM_PCD_CC;
41496 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41497 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41498 + p_Scheme->useHash = TRUE;
41499 +
41500 + /* Configures scheme's key*/
41501 + if (ipv4 == TRUE)
41502 + {
41503 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41504 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41505 + e_FM_PCD_EXTRACT_BY_HDR;
41506 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41507 + e_FM_PCD_EXTRACT_FULL_FIELD;
41508 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41509 + HEADER_TYPE_IPv4;
41510 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41511 + NET_HEADER_FIELD_IPv4_DST_IP;
41512 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41513 + e_FM_PCD_EXTRACT_BY_HDR;
41514 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41515 + e_FM_PCD_EXTRACT_FULL_FIELD;
41516 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41517 + HEADER_TYPE_IPv4;
41518 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41519 + NET_HEADER_FIELD_IPv4_SRC_IP;
41520 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41521 + e_FM_PCD_EXTRACT_BY_HDR;
41522 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41523 + e_FM_PCD_EXTRACT_FULL_FIELD;
41524 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41525 + HEADER_TYPE_IPv4;
41526 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41527 + NET_HEADER_FIELD_IPv4_PROTO;
41528 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41529 + e_FM_PCD_EXTRACT_BY_HDR;
41530 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41531 + HEADER_TYPE_IPv4;
41532 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41533 + e_FM_PCD_EXTRACT_FROM_HDR;
41534 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41535 + FALSE;
41536 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41537 + 2;
41538 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41539 + 4;
41540 + }
41541 + else /* IPv6 */
41542 + {
41543 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41544 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41545 + e_FM_PCD_EXTRACT_BY_HDR;
41546 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41547 + e_FM_PCD_EXTRACT_FULL_FIELD;
41548 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41549 + HEADER_TYPE_IPv6;
41550 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41551 + NET_HEADER_FIELD_IPv6_DST_IP;
41552 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41553 + e_FM_PCD_EXTRACT_BY_HDR;
41554 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41555 + e_FM_PCD_EXTRACT_FULL_FIELD;
41556 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41557 + HEADER_TYPE_IPv6;
41558 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41559 + NET_HEADER_FIELD_IPv6_SRC_IP;
41560 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41561 + e_FM_PCD_EXTRACT_BY_HDR;
41562 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41563 + HEADER_TYPE_USER_DEFINED_SHIM2;
41564 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41565 + e_FM_PCD_EXTRACT_FROM_HDR;
41566 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41567 + 4;
41568 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41569 + 4;
41570 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41571 + TRUE;
41572 + }
41573 +
41574 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41575 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41576 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41577 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41578 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41579 + {
41580 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41581 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41582 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41583 + e_FM_PCD_KG_DFLT_GBL_0;
41584 + }
41585 +}
41586 +
41587 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41588 + t_FmPcdManipReassemIpStats *p_Stats)
41589 +{
41590 + ASSERT_COND(p_Manip);
41591 + ASSERT_COND(p_Stats);
41592 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41593 +
41594 + p_Stats->timeout =
41595 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41596 + p_Stats->rfdPoolBusy =
41597 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41598 + p_Stats->internalBufferBusy =
41599 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41600 + p_Stats->externalBufferBusy =
41601 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41602 + p_Stats->sgFragments =
41603 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41604 + p_Stats->dmaSemaphoreDepletion =
41605 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41606 +#if (DPAA_VERSION >= 11)
41607 + p_Stats->nonConsistentSp =
41608 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41609 +#endif /* (DPAA_VERSION >= 11) */
41610 +
41611 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41612 + {
41613 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41614 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41615 + p_Stats->specificHdrStatistics[0].validFragments =
41616 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41617 + p_Stats->specificHdrStatistics[0].processedFragments =
41618 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41619 + p_Stats->specificHdrStatistics[0].malformedFragments =
41620 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41621 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41622 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41623 + p_Stats->specificHdrStatistics[0].discardedFragments =
41624 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41625 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41626 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41627 + }
41628 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41629 + {
41630 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41631 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41632 + p_Stats->specificHdrStatistics[1].validFragments =
41633 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41634 + p_Stats->specificHdrStatistics[1].processedFragments =
41635 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41636 + p_Stats->specificHdrStatistics[1].malformedFragments =
41637 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41638 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41639 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41640 + p_Stats->specificHdrStatistics[1].discardedFragments =
41641 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41642 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41643 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41644 + }
41645 + return E_OK;
41646 +}
41647 +
41648 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41649 + t_FmPcdManipFragIpStats *p_Stats)
41650 +{
41651 + t_AdOfTypeContLookup *p_Ad;
41652 +
41653 + ASSERT_COND(p_Manip);
41654 + ASSERT_COND(p_Stats);
41655 + ASSERT_COND(p_Manip->h_Ad);
41656 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41657 +
41658 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41659 +
41660 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41661 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41662 + & 0x00ffffff;
41663 + p_Stats->generatedFragments =
41664 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41665 +
41666 + return E_OK;
41667 +}
41668 +
41669 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41670 + t_FmPcdManip *p_Manip)
41671 +{
41672 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41673 + t_FmPcd *p_FmPcd;
41674 +#if (DPAA_VERSION == 10)
41675 + t_Error err = E_OK;
41676 +#endif /* (DPAA_VERSION == 10) */
41677 +
41678 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41679 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41680 + E_INVALID_VALUE);
41681 +
41682 + p_FmPcd = p_Manip->h_FmPcd;
41683 + /* Allocation of fragmentation Action Descriptor */
41684 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41685 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41686 + FM_PCD_CC_AD_TABLE_ALIGN);
41687 + if (!p_Manip->fragParams.p_Frag)
41688 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41689 + ("MURAM alloc for Fragmentation table descriptor"));
41690 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41691 +
41692 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41693 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41694 +
41695 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41696 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41697 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41698 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41699 +
41700 +
41701 + /* Set Scatter/Gather BPid */
41702 + if (p_ManipParams->sgBpidEn)
41703 + {
41704 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41705 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41706 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41707 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41708 + }
41709 +
41710 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41711 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41712 + - p_FmPcd->physicalMuramBase);
41713 +#if (DPAA_VERSION == 10)
41714 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41715 +#else
41716 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41717 +#endif /* (DPAA_VERSION == 10) */
41718 +
41719 + /* Set all Ad registers */
41720 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41721 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41722 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41723 +
41724 + /* Saves user's fragmentation manipulation parameters */
41725 + p_Manip->frag = TRUE;
41726 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41727 +
41728 +#if (DPAA_VERSION == 10)
41729 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41730 +
41731 + /* scratch buffer pool initialization */
41732 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41733 + {
41734 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41735 + p_Manip->fragParams.p_Frag = NULL;
41736 + RETURN_ERROR(MAJOR, err, NO_MSG);
41737 + }
41738 +#endif /* (DPAA_VERSION == 10) */
41739 +
41740 + return E_OK;
41741 +}
41742 +
41743 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41744 +{
41745 + t_Error err = E_OK;
41746 + t_FmPcd *p_FmPcd;
41747 + t_AdOfTypeContLookup *p_Ad;
41748 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41749 +
41750 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41751 + p_FmPcd = p_Manip->h_FmPcd;
41752 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41753 +
41754 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41755 +
41756 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41757 + if (p_Manip->frag == TRUE)
41758 + {
41759 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41760 + - (p_FmPcd->physicalMuramBase));
41761 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41762 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41763 + }
41764 +
41765 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41766 + tmpReg32 |= HMAN_OC_IP_MANIP;
41767 +
41768 +#if (DPAA_VERSION >= 11)
41769 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41770 +#endif /* (DPAA_VERSION >= 11) */
41771 +
41772 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41773 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41774 + WRITE_UINT32(p_Ad->gmask, 0);
41775 + /* Total frame counter - MUST be initialized to zero.*/
41776 +
41777 + return err;
41778 +}
41779 +
41780 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41781 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41782 + t_Handle h_Ad, bool validate)
41783 +{
41784 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41785 + t_Error err;
41786 +
41787 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41788 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41789 + E_INVALID_STATE);
41790 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41791 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41792 +
41793 + UNUSED(h_FmPcd);
41794 + UNUSED(h_Ad);
41795 + UNUSED(h_PcdParams);
41796 + UNUSED(validate);
41797 + UNUSED(p_Manip);
41798 +
41799 + fmPortGetSetCcParams.setCcParams.type = 0;
41800 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41801 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41802 + RETURN_ERROR(MAJOR, err, NO_MSG);
41803 +
41804 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41805 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41806 +
41807 + return E_OK;
41808 +}
41809 +
41810 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41811 + t_FmPcdManip *p_Manip)
41812 +{
41813 + t_AdOfTypeContLookup *p_Ad;
41814 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41815 + t_Error err = E_OK;
41816 + uint32_t tmpReg32 = 0;
41817 + uint32_t power;
41818 +
41819 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41820 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41821 +
41822 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41823 +
41824 + SANITY_CHECK_RETURN_ERROR(
41825 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41826 + E_INVALID_VALUE);
41827 + SANITY_CHECK_RETURN_ERROR(
41828 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41829 + E_INVALID_VALUE);
41830 + SANITY_CHECK_RETURN_ERROR(
41831 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41832 + E_INVALID_VALUE);
41833 + SANITY_CHECK_RETURN_ERROR(
41834 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41835 + E_INVALID_VALUE);
41836 + SANITY_CHECK_RETURN_ERROR(
41837 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41838 + E_INVALID_VALUE);
41839 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41840 +
41841 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41842 +
41843 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41844 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
41845 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
41846 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
41847 + tmpReg32 |=
41848 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
41849 + tmpReg32 |=
41850 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
41851 + if (p_IPSecParams->arwSize)
41852 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
41853 + & (FM_MURAM_SIZE-1));
41854 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41855 +
41856 + tmpReg32 = 0;
41857 + if (p_IPSecParams->arwSize) {
41858 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
41859 + LOG2(power, power);
41860 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
41861 + }
41862 +
41863 + if (p_ManipParams->h_NextManip)
41864 + tmpReg32 |=
41865 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
41866 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
41867 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41868 +
41869 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
41870 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
41871 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
41872 + if (p_ManipParams->h_NextManip)
41873 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
41874 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41875 +
41876 + return err;
41877 +}
41878 +
41879 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
41880 +{
41881 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41882 +
41883 + /* Allocation if CAPWAP Action descriptor */
41884 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
41885 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41886 + FM_PCD_CC_AD_TABLE_ALIGN);
41887 + if (!p_Manip->reassmParams.capwap.h_Ad)
41888 + {
41889 + ReleaseManipHandler(p_Manip, p_FmPcd);
41890 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41891 + ("Allocation of CAPWAP table descriptor"));
41892 + }
41893 +
41894 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41895 +
41896 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
41897 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
41898 +}
41899 +
41900 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
41901 + t_FmPcdKgSchemeParams *p_Scheme,
41902 + t_Handle h_CcTree, uint8_t groupId)
41903 +{
41904 + uint8_t res;
41905 +
41906 + /* Configures scheme's network environment parameters */
41907 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
41908 + res = FmPcdNetEnvGetUnitId(
41909 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41910 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41911 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41912 + p_Scheme->netEnvParams.unitIds[0] = res;
41913 +
41914 + /* Configures scheme's next engine parameters*/
41915 + p_Scheme->nextEngine = e_FM_PCD_CC;
41916 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41917 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41918 + p_Scheme->useHash = TRUE;
41919 +
41920 + /* Configures scheme's key*/
41921 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
41922 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41923 + e_FM_PCD_EXTRACT_NON_HDR;
41924 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
41925 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
41926 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
41927 + e_FM_PCD_ACTION_NONE;
41928 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
41929 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
41930 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41931 + e_FM_PCD_EXTRACT_NON_HDR;
41932 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
41933 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
41934 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
41935 + e_FM_PCD_ACTION_NONE;
41936 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
41937 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
41938 +
41939 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
41940 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
41941 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
41942 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
41943 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
41944 +}
41945 +
41946 +#if (DPAA_VERSION >= 11)
41947 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
41948 + t_FmPcdManipReassemCapwapStats *p_Stats)
41949 +{
41950 + ASSERT_COND(p_Manip);
41951 + ASSERT_COND(p_Stats);
41952 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41953 +
41954 + p_Stats->timeout =
41955 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41956 + p_Stats->rfdPoolBusy =
41957 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41958 + p_Stats->internalBufferBusy =
41959 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41960 + p_Stats->externalBufferBusy =
41961 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41962 + p_Stats->sgFragments =
41963 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41964 + p_Stats->dmaSemaphoreDepletion =
41965 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41966 + p_Stats->exceedMaxReassemblyFrameLen =
41967 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41968 +
41969 + p_Stats->successfullyReassembled =
41970 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
41971 + p_Stats->validFragments =
41972 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
41973 + p_Stats->processedFragments =
41974 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
41975 + p_Stats->malformedFragments =
41976 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
41977 + p_Stats->autoLearnBusy =
41978 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
41979 + p_Stats->discardedFragments =
41980 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
41981 + p_Stats->moreThan16Fragments =
41982 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
41983 +
41984 + return E_OK;
41985 +}
41986 +
41987 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
41988 + t_FmPcdManipFragCapwapStats *p_Stats)
41989 +{
41990 + t_AdOfTypeContLookup *p_Ad;
41991 +
41992 + ASSERT_COND(p_Manip);
41993 + ASSERT_COND(p_Stats);
41994 + ASSERT_COND(p_Manip->h_Ad);
41995 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41996 +
41997 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41998 +
41999 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
42000 +
42001 + return E_OK;
42002 +}
42003 +
42004 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
42005 + t_FmPcdManip *p_Manip)
42006 +{
42007 + uint32_t maxSetNumber = 10000;
42008 + t_FmPcdManipReassemCapwapParams reassmManipParams =
42009 + p_ManipReassmParams->u.capwapReassem;
42010 + t_Error res;
42011 +
42012 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
42013 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
42014 + E_INVALID_HANDLE);
42015 +
42016 + /* Check validation of user's parameter.*/
42017 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
42018 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
42019 + RETURN_ERROR(
42020 + MAJOR, E_INVALID_VALUE,
42021 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
42022 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
42023 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
42024 + if (reassmManipParams.maxNumFramesInProcess
42025 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
42026 + RETURN_ERROR(
42027 + MAJOR,
42028 + E_INVALID_VALUE,
42029 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
42030 +
42031 + /* Saves user's reassembly manipulation parameters */
42032 + p_Manip->reassmParams.capwap.relativeSchemeId =
42033 + reassmManipParams.relativeSchemeId;
42034 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
42035 + reassmManipParams.numOfFramesPerHashEntry;
42036 + p_Manip->reassmParams.capwap.maxRessembledsSize =
42037 + reassmManipParams.maxReassembledFrameLength;
42038 + p_Manip->reassmParams.maxNumFramesInProcess =
42039 + reassmManipParams.maxNumFramesInProcess;
42040 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
42041 + p_Manip->reassmParams.fqidForTimeOutFrames =
42042 + reassmManipParams.fqidForTimeOutFrames;
42043 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
42044 + reassmManipParams.timeoutThresholdForReassmProcess;
42045 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
42046 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
42047 +
42048 + /* Creates and initializes the Reassembly common parameter table */
42049 + CreateReassCommonTable(p_Manip);
42050 +
42051 + res = SetCapwapReassmManip(p_Manip);
42052 + if (res != E_OK)
42053 + return res;
42054 +
42055 + return E_OK;
42056 +}
42057 +
42058 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
42059 + t_FmPcdManip *p_Manip)
42060 +{
42061 + t_FmPcd *p_FmPcd;
42062 + t_AdOfTypeContLookup *p_Ad;
42063 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
42064 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42065 +
42066 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42067 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
42068 + E_INVALID_VALUE);
42069 + p_FmPcd = p_Manip->h_FmPcd;
42070 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
42071 +
42072 + /* Allocation of fragmentation Action Descriptor */
42073 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
42074 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42075 + FM_PCD_CC_AD_TABLE_ALIGN);
42076 + if (!p_Manip->fragParams.p_Frag)
42077 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42078 + ("MURAM alloc for Fragmentation table descriptor"));
42079 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42080 +
42081 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
42082 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42083 +
42084 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
42085 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
42086 + ccAdBaseReg |=
42087 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
42088 + 0;
42089 +
42090 + /* Set Scatter/Gather BPid */
42091 + if (p_ManipParams->sgBpidEn)
42092 + {
42093 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
42094 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
42095 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
42096 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
42097 + }
42098 +
42099 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
42100 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
42101 + - p_FmPcd->physicalMuramBase);
42102 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
42103 +
42104 + /* Set all Ad registers */
42105 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
42106 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
42107 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
42108 +
42109 + /* Saves user's fragmentation manipulation parameters */
42110 + p_Manip->frag = TRUE;
42111 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42112 +
42113 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42114 +
42115 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
42116 + - (p_FmPcd->physicalMuramBase));
42117 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
42118 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
42119 +
42120 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42121 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
42122 +
42123 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
42124 +
42125 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42126 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
42127 + WRITE_UINT32(p_Ad->gmask, 0);
42128 + /* Total frame counter - MUST be initialized to zero.*/
42129 +
42130 + return E_OK;
42131 +}
42132 +
42133 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
42134 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
42135 + t_Handle h_Ad, bool validate)
42136 +{
42137 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42138 + t_Error err;
42139 +
42140 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42141 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
42142 + E_INVALID_STATE);
42143 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
42144 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
42145 +
42146 + UNUSED(h_FmPcd);
42147 + UNUSED(h_Ad);
42148 + UNUSED(h_PcdParams);
42149 + UNUSED(validate);
42150 + UNUSED(p_Manip);
42151 +
42152 + fmPortGetSetCcParams.setCcParams.type = 0;
42153 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
42154 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
42155 + RETURN_ERROR(MAJOR, err, NO_MSG);
42156 +
42157 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
42158 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
42159 +
42160 + return E_OK;
42161 +}
42162 +
42163 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
42164 + t_FmPcdManip *p_Manip)
42165 +{
42166 + t_AdOfTypeContLookup *p_Ad;
42167 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
42168 + t_Error err = E_OK;
42169 + uint32_t tmpReg32 = 0;
42170 +
42171 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42172 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42173 +
42174 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
42175 +
42176 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42177 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42178 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
42179 + /* TODO - add 'qosSrc' */
42180 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42181 +
42182 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
42183 + if (p_ManipParams->h_NextManip)
42184 + {
42185 + WRITE_UINT32(
42186 + p_Ad->matchTblPtr,
42187 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
42188 +
42189 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
42190 + }
42191 +
42192 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42193 +
42194 + return err;
42195 +}
42196 +#endif /* (DPAA_VERSION >= 11) */
42197 +
42198 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
42199 + bool stats)
42200 +{
42201 + t_FmPcdManip *p_Manip;
42202 + t_Error err;
42203 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42204 +
42205 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42206 + if (!p_Manip)
42207 + {
42208 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42209 + return NULL;
42210 + }
42211 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42212 +
42213 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42214 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42215 + sizeof(p_Manip->manipParams));
42216 +
42217 + if (!stats)
42218 + err = CheckManipParamsAndSetType(p_Manip,
42219 + (t_FmPcdManipParams *)p_Params);
42220 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42221 + else
42222 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42223 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42224 + else
42225 + {
42226 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42227 + XX_Free(p_Manip);
42228 + return NULL;
42229 + }
42230 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42231 + if (err)
42232 + {
42233 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42234 + XX_Free(p_Manip);
42235 + return NULL;
42236 + }
42237 +
42238 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42239 + {
42240 + /* In Case of reassembly manipulation the reassembly action descriptor will
42241 + be defines later on */
42242 + if (p_Manip->muramAllocate)
42243 + {
42244 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42245 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42246 + FM_PCD_CC_AD_TABLE_ALIGN);
42247 + if (!p_Manip->h_Ad)
42248 + {
42249 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42250 + ReleaseManipHandler(p_Manip, p_FmPcd);
42251 + XX_Free(p_Manip);
42252 + return NULL;
42253 + }
42254 +
42255 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42256 + }
42257 + else
42258 + {
42259 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42260 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42261 + if (!p_Manip->h_Ad)
42262 + {
42263 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42264 + ReleaseManipHandler(p_Manip, p_FmPcd);
42265 + XX_Free(p_Manip);
42266 + return NULL;
42267 + }
42268 +
42269 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42270 + }
42271 + }
42272 +
42273 + p_Manip->h_FmPcd = h_FmPcd;
42274 +
42275 + return p_Manip;
42276 +}
42277 +
42278 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42279 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42280 +{
42281 + t_CcNodeInformation *p_CcNodeInformation;
42282 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42283 + t_List *p_Pos;
42284 + int i = 0;
42285 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42286 + t_CcNodeInformation ccNodeInfo;
42287 +
42288 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42289 + {
42290 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42291 + p_NodePtrOnCurrentMdfManip =
42292 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42293 +
42294 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42295 +
42296 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42297 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42298 + {
42299 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42300 + == e_FM_PCD_CC)
42301 + {
42302 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42303 + == (t_Handle)p_CrntMdfManip)
42304 + {
42305 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42306 + p_AdTablePtOnCrntCurrentMdfNode =
42307 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42308 + else
42309 + p_AdTablePtOnCrntCurrentMdfNode =
42310 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42311 +
42312 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42313 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42314 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42315 + }
42316 + }
42317 + }
42318 +
42319 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42320 + }
42321 +}
42322 +
42323 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42324 + t_FmPcd *p_FmPcd)
42325 +{
42326 + t_Error err;
42327 +
42328 + /* Copy the HMTD */
42329 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42330 + /* Replace the HMCT table pointer */
42331 + WRITE_UINT32(
42332 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42333 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42334 + /* Call Host Command to replace HMTD by a new HMTD */
42335 + err = FmHcPcdCcDoDynamicChange(
42336 + p_FmPcd->h_Hc,
42337 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42338 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42339 + if (err)
42340 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42341 +}
42342 +
42343 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42344 + t_Handle h_FmPort, t_Handle h_Manip,
42345 + t_Handle h_Ad, bool validate, int level,
42346 + t_Handle h_FmTree)
42347 +{
42348 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42349 + t_Error err = E_OK;
42350 +
42351 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42352 +
42353 + UNUSED(level);
42354 + UNUSED(h_FmTree);
42355 +
42356 + switch (p_Manip->opcode)
42357 + {
42358 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42359 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42360 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42361 + p_Manip,
42362 + h_Ad,
42363 + validate);
42364 + break;
42365 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42366 + if (!p_Manip->h_Frag)
42367 + break;
42368 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42369 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42370 + break;
42371 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42372 + if (p_Manip->h_Frag)
42373 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42374 + break;
42375 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42376 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42377 + break;
42378 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42379 + case (HMAN_OC_IP_REASSEMBLY):
42380 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42381 + validate);
42382 + break;
42383 + case (HMAN_OC_IP_FRAGMENTATION):
42384 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42385 + h_Ad, validate);
42386 + break;
42387 +#if (DPAA_VERSION >= 11)
42388 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42389 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42390 + h_Ad, validate);
42391 + break;
42392 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42393 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42394 + validate);
42395 + break;
42396 +#endif /* (DPAA_VERSION >= 11) */
42397 + default:
42398 + return E_OK;
42399 + }
42400 +
42401 + return err;
42402 +}
42403 +
42404 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42405 + bool validate, int level,
42406 + t_Handle h_FmTree)
42407 +{
42408 +
42409 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42410 + t_Error err = E_OK;
42411 +
42412 + UNUSED(level);
42413 +
42414 + switch (p_Manip->opcode)
42415 + {
42416 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42417 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42418 + RETURN_ERROR(
42419 + MAJOR,
42420 + E_INVALID_STATE,
42421 + ("modify node with this type of manipulation is not suppported"));
42422 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42423 +
42424 + if (p_Manip->h_Frag)
42425 + {
42426 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42427 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42428 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42429 + RETURN_ERROR(
42430 + MAJOR,
42431 + E_INVALID_STATE,
42432 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42433 + }
42434 + break;
42435 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42436 + if (p_Manip->h_Frag)
42437 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42438 + break;
42439 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42440 + default:
42441 + return E_OK;
42442 + }
42443 +
42444 + return err;
42445 +}
42446 +
42447 +/*****************************************************************************/
42448 +/* Inter-module API routines */
42449 +/*****************************************************************************/
42450 +
42451 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42452 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42453 + bool validate, int level, t_Handle h_FmTree,
42454 + bool modify)
42455 +{
42456 + t_Error err;
42457 +
42458 + if (!modify)
42459 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42460 + h_Ad, validate, level, h_FmTree);
42461 + else
42462 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42463 +
42464 + return err;
42465 +}
42466 +
42467 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42468 +{
42469 +
42470 + uint32_t intFlags;
42471 +
42472 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42473 + if (add)
42474 + ((t_FmPcdManip *)h_Manip)->owner++;
42475 + else
42476 + {
42477 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42478 + ((t_FmPcdManip *)h_Manip)->owner--;
42479 + }
42480 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42481 +}
42482 +
42483 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42484 +{
42485 + ASSERT_COND(h_Manip);
42486 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42487 +}
42488 +
42489 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42490 +{
42491 + ASSERT_COND(h_Manip);
42492 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42493 +}
42494 +
42495 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42496 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42497 + uint32_t *requiredAction)
42498 +{
42499 + t_FmPcdManip *p_Manip;
42500 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42501 + t_Error err = E_OK;
42502 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42503 + bool pointFromCc = TRUE;
42504 +
42505 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42506 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42507 + E_NULL_POINTER);
42508 +
42509 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42510 + *requiredAction = 0;
42511 +
42512 + while (p_Manip)
42513 + {
42514 + switch (p_Manip->opcode)
42515 + {
42516 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42517 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42518 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42519 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42520 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42521 + p_Manip->cnia = TRUE;
42522 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42523 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42524 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42525 + p_Manip->ownerTmp++;
42526 + break;
42527 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42528 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42529 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42530 + RETURN_ERROR(
42531 + MAJOR,
42532 + E_INVALID_STATE,
42533 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42534 + p_Manip->ownerTmp++;
42535 + break;
42536 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42537 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42538 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42539 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42540 + 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"));
42541 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42542 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42543 + if (err)
42544 + RETURN_ERROR(MAJOR, err, NO_MSG);
42545 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42546 + break;
42547 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42548 + case (HMAN_OC_IP_FRAGMENTATION):
42549 + case (HMAN_OC_IP_REASSEMBLY):
42550 +#if (DPAA_VERSION >= 11)
42551 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42552 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42553 +#endif /* (DPAA_VERSION >= 11) */
42554 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42555 + RETURN_ERROR(
42556 + MAJOR,
42557 + E_INVALID_STATE,
42558 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42559 + p_Manip->ownerTmp++;
42560 + break;
42561 + case (HMAN_OC_IPSEC_MANIP):
42562 +#if (DPAA_VERSION >= 11)
42563 + case (HMAN_OC_CAPWAP_MANIP):
42564 +#endif /* (DPAA_VERSION >= 11) */
42565 + p_Manip->ownerTmp++;
42566 + break;
42567 + case (HMAN_OC):
42568 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42569 + && MANIP_IS_CASCADED(p_Manip))
42570 + RETURN_ERROR(
42571 + MINOR,
42572 + E_INVALID_STATE,
42573 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42574 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42575 + RETURN_ERROR(
42576 + MAJOR,
42577 + E_INVALID_STATE,
42578 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42579 + break;
42580 + default:
42581 + RETURN_ERROR(
42582 + MAJOR, E_INVALID_STATE,
42583 + ("invalid type of header manipulation for this state"));
42584 + }
42585 + p_Manip = p_Manip->h_NextManip;
42586 + pointFromCc = FALSE;
42587 + }
42588 + return E_OK;
42589 +}
42590 +
42591 +
42592 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42593 + t_Handle h_FmPcdCcNode)
42594 +{
42595 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42596 + t_Error err = E_OK;
42597 +
42598 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42599 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42600 +
42601 + switch (p_Manip->opcode)
42602 + {
42603 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42604 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42605 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42606 + RETURN_ERROR(
42607 + MAJOR,
42608 + E_INVALID_VALUE,
42609 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42610 + break;
42611 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42612 + if (p_Manip->h_Frag)
42613 + {
42614 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42615 + RETURN_ERROR(
42616 + MAJOR,
42617 + E_INVALID_VALUE,
42618 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42619 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42620 + if (err)
42621 + RETURN_ERROR(MAJOR, err, NO_MSG);
42622 + }
42623 + break;
42624 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42625 + default:
42626 + break;
42627 + }
42628 +
42629 + return err;
42630 +}
42631 +
42632 +void FmPcdManipUpdateAdResultForCc(
42633 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42634 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42635 +{
42636 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42637 +
42638 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42639 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42640 +
42641 + ASSERT_COND(p_Manip);
42642 + ASSERT_COND(p_CcNextEngineParams);
42643 + ASSERT_COND(p_Ad);
42644 + ASSERT_COND(p_AdNewPtr);
42645 +
42646 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42647 +
42648 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42649 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42650 + switch (p_Manip->opcode)
42651 + {
42652 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42653 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42654 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42655 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42656 + *p_AdNewPtr = p_Manip->h_Ad;
42657 + break;
42658 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42659 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42660 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42661 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42662 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42663 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42664 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42665 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42666 + *p_AdNewPtr = NULL;
42667 + break;
42668 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42669 + case (HMAN_OC_IPSEC_MANIP):
42670 +#if (DPAA_VERSION >= 11)
42671 + case (HMAN_OC_CAPWAP_MANIP):
42672 +#endif /* (DPAA_VERSION >= 11) */
42673 + *p_AdNewPtr = p_Manip->h_Ad;
42674 + break;
42675 + case (HMAN_OC_IP_FRAGMENTATION):
42676 +#if (DPAA_VERSION >= 11)
42677 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42678 +#endif /* (DPAA_VERSION >= 11) */
42679 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42680 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42681 + {
42682 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42683 + sizeof(t_AdOfTypeContLookup));
42684 +#if (DPAA_VERSION >= 11)
42685 + WRITE_UINT32(
42686 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42687 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42688 +#endif /* (DPAA_VERSION >= 11) */
42689 + *p_AdNewPtr = NULL;
42690 + }
42691 + else
42692 + *p_AdNewPtr = p_Manip->h_Ad;
42693 + break;
42694 + case (HMAN_OC_IP_REASSEMBLY):
42695 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42696 + {
42697 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42698 + {
42699 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42700 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42701 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42702 + }
42703 + else
42704 + {
42705 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42706 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42707 + }
42708 + }
42709 + else
42710 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42711 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42712 + sizeof(t_AdOfTypeContLookup));
42713 + *p_AdNewPtr = NULL;
42714 + break;
42715 +#if (DPAA_VERSION >= 11)
42716 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42717 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42718 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42719 + sizeof(t_AdOfTypeContLookup));
42720 + *p_AdNewPtr = NULL;
42721 + break;
42722 +#endif /* (DPAA_VERSION >= 11) */
42723 + case (HMAN_OC):
42724 + /* Allocate and initialize HMTD */
42725 + *p_AdNewPtr = p_Manip->h_Ad;
42726 + break;
42727 + default:
42728 + break;
42729 + }
42730 +}
42731 +
42732 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42733 + t_Handle *p_AdNewPtr,
42734 + uint32_t adTableOffset)
42735 +{
42736 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42737 +
42738 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42739 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42740 + ASSERT_COND(p_Manip);
42741 +
42742 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42743 +
42744 + switch (p_Manip->opcode)
42745 + {
42746 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42747 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42748 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42749 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42750 + WRITE_UINT32(
42751 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42752 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42753 + WRITE_UINT32(
42754 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42755 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42756 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42757 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42758 + WRITE_UINT32(
42759 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42760 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42761 + *p_AdNewPtr = NULL;
42762 + break;
42763 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42764 + case (HMAN_OC):
42765 + /* Initialize HMTD within the match table*/
42766 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42767 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42768 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42769 + /* update NADEN to be "1"*/
42770 + WRITE_UINT16(
42771 + ((t_Hmtd *)p_Ad)->cfg,
42772 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42773 + /* update next action descriptor */
42774 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42775 + (uint16_t)(adTableOffset >> 4));
42776 + /* mark that Manip's HMTD is not used */
42777 + *p_AdNewPtr = NULL;
42778 + break;
42779 +
42780 + default:
42781 + break;
42782 + }
42783 +}
42784 +
42785 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42786 + t_Handle h_CcTree, t_Handle h_Manip,
42787 + bool isIpv4, uint8_t groupId)
42788 +{
42789 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42790 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42791 + t_Handle h_Scheme;
42792 +
42793 + ASSERT_COND(p_FmPcd);
42794 + ASSERT_COND(h_NetEnv);
42795 + ASSERT_COND(p_Manip);
42796 +
42797 + /* scheme was already build, no need to check for IPv6 */
42798 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42799 + return E_OK;
42800 +
42801 + if (isIpv4) {
42802 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42803 + if (h_Scheme) {
42804 + /* scheme was found */
42805 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42806 + return E_OK;
42807 + }
42808 + } else {
42809 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42810 + if (h_Scheme) {
42811 + /* scheme was found */
42812 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42813 + return E_OK;
42814 + }
42815 + }
42816 +
42817 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42818 + if (!p_SchemeParams)
42819 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42820 + ("Memory allocation failed for scheme"));
42821 +
42822 + /* Configures the IPv4 or IPv6 scheme*/
42823 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42824 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42825 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42826 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42827 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42828 + p_SchemeParams->schemeCounter.update = TRUE;
42829 +#if (DPAA_VERSION >= 11)
42830 + p_SchemeParams->alwaysDirect = TRUE;
42831 + p_SchemeParams->bypassFqidGeneration = TRUE;
42832 +#else
42833 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42834 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42835 +#endif /* (DPAA_VERSION >= 11) */
42836 +
42837 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42838 +
42839 + /* Sets the new scheme */
42840 + if (isIpv4)
42841 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42842 + p_FmPcd, p_SchemeParams);
42843 + else
42844 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
42845 + p_FmPcd, p_SchemeParams);
42846 +
42847 + XX_Free(p_SchemeParams);
42848 +
42849 + return E_OK;
42850 +}
42851 +
42852 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
42853 +{
42854 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42855 +
42856 + ASSERT_COND(p_Manip);
42857 +
42858 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
42859 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
42860 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
42861 +
42862 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
42863 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
42864 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
42865 +
42866 + return E_OK;
42867 +}
42868 +
42869 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
42870 +{
42871 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42872 +
42873 + ASSERT_COND(p_Manip);
42874 +
42875 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
42876 +}
42877 +
42878 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42879 + t_Handle h_CcTree, t_Handle h_Manip,
42880 + uint8_t groupId)
42881 +{
42882 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42883 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42884 +
42885 + ASSERT_COND(p_FmPcd);
42886 + ASSERT_COND(h_NetEnv);
42887 + ASSERT_COND(p_Manip);
42888 +
42889 + /* scheme was already build, no need to check for IPv6 */
42890 + if (p_Manip->reassmParams.capwap.h_Scheme)
42891 + return E_OK;
42892 +
42893 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42894 + if (!p_SchemeParams)
42895 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42896 + ("Memory allocation failed for scheme"));
42897 +
42898 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42899 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42900 + p_SchemeParams->id.relativeSchemeId =
42901 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
42902 + p_SchemeParams->schemeCounter.update = TRUE;
42903 + p_SchemeParams->bypassFqidGeneration = TRUE;
42904 +
42905 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
42906 +
42907 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
42908 + p_SchemeParams);
42909 +
42910 + XX_Free(p_SchemeParams);
42911 +
42912 + return E_OK;
42913 +}
42914 +
42915 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
42916 +{
42917 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42918 +
42919 + ASSERT_COND(p_Manip);
42920 +
42921 + if (p_Manip->reassmParams.capwap.h_Scheme)
42922 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
42923 +
42924 + return E_OK;
42925 +}
42926 +
42927 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42928 +t_Handle FmPcdManipApplSpecificBuild(void)
42929 +{
42930 + t_FmPcdManip *p_Manip;
42931 +
42932 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42933 + if (!p_Manip)
42934 + {
42935 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42936 + return NULL;
42937 + }
42938 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42939 +
42940 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42941 + p_Manip->muramAllocate = FALSE;
42942 +
42943 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42944 + if (!p_Manip->h_Ad)
42945 + {
42946 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42947 + XX_Free(p_Manip);
42948 + return NULL;
42949 + }
42950 +
42951 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42952 +
42953 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
42954 + /*Application specific = type of flowId index, move internal frame header from data to IC,
42955 + SEC errors check*/
42956 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
42957 + {
42958 + XX_Free(p_Manip->h_Ad);
42959 + XX_Free(p_Manip);
42960 + return NULL;
42961 + }
42962 + return p_Manip;
42963 +}
42964 +
42965 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
42966 +{
42967 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42968 + ASSERT_COND(h_Manip);
42969 +
42970 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
42971 +}
42972 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42973 +/*********************** End of inter-module routines ************************/
42974 +
42975 +/****************************************/
42976 +/* API Init unit functions */
42977 +/****************************************/
42978 +
42979 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
42980 + t_FmPcdManipParams *p_ManipParams)
42981 +{
42982 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42983 + t_FmPcdManip *p_Manip;
42984 + t_Error err;
42985 +
42986 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
42987 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
42988 +
42989 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
42990 + if (!p_Manip)
42991 + return NULL;
42992 +
42993 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
42994 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
42995 + || (p_Manip->opcode == HMAN_OC)
42996 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
42997 +#if (DPAA_VERSION >= 11)
42998 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
42999 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
43000 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
43001 +#endif /* (DPAA_VERSION >= 11) */
43002 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
43003 + {
43004 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
43005 + XX_Free(p_Manip);
43006 + return NULL;
43007 + }
43008 + p_Manip->h_Spinlock = XX_InitSpinlock();
43009 + if (!p_Manip->h_Spinlock)
43010 + {
43011 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43012 + ReleaseManipHandler(p_Manip, p_FmPcd);
43013 + XX_Free(p_Manip);
43014 + return NULL;
43015 + }INIT_LIST(&p_Manip->nodesLst);
43016 +
43017 + switch (p_Manip->opcode)
43018 + {
43019 + case (HMAN_OC_IP_REASSEMBLY):
43020 + /* IpReassembly */
43021 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
43022 + break;
43023 + case (HMAN_OC_IP_FRAGMENTATION):
43024 + /* IpFragmentation */
43025 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
43026 + if (err)
43027 + break;
43028 + err = IPManip(p_Manip);
43029 + break;
43030 + case (HMAN_OC_IPSEC_MANIP):
43031 + err = IPSecManip(p_ManipParams, p_Manip);
43032 + break;
43033 +#if (DPAA_VERSION >= 11)
43034 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43035 + /* CapwapReassembly */
43036 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
43037 + break;
43038 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43039 + /* CapwapFragmentation */
43040 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
43041 + p_Manip);
43042 + break;
43043 + case (HMAN_OC_CAPWAP_MANIP):
43044 + err = CapwapManip(p_ManipParams, p_Manip);
43045 + break;
43046 +#endif /* (DPAA_VERSION >= 11) */
43047 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43048 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
43049 + /* HmanType1 */
43050 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
43051 + break;
43052 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43053 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
43054 + p_Manip,
43055 + p_FmPcd,
43056 + p_ManipParams->fragOrReasmParams.sgBpid);
43057 + if (err)
43058 + {
43059 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43060 + ReleaseManipHandler(p_Manip, p_FmPcd);
43061 + XX_Free(p_Manip);
43062 + return NULL;
43063 + }
43064 + if (p_Manip->insrt)
43065 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
43066 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43067 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
43068 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
43069 + break;
43070 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43071 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
43072 + p_Manip,
43073 + p_FmPcd,
43074 + p_ManipParams->fragOrReasmParams.sgBpid);
43075 + if (err)
43076 + {
43077 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43078 + ReleaseManipHandler(p_Manip, p_FmPcd);
43079 + XX_Free(p_Manip);
43080 + return NULL;
43081 + }
43082 + if (p_Manip->rmv)
43083 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
43084 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43085 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
43086 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
43087 + break;
43088 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43089 + /*Application Specific type 1*/
43090 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
43091 + break;
43092 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43093 + case (HMAN_OC):
43094 + /* New Manip */
43095 + err = CreateManipActionNew(p_Manip, p_ManipParams);
43096 + break;
43097 + default:
43098 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43099 + ReleaseManipHandler(p_Manip, p_FmPcd);
43100 + XX_Free(p_Manip);
43101 + return NULL;
43102 + }
43103 +
43104 + if (err)
43105 + {
43106 + REPORT_ERROR(MAJOR, err, NO_MSG);
43107 + ReleaseManipHandler(p_Manip, p_FmPcd);
43108 + XX_Free(p_Manip);
43109 + return NULL;
43110 + }
43111 +
43112 + if (p_ManipParams->h_NextManip)
43113 + {
43114 + /* in the check routine we've verified that h_NextManip has no owners
43115 + * and that only supported types are allowed. */
43116 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
43117 + /* save a "prev" pointer in h_NextManip */
43118 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
43119 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
43120 + }
43121 +
43122 + return p_Manip;
43123 +}
43124 +
43125 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
43126 + t_FmPcdManipParams *p_ManipParams)
43127 +{
43128 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
43129 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
43130 + t_Error err;
43131 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
43132 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
43133 + t_CcNodeInformation *p_CcNodeInfo;
43134 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43135 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43136 +
43137 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
43138 +
43139 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
43140 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
43141 + RETURN_ERROR(
43142 + MINOR,
43143 + E_NOT_SUPPORTED,
43144 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
43145 +
43146 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
43147 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
43148 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
43149 + sizeof(p_Manip->manipParams));
43150 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
43151 +
43152 + /* The replacement of the HdrManip depends on the node type.*/
43153 + /*
43154 + * (1) If this is an independent node, all its owners should be updated.
43155 + *
43156 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
43157 + * it has a "next" and it has a "cascaded" indication), the next
43158 + * node remains unchanged, and the behavior is as in (1).
43159 + *
43160 + * (3) If it is not the head, but a part of a cascaded chain, in can be
43161 + * also replaced as a regular node with just one owner.
43162 + *
43163 + * (4) If it is a part of a chain implemented as a unified table, the
43164 + * whole table is replaced and the owners of the head node must be updated.
43165 + *
43166 + */
43167 + /* lock shadow */
43168 + if (!p_FmPcd->p_CcShadow)
43169 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
43170 +
43171 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
43172 + return ERROR_CODE(E_BUSY);
43173 +
43174 + /* this routine creates a new manip action in the CC Shadow. */
43175 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
43176 + if (err)
43177 + RETURN_ERROR(MINOR, err, NO_MSG);
43178 +
43179 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
43180 + * replace only HMTD and no lcok is required. Otherwise
43181 + * lock the whole PCD
43182 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
43183 + if (!FmPcdLockTryLockAll(p_FmPcd))
43184 + {
43185 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
43186 + return ERROR_CODE(E_BUSY);
43187 + }
43188 +
43189 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
43190 +
43191 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
43192 + e_MANIP_HANDLER_TABLE_OWNER);
43193 + ASSERT_COND(p_FirstManip);
43194 +
43195 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
43196 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43197 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
43198 +
43199 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43200 + ASSERT_COND(p_Hmtd);
43201 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43202 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43203 +
43204 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43205 + {
43206 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43207 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43208 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43209 + }
43210 +
43211 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43212 + ASSERT_COND(p_WholeHmct);
43213 +
43214 + /* re-build the HMCT n the original location */
43215 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43216 + if (err)
43217 + {
43218 + RELEASE_LOCK(p_FmPcd->shadowLock);
43219 + RETURN_ERROR(MINOR, err, NO_MSG);
43220 + }
43221 +
43222 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43223 + ASSERT_COND(p_Hmtd);
43224 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43225 + ((t_FmPcd*)p_Manip->h_FmPcd));
43226 +
43227 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43228 + * For each p_Hmct (from list+fixed):
43229 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43230 + {
43231 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43232 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43233 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43234 + }
43235 +
43236 +
43237 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43238 +
43239 + FmPcdLockUnlockAll(p_FmPcd);
43240 +
43241 + /* unlock shadow */
43242 + RELEASE_LOCK(p_FmPcd->shadowLock);
43243 +
43244 + return E_OK;
43245 +}
43246 +
43247 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43248 +{
43249 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43250 +
43251 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43252 +
43253 + if (p_Manip->owner)
43254 + RETURN_ERROR(
43255 + MAJOR,
43256 + E_INVALID_STATE,
43257 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43258 +
43259 + if (p_Manip->h_NextManip)
43260 + {
43261 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43262 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43263 + }
43264 +
43265 + if (p_Manip->p_Hmct
43266 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43267 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43268 + p_Manip->p_Hmct);
43269 +
43270 + if (p_Manip->h_Spinlock)
43271 + {
43272 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43273 + p_Manip->h_Spinlock = NULL;
43274 + }
43275 +
43276 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43277 +
43278 + XX_Free(h_ManipNode);
43279 +
43280 + return E_OK;
43281 +}
43282 +
43283 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43284 + t_FmPcdManipStats *p_FmPcdManipStats)
43285 +{
43286 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43287 +
43288 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43289 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43290 +
43291 + switch (p_Manip->opcode)
43292 + {
43293 + case (HMAN_OC_IP_REASSEMBLY):
43294 + return IpReassemblyStats(p_Manip,
43295 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43296 + case (HMAN_OC_IP_FRAGMENTATION):
43297 + return IpFragmentationStats(p_Manip,
43298 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43299 +#if (DPAA_VERSION >= 11)
43300 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43301 + return CapwapReassemblyStats(
43302 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43303 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43304 + return CapwapFragmentationStats(
43305 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43306 +#endif /* (DPAA_VERSION >= 11) */
43307 + default:
43308 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43309 + ("no statistics to this type of manip"));
43310 + }
43311 +
43312 + return E_OK;
43313 +}
43314 +
43315 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43316 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43317 +{
43318 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43319 + t_FmPcdManip *p_Manip;
43320 + t_Error err;
43321 +
43322 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43323 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43324 +
43325 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43326 + if (!p_Manip)
43327 + return NULL;
43328 +
43329 + switch (p_Manip->opcode)
43330 + {
43331 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43332 + /* Indexed statistics */
43333 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43334 + break;
43335 + default:
43336 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43337 + ReleaseManipHandler(p_Manip, p_FmPcd);
43338 + XX_Free(p_Manip);
43339 + return NULL;
43340 + }
43341 +
43342 + if (err)
43343 + {
43344 + REPORT_ERROR(MAJOR, err, NO_MSG);
43345 + ReleaseManipHandler(p_Manip, p_FmPcd);
43346 + XX_Free(p_Manip);
43347 + return NULL;
43348 + }
43349 +
43350 + return p_Manip;
43351 +}
43352 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43353 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43354 new file mode 100644
43355 index 00000000..853bb834
43356 --- /dev/null
43357 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43358 @@ -0,0 +1,555 @@
43359 +/*
43360 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43361 + *
43362 + * Redistribution and use in source and binary forms, with or without
43363 + * modification, are permitted provided that the following conditions are met:
43364 + * * Redistributions of source code must retain the above copyright
43365 + * notice, this list of conditions and the following disclaimer.
43366 + * * Redistributions in binary form must reproduce the above copyright
43367 + * notice, this list of conditions and the following disclaimer in the
43368 + * documentation and/or other materials provided with the distribution.
43369 + * * Neither the name of Freescale Semiconductor nor the
43370 + * names of its contributors may be used to endorse or promote products
43371 + * derived from this software without specific prior written permission.
43372 + *
43373 + *
43374 + * ALTERNATIVELY, this software may be distributed under the terms of the
43375 + * GNU General Public License ("GPL") as published by the Free Software
43376 + * Foundation, either version 2 of that License or (at your option) any
43377 + * later version.
43378 + *
43379 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43380 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43381 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43382 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43383 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43384 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43385 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43386 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43387 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43388 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43389 + */
43390 +
43391 +
43392 +/******************************************************************************
43393 + @File fm_manip.h
43394 +
43395 + @Description FM PCD manip...
43396 +*//***************************************************************************/
43397 +#ifndef __FM_MANIP_H
43398 +#define __FM_MANIP_H
43399 +
43400 +#include "std_ext.h"
43401 +#include "error_ext.h"
43402 +#include "list_ext.h"
43403 +
43404 +#include "fm_cc.h"
43405 +
43406 +
43407 +/***********************************************************************/
43408 +/* Header manipulations defines */
43409 +/***********************************************************************/
43410 +
43411 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43412 +
43413 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43414 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43415 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43416 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43417 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43418 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43419 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43420 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43421 +#else
43422 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43423 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43424 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43425 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43426 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43427 +#define HMAN_OC_IP_MANIP 0x34
43428 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43429 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43430 +#define HMAN_OC_IPSEC_MANIP 0xF4
43431 +#define HMAN_OC 0x35
43432 +
43433 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43434 +#define HMAN_RMV_HDR 0x80000000
43435 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43436 +
43437 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43438 +#define UDP_CHECKSUM_FIELD_SIZE 2
43439 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43440 +
43441 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43442 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43443 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43444 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43445 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43446 +
43447 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43448 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43449 +
43450 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43451 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43452 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43453 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43454 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43455 +
43456 +
43457 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43458 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43459 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43460 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43461 +
43462 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43463 +
43464 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43465 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43466 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43467 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43468 +
43469 +#if (DPAA_VERSION >= 11)
43470 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43471 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43472 +
43473 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43474 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43475 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43476 +
43477 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43478 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43479 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43480 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43481 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43482 +#endif /* (DPAA_VERSION >= 11) */
43483 +
43484 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43485 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43486 +
43487 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43488 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43489 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43490 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43491 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43492 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43493 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43494 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43495 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43496 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43497 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43498 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43499 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43500 +
43501 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43502 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43503 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43504 +
43505 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43506 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43507 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43508 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43509 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43510 +
43511 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43512 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43513 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43514 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43515 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43516 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43517 +
43518 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43519 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43520 +
43521 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43522 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43523 +
43524 +#define e_FM_MANIP_IP_INDX 1
43525 +
43526 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43527 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43528 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43529 +#define HMCD_OPCODE_L2_RMV 0x08
43530 +#define HMCD_OPCODE_L2_INSRT 0x09
43531 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43532 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43533 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43534 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43535 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43536 +#define HMCD_OPCODE_REPLACE_IP 0x12
43537 +#define HMCD_OPCODE_RMV_TILL 0x15
43538 +#define HMCD_OPCODE_UDP_INSRT 0x16
43539 +#define HMCD_OPCODE_IP_INSRT 0x17
43540 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43541 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43542 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43543 +
43544 +#define HMCD_LAST 0x00800000
43545 +
43546 +#define HMCD_DSCP_VALUES 64
43547 +
43548 +#define HMCD_BASIC_SIZE 4
43549 +#define HMCD_PTR_SIZE 4
43550 +#define HMCD_PARAM_SIZE 4
43551 +#define HMCD_IPV4_ADDR_SIZE 4
43552 +#define HMCD_IPV6_ADDR_SIZE 0x10
43553 +#define HMCD_L4_HDR_SIZE 8
43554 +
43555 +#define HMCD_CAPWAP_INSRT 0x00010000
43556 +#define HMCD_INSRT_UDP_LITE 0x00010000
43557 +#define HMCD_IP_ID_MASK 0x0000FFFF
43558 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43559 +#define HMCD_IP_SIZE_SHIFT 8
43560 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43561 +#define HMCD_IP_OR_QOS 0x00010000
43562 +#define HMCD_IP_L4_CS_CALC 0x00040000
43563 +#define HMCD_IP_DF_MODE 0x00400000
43564 +
43565 +
43566 +#define HMCD_OC_SHIFT 24
43567 +
43568 +#define HMCD_RMV_OFFSET_SHIFT 0
43569 +#define HMCD_RMV_SIZE_SHIFT 8
43570 +
43571 +#define HMCD_INSRT_OFFSET_SHIFT 0
43572 +#define HMCD_INSRT_SIZE_SHIFT 8
43573 +
43574 +#define HMTD_CFG_TYPE 0x4000
43575 +#define HMTD_CFG_EXT_HMCT 0x0080
43576 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43577 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43578 +
43579 +#define HMCD_RMV_L2_ETHERNET 0
43580 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43581 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43582 +#define HMCD_RMV_L2_MPLS 3
43583 +#define HMCD_RMV_L2_PPPOE 4
43584 +
43585 +#define HMCD_INSRT_L2_MPLS 0
43586 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43587 +#define HMCD_INSRT_L2_PPPOE 2
43588 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43589 +
43590 +#define HMCD_L2_MODE_SHIFT 16
43591 +
43592 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43593 +#define HMCD_VLAN_PRI_UPDATE 0
43594 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43595 +
43596 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43597 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43598 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43599 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43600 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43601 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43602 +
43603 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43604 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43605 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43606 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43607 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43608 +
43609 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43610 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43611 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43612 +
43613 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43614 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43615 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43616 +#define HMCD_IP_REPLACE_ID 0x00400000
43617 +
43618 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43619 +
43620 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43621 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43622 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43623 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43624 +
43625 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43626 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43627 +
43628 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43629 +
43630 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43631 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43632 +
43633 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43634 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43635 +
43636 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43637 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43638 +
43639 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43640 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43641 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43642 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43643 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43644 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43645 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43646 +#define MANIP_FREE_HMTD(h_Manip) \
43647 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43648 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43649 + else \
43650 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43651 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43652 + }
43653 +/* position regarding Manip SW structure */
43654 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43655 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43656 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43657 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43658 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43659 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43660 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43661 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43662 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43663 +
43664 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43665 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43666 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43667 +
43668 +typedef enum e_ManipUnifiedPosition {
43669 + e_MANIP_UNIFIED_NONE = 0,
43670 + e_MANIP_UNIFIED_FIRST,
43671 + e_MANIP_UNIFIED_MID,
43672 + e_MANIP_UNIFIED_LAST
43673 +} e_ManipUnifiedPosition;
43674 +
43675 +typedef enum e_ManipInfo {
43676 + e_MANIP_HMTD,
43677 + e_MANIP_HMCT,
43678 + e_MANIP_HANDLER_TABLE_OWNER
43679 +}e_ManipInfo;
43680 +/***********************************************************************/
43681 +/* Memory map */
43682 +/***********************************************************************/
43683 +#if defined(__MWERKS__) && !defined(__GNUC__)
43684 +#pragma pack(push,1)
43685 +#endif /* defined(__MWERKS__) && ... */
43686 +
43687 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43688 +typedef struct t_CapwapReasmPram {
43689 + volatile uint32_t mode;
43690 + volatile uint32_t autoLearnHashTblPtr;
43691 + volatile uint32_t intStatsTblPtr;
43692 + volatile uint32_t reasmFrmDescPoolTblPtr;
43693 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43694 + volatile uint32_t timeOutTblPtr;
43695 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43696 + volatile uint32_t risc23SetIndexes;
43697 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43698 + volatile uint32_t extendedStatsTblPtr;
43699 + volatile uint32_t expirationDelay;
43700 + volatile uint32_t totalProcessedFragCounter;
43701 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43702 + volatile uint32_t totalDuplicatedFragCounter;
43703 + volatile uint32_t totalMalformdFragCounter;
43704 + volatile uint32_t totalTimeOutCounter;
43705 + volatile uint32_t totalSetBusyCounter;
43706 + volatile uint32_t totalRfdPoolBusyCounter;
43707 + volatile uint32_t totalDiscardedFragsCounter;
43708 + volatile uint32_t totalMoreThan16FramesCounter;
43709 + volatile uint32_t internalBufferBusy;
43710 + volatile uint32_t externalBufferBusy;
43711 + volatile uint32_t reserved1[4];
43712 +} t_CapwapReasmPram;
43713 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43714 +
43715 +typedef _Packed struct t_ReassTbl {
43716 + volatile uint16_t waysNumAndSetSize;
43717 + volatile uint16_t autoLearnHashKeyMask;
43718 + volatile uint32_t reassCommonPrmTblPtr;
43719 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43720 + volatile uint32_t autoLearnHashTblPtrLow;
43721 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43722 + volatile uint32_t autoLearnSetLockTblPtrLow;
43723 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43724 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43725 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43726 + volatile uint32_t totalValidFragmentCounter;
43727 + volatile uint32_t totalProcessedFragCounter;
43728 + volatile uint32_t totalMalformdFragCounter;
43729 + volatile uint32_t totalSetBusyCounter;
43730 + volatile uint32_t totalDiscardedFragsCounter;
43731 + volatile uint32_t totalMoreThan16FramesCounter;
43732 + volatile uint32_t reserved2[2];
43733 +} _PackedType t_ReassTbl;
43734 +
43735 +typedef struct t_ReassCommonTbl {
43736 + volatile uint32_t timeoutModeAndFqid;
43737 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43738 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43739 + volatile uint32_t reassFrmDescPoolPtrLow;
43740 + volatile uint32_t timeOutTblPtr;
43741 + volatile uint32_t expirationDelay;
43742 + volatile uint32_t internalBufferManagement;
43743 + volatile uint32_t reserved2;
43744 + volatile uint32_t totalTimeOutCounter;
43745 + volatile uint32_t totalRfdPoolBusyCounter;
43746 + volatile uint32_t totalInternalBufferBusy;
43747 + volatile uint32_t totalExternalBufferBusy;
43748 + volatile uint32_t totalSgFragmentCounter;
43749 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43750 + volatile uint32_t totalNCSPCounter;
43751 + volatile uint32_t discardMask;
43752 +} t_ReassCommonTbl;
43753 +
43754 +typedef _Packed struct t_Hmtd {
43755 + volatile uint16_t cfg;
43756 + volatile uint8_t eliodnOffset;
43757 + volatile uint8_t extHmcdBasePtrHi;
43758 + volatile uint32_t hmcdBasePtr;
43759 + volatile uint16_t nextAdIdx;
43760 + volatile uint8_t res1;
43761 + volatile uint8_t opCode;
43762 + volatile uint32_t res2;
43763 +} _PackedType t_Hmtd;
43764 +
43765 +#if defined(__MWERKS__) && !defined(__GNUC__)
43766 +#pragma pack(pop)
43767 +#endif /* defined(__MWERKS__) && ... */
43768 +
43769 +
43770 +/***********************************************************************/
43771 +/* Driver's internal structures */
43772 +/***********************************************************************/
43773 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43774 +typedef struct
43775 +{
43776 + t_Handle p_AutoLearnHashTbl;
43777 + t_Handle p_ReassmFrmDescrPoolTbl;
43778 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43779 + t_Handle p_TimeOutTbl;
43780 + uint16_t maxNumFramesInProcess;
43781 + uint8_t numOfTasks;
43782 + //uint8_t poolId;
43783 + uint8_t prOffset;
43784 + uint16_t dataOffset;
43785 + uint8_t sgBpid;
43786 + uint8_t hwPortId;
43787 + uint32_t fqidForTimeOutFrames;
43788 + uint32_t timeoutRoutineRequestTime;
43789 + uint32_t bitFor1Micro;
43790 +} t_CapwapFragParams;
43791 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43792 +
43793 +typedef struct
43794 +{
43795 + t_AdOfTypeContLookup *p_Frag;
43796 +#if (DPAA_VERSION == 10)
43797 + uint8_t scratchBpid;
43798 +#endif /* (DPAA_VERSION == 10) */
43799 +} t_FragParams;
43800 +
43801 +typedef struct t_ReassmParams
43802 +{
43803 + e_NetHeaderType hdr; /* Header selection */
43804 + t_ReassCommonTbl *p_ReassCommonTbl;
43805 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43806 + uintptr_t reassFrmDescrPoolTblAddr;
43807 + uintptr_t timeOutTblAddr;
43808 + uintptr_t internalBufferPoolManagementIndexAddr;
43809 + uintptr_t internalBufferPoolAddr;
43810 + uint32_t maxNumFramesInProcess;
43811 + uint8_t sgBpid;
43812 + uint8_t dataMemId;
43813 + uint16_t dataLiodnOffset;
43814 + uint32_t fqidForTimeOutFrames;
43815 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43816 + uint32_t timeoutThresholdForReassmProcess;
43817 + union {
43818 + struct {
43819 + t_Handle h_Ipv4Ad;
43820 + t_Handle h_Ipv6Ad;
43821 + bool ipv6Assigned;
43822 + t_ReassTbl *p_Ipv4ReassTbl;
43823 + t_ReassTbl *p_Ipv6ReassTbl;
43824 + uintptr_t ipv4AutoLearnHashTblAddr;
43825 + uintptr_t ipv6AutoLearnHashTblAddr;
43826 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43827 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43828 + uint16_t minFragSize[2];
43829 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43830 + uint8_t relativeSchemeId[2];
43831 + t_Handle h_Ipv4Scheme;
43832 + t_Handle h_Ipv6Scheme;
43833 + uint32_t nonConsistentSpFqid;
43834 + } ip;
43835 + struct {
43836 + t_Handle h_Ad;
43837 + t_ReassTbl *p_ReassTbl;
43838 + uintptr_t autoLearnHashTblAddr;
43839 + uintptr_t autoLearnSetLockTblAddr;
43840 + uint16_t maxRessembledsSize;
43841 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43842 + uint8_t relativeSchemeId;
43843 + t_Handle h_Scheme;
43844 + } capwap;
43845 + };
43846 +} t_ReassmParams;
43847 +
43848 +typedef struct{
43849 + e_FmPcdManipType type;
43850 + t_FmPcdManipParams manipParams;
43851 + bool muramAllocate;
43852 + t_Handle h_Ad;
43853 + uint32_t opcode;
43854 + bool rmv;
43855 + bool insrt;
43856 + t_Handle h_NextManip;
43857 + t_Handle h_PrevManip;
43858 + e_FmPcdManipType nextManipType;
43859 + /* HdrManip parameters*/
43860 + uint8_t *p_Hmct;
43861 + uint8_t *p_Data;
43862 + bool dontParseAfterManip;
43863 + bool fieldUpdate;
43864 + bool custom;
43865 + uint16_t tableSize;
43866 + uint8_t dataSize;
43867 + bool cascaded;
43868 + e_ManipUnifiedPosition unifiedPosition;
43869 + /* end HdrManip */
43870 + uint8_t *p_Template;
43871 + uint16_t owner;
43872 + uint32_t updateParams;
43873 + uint32_t shadowUpdateParams;
43874 + bool frag;
43875 + bool reassm;
43876 + uint16_t sizeForFragmentation;
43877 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43878 + t_Handle h_Frag;
43879 + t_CapwapFragParams capwapFragParams;
43880 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43881 + union {
43882 + t_ReassmParams reassmParams;
43883 + t_FragParams fragParams;
43884 + };
43885 + uint8_t icOffset;
43886 + uint16_t ownerTmp;
43887 + bool cnia;
43888 + t_Handle p_StatsTbl;
43889 + t_Handle h_FmPcd;
43890 + t_List nodesLst;
43891 + t_Handle h_Spinlock;
43892 +} t_FmPcdManip;
43893 +
43894 +typedef struct t_FmPcdCcSavedManipParams
43895 +{
43896 + union
43897 + {
43898 + struct
43899 + {
43900 + uint16_t dataOffset;
43901 + //uint8_t poolId;
43902 + }capwapParams;
43903 + struct
43904 + {
43905 + uint16_t dataOffset;
43906 + uint8_t poolId;
43907 + }ipParams;
43908 + };
43909 +
43910 +} t_FmPcdCcSavedManipParams;
43911 +
43912 +
43913 +#endif /* __FM_MANIP_H */
43914 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
43915 new file mode 100644
43916 index 00000000..91f70a1a
43917 --- /dev/null
43918 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
43919 @@ -0,0 +1,2095 @@
43920 +/*
43921 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43922 + *
43923 + * Redistribution and use in source and binary forms, with or without
43924 + * modification, are permitted provided that the following conditions are met:
43925 + * * Redistributions of source code must retain the above copyright
43926 + * notice, this list of conditions and the following disclaimer.
43927 + * * Redistributions in binary form must reproduce the above copyright
43928 + * notice, this list of conditions and the following disclaimer in the
43929 + * documentation and/or other materials provided with the distribution.
43930 + * * Neither the name of Freescale Semiconductor nor the
43931 + * names of its contributors may be used to endorse or promote products
43932 + * derived from this software without specific prior written permission.
43933 + *
43934 + *
43935 + * ALTERNATIVELY, this software may be distributed under the terms of the
43936 + * GNU General Public License ("GPL") as published by the Free Software
43937 + * Foundation, either version 2 of that License or (at your option) any
43938 + * later version.
43939 + *
43940 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43941 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43942 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43943 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43944 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43945 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43946 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43947 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43948 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43949 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43950 + */
43951 +
43952 +
43953 +/******************************************************************************
43954 + @File fm_pcd.c
43955 +
43956 + @Description FM PCD ...
43957 +*//***************************************************************************/
43958 +#include "std_ext.h"
43959 +#include "error_ext.h"
43960 +#include "string_ext.h"
43961 +#include "xx_ext.h"
43962 +#include "sprint_ext.h"
43963 +#include "debug_ext.h"
43964 +#include "net_ext.h"
43965 +#include "fm_ext.h"
43966 +#include "fm_pcd_ext.h"
43967 +
43968 +#include "fm_common.h"
43969 +#include "fm_pcd.h"
43970 +#include "fm_pcd_ipc.h"
43971 +#include "fm_hc.h"
43972 +#include "fm_muram_ext.h"
43973 +
43974 +
43975 +/****************************************/
43976 +/* static functions */
43977 +/****************************************/
43978 +
43979 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
43980 +{
43981 + if (!p_FmPcd->h_Fm)
43982 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
43983 +
43984 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
43985 + {
43986 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
43987 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43988 +
43989 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
43990 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43991 +
43992 + if (!p_FmPcd->f_Exception)
43993 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
43994 +
43995 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
43996 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
43997 +
43998 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
43999 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
44000 + }
44001 +
44002 + return E_OK;
44003 +}
44004 +
44005 +static volatile bool blockingFlag = FALSE;
44006 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
44007 + uint8_t *p_Msg,
44008 + uint8_t *p_Reply,
44009 + uint32_t replyLength,
44010 + t_Error status)
44011 +{
44012 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
44013 + blockingFlag = FALSE;
44014 +}
44015 +
44016 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
44017 + uint8_t *p_Msg,
44018 + uint32_t msgLength,
44019 + uint8_t *p_Reply,
44020 + uint32_t *p_ReplyLength)
44021 +{
44022 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44023 + t_Error err = E_OK;
44024 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
44025 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
44026 +
44027 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44028 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
44029 +
44030 +#ifdef DISABLE_SANITY_CHECKS
44031 + UNUSED(msgLength);
44032 +#endif /* DISABLE_SANITY_CHECKS */
44033 +
44034 + ASSERT_COND(p_Msg);
44035 +
44036 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
44037 + *p_ReplyLength = 0;
44038 +
44039 + switch (p_IpcMsg->msgId)
44040 + {
44041 + case (FM_PCD_MASTER_IS_ALIVE):
44042 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
44043 + p_IpcReply->error = E_OK;
44044 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44045 + break;
44046 + case (FM_PCD_MASTER_IS_ENABLED):
44047 + /* count partitions registrations */
44048 + if (p_FmPcd->enabled)
44049 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
44050 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
44051 + p_IpcReply->error = E_OK;
44052 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44053 + break;
44054 + case (FM_PCD_GUEST_DISABLE):
44055 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
44056 + {
44057 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
44058 + p_IpcReply->error = E_OK;
44059 + }
44060 + else
44061 + {
44062 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
44063 + p_IpcReply->error = E_INVALID_STATE;
44064 + }
44065 + *p_ReplyLength = sizeof(uint32_t);
44066 + break;
44067 + case (FM_PCD_GET_COUNTER):
44068 + {
44069 + e_FmPcdCounters inCounter;
44070 + uint32_t outCounter;
44071 +
44072 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
44073 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
44074 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
44075 + p_IpcReply->error = E_OK;
44076 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44077 + break;
44078 + }
44079 + case (FM_PCD_ALLOC_KG_SCHEMES):
44080 + {
44081 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44082 +
44083 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44084 + err = FmPcdKgAllocSchemes(h_FmPcd,
44085 + ipcSchemesParams.numOfSchemes,
44086 + ipcSchemesParams.guestId,
44087 + p_IpcReply->replyBody);
44088 + p_IpcReply->error = err;
44089 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
44090 + break;
44091 + }
44092 + case (FM_PCD_FREE_KG_SCHEMES):
44093 + {
44094 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44095 +
44096 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44097 + err = FmPcdKgFreeSchemes(h_FmPcd,
44098 + ipcSchemesParams.numOfSchemes,
44099 + ipcSchemesParams.guestId,
44100 + ipcSchemesParams.schemesIds);
44101 + p_IpcReply->error = err;
44102 + *p_ReplyLength = sizeof(uint32_t);
44103 + break;
44104 + }
44105 + case (FM_PCD_ALLOC_KG_CLSPLAN):
44106 + {
44107 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44108 +
44109 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44110 + err = KgAllocClsPlanEntries(h_FmPcd,
44111 + ipcKgClsPlanParams.numOfClsPlanEntries,
44112 + ipcKgClsPlanParams.guestId,
44113 + p_IpcReply->replyBody);
44114 + p_IpcReply->error = err;
44115 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44116 + break;
44117 + }
44118 + case (FM_PCD_FREE_KG_CLSPLAN):
44119 + {
44120 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44121 +
44122 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44123 + KgFreeClsPlanEntries(h_FmPcd,
44124 + ipcKgClsPlanParams.numOfClsPlanEntries,
44125 + ipcKgClsPlanParams.guestId,
44126 + ipcKgClsPlanParams.clsPlanBase);
44127 + *p_ReplyLength = sizeof(uint32_t);
44128 + break;
44129 + }
44130 + case (FM_PCD_ALLOC_PROFILES):
44131 + {
44132 + t_FmIpcResourceAllocParams ipcAllocParams;
44133 + uint16_t base;
44134 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44135 + base = PlcrAllocProfilesForPartition(h_FmPcd,
44136 + ipcAllocParams.base,
44137 + ipcAllocParams.num,
44138 + ipcAllocParams.guestId);
44139 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
44140 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
44141 + break;
44142 + }
44143 + case (FM_PCD_FREE_PROFILES):
44144 + {
44145 + t_FmIpcResourceAllocParams ipcAllocParams;
44146 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44147 + PlcrFreeProfilesForPartition(h_FmPcd,
44148 + ipcAllocParams.base,
44149 + ipcAllocParams.num,
44150 + ipcAllocParams.guestId);
44151 + break;
44152 + }
44153 + case (FM_PCD_SET_PORT_PROFILES):
44154 + {
44155 + t_FmIpcResourceAllocParams ipcAllocParams;
44156 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44157 + PlcrSetPortProfiles(h_FmPcd,
44158 + ipcAllocParams.guestId,
44159 + ipcAllocParams.num,
44160 + ipcAllocParams.base);
44161 + break;
44162 + }
44163 + case (FM_PCD_CLEAR_PORT_PROFILES):
44164 + {
44165 + t_FmIpcResourceAllocParams ipcAllocParams;
44166 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44167 + PlcrClearPortProfiles(h_FmPcd,
44168 + ipcAllocParams.guestId);
44169 + break;
44170 + }
44171 + case (FM_PCD_GET_SW_PRS_OFFSET):
44172 + {
44173 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
44174 + uint32_t swPrsOffset;
44175 +
44176 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
44177 + swPrsOffset =
44178 + FmPcdGetSwPrsOffset(h_FmPcd,
44179 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
44180 + ipcSwPrsLable.indexPerHdr);
44181 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
44182 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44183 + break;
44184 + }
44185 + case (FM_PCD_PRS_INC_PORT_STATS):
44186 + {
44187 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
44188 +
44189 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
44190 + PrsIncludePortInStatistics(h_FmPcd,
44191 + ipcPrsIncludePort.hardwarePortId,
44192 + ipcPrsIncludePort.include);
44193 + break;
44194 + }
44195 + default:
44196 + *p_ReplyLength = 0;
44197 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
44198 + }
44199 + return E_OK;
44200 +}
44201 +
44202 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
44203 +{
44204 + ASSERT_COND(h_NetEnv);
44205 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
44206 +}
44207 +
44208 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44209 +{
44210 + ASSERT_COND(h_NetEnv);
44211 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44212 +}
44213 +
44214 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44215 +{
44216 + uint32_t intFlags;
44217 +
44218 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44219 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44220 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44221 +}
44222 +
44223 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44224 +{
44225 + t_FmPcdLock *p_Lock = NULL;
44226 + uint32_t intFlags;
44227 +
44228 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44229 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44230 + {
44231 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44232 + LIST_DelAndInit(&p_Lock->node);
44233 + }
44234 + if (p_FmPcd->h_Spinlock)
44235 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44236 +
44237 + return p_Lock;
44238 +}
44239 +
44240 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44241 +{
44242 + uint32_t intFlags;
44243 +
44244 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44245 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44246 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44247 +}
44248 +
44249 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44250 +{
44251 + t_FmPcdLock *p_Lock;
44252 + int i;
44253 +
44254 + for (i=0; i<10; i++)
44255 + {
44256 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44257 + if (!p_Lock)
44258 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44259 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44260 + INIT_LIST(&p_Lock->node);
44261 + p_Lock->h_Spinlock = XX_InitSpinlock();
44262 + if (!p_Lock->h_Spinlock)
44263 + {
44264 + XX_Free(p_Lock);
44265 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44266 + }
44267 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44268 + }
44269 +
44270 + return E_OK;
44271 +}
44272 +
44273 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44274 +{
44275 + t_FmPcdLock *p_Lock;
44276 +
44277 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44278 + while (p_Lock)
44279 + {
44280 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44281 + XX_Free(p_Lock);
44282 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44283 + }
44284 +}
44285 +
44286 +
44287 +
44288 +/*****************************************************************************/
44289 +/* Inter-module API routines */
44290 +/*****************************************************************************/
44291 +
44292 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44293 +{
44294 + ASSERT_COND(p_FmPcd);
44295 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44296 +}
44297 +
44298 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44299 +{
44300 + uint8_t netEnvId = p_GrpParams->netEnvId;
44301 + int i, k, j;
44302 +
44303 + ASSERT_COND(p_FmPcd);
44304 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44305 + {
44306 + p_GrpParams->grpExists = TRUE;
44307 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44308 + return E_OK;
44309 + }
44310 +
44311 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44312 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44313 + {
44314 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44315 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44316 + {
44317 + /* if an option exists, add it to the opts list */
44318 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44319 + {
44320 + /* check if this option already exists, add if it doesn't */
44321 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44322 + {
44323 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44324 + break;
44325 + }
44326 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44327 + if (j == p_GrpParams->numOfOptions)
44328 + {
44329 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44330 + p_GrpParams->numOfOptions++;
44331 + }
44332 + }
44333 + }
44334 + }
44335 +
44336 + if (p_GrpParams->numOfOptions == 0)
44337 + {
44338 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44339 + {
44340 + p_GrpParams->grpExists = TRUE;
44341 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44342 + }
44343 + }
44344 +
44345 + return E_OK;
44346 +
44347 +}
44348 +
44349 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44350 +{
44351 + uint8_t j,k;
44352 +
44353 + *p_Vector = 0;
44354 +
44355 + ASSERT_COND(p_FmPcd);
44356 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44357 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44358 + {
44359 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44360 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44361 + {
44362 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44363 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44364 + }
44365 + }
44366 +
44367 + if (!*p_Vector)
44368 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44369 + else
44370 + return E_OK;
44371 +}
44372 +
44373 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44374 +{
44375 + int i;
44376 +
44377 + ASSERT_COND(p_FmPcd);
44378 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44379 +
44380 + p_Params->vector = 0;
44381 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44382 + {
44383 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44384 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44385 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44386 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44387 + }
44388 +
44389 + return E_OK;
44390 +}
44391 +
44392 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44393 +{
44394 + int i=0, k;
44395 +
44396 + ASSERT_COND(p_FmPcd);
44397 + /* check whether a given unit may be used by non-clsPlan users. */
44398 + /* first, recognize the unit by its vector */
44399 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44400 + {
44401 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44402 + {
44403 + for (k=0;
44404 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44405 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44406 + k++)
44407 + /* check that no option exists */
44408 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44409 + return FALSE;
44410 + break;
44411 + }
44412 + i++;
44413 + }
44414 + /* assert that a unit was found to mach the vector */
44415 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44416 +
44417 + return TRUE;
44418 +}
44419 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44420 +{
44421 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44422 + int i, k;
44423 +
44424 + ASSERT_COND(p_FmPcd);
44425 +
44426 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44427 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44428 + {
44429 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44430 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44431 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44432 + return TRUE;
44433 + }
44434 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44435 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44436 + {
44437 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44438 + return TRUE;
44439 + }
44440 +
44441 + return FALSE;
44442 +}
44443 +
44444 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44445 +{
44446 + uint8_t i, k;
44447 +
44448 + ASSERT_COND(p_FmPcd);
44449 +
44450 + if (interchangeable)
44451 + {
44452 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44453 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44454 + {
44455 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44456 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44457 + {
44458 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44459 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44460 +
44461 + return i;
44462 + }
44463 + }
44464 + }
44465 + else
44466 + {
44467 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44468 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44469 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44470 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44471 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44472 + return i;
44473 +
44474 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44475 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44476 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44477 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44478 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44479 + }
44480 +
44481 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44482 +}
44483 +
44484 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44485 +{
44486 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44487 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44488 + uint8_t result;
44489 + t_Error err = E_OK;
44490 +
44491 + ASSERT_COND(p_FmPcd);
44492 + ASSERT_COND(h_ReasmCommonPramTbl);
44493 +
44494 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44495 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44496 +
44497 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44498 + RETURN_ERROR(MAJOR, err, NO_MSG);
44499 +
44500 + switch (result)
44501 + {
44502 + case (0):
44503 + return E_OK;
44504 + case (1):
44505 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44506 + case (2):
44507 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44508 + case (3):
44509 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44510 + default:
44511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44512 + }
44513 +
44514 + return E_OK;
44515 +}
44516 +
44517 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44518 +{
44519 + int i;
44520 +
44521 + ASSERT_COND(p_FmPcd);
44522 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44523 +
44524 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44525 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44526 + {
44527 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44528 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44529 + }
44530 +
44531 + return HEADER_TYPE_NONE;
44532 +}
44533 +
44534 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44535 +{
44536 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44537 + uint16_t swPortIndex = 0;
44538 +
44539 + ASSERT_COND(h_FmPcd);
44540 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44541 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44542 +}
44543 +
44544 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44545 +{
44546 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44547 +
44548 + ASSERT_COND(h_FmPcd);
44549 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44550 +}
44551 +
44552 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44553 +{
44554 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44555 +
44556 + ASSERT_COND(h_FmPcd);
44557 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44558 +}
44559 +
44560 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44561 +{
44562 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44563 +}
44564 +
44565 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44566 +{
44567 + uint32_t intFlags;
44568 +
44569 + ASSERT_COND(h_FmPcd);
44570 +
44571 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44572 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44573 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44574 +}
44575 +
44576 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44577 +{
44578 + uint32_t intFlags;
44579 +
44580 + ASSERT_COND(h_FmPcd);
44581 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44582 +
44583 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44584 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44585 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44586 +}
44587 +
44588 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44589 +{
44590 + ASSERT_COND(h_FmPcd);
44591 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44592 +}
44593 +
44594 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44595 +{
44596 + ASSERT_COND(h_FmPcd);
44597 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44598 +}
44599 +
44600 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44601 +{
44602 + t_FmPcdLock *p_Lock;
44603 + ASSERT_COND(h_FmPcd);
44604 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44605 + if (!p_Lock)
44606 + {
44607 + FillFreeLocksLst(h_FmPcd);
44608 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44609 + }
44610 +
44611 + if (p_Lock)
44612 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44613 + return p_Lock;
44614 +}
44615 +
44616 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44617 +{
44618 + uint32_t intFlags;
44619 + ASSERT_COND(h_FmPcd);
44620 + intFlags = FmPcdLock(h_FmPcd);
44621 + LIST_DelAndInit(&p_Lock->node);
44622 + FmPcdUnlock(h_FmPcd, intFlags);
44623 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44624 +}
44625 +
44626 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44627 +{
44628 + uint32_t intFlags;
44629 + t_List *p_Pos, *p_SavedPos=NULL;
44630 +
44631 + ASSERT_COND(h_FmPcd);
44632 + intFlags = FmPcdLock(h_FmPcd);
44633 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44634 + {
44635 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44636 + if (!FmPcdLockTryLock(p_Lock))
44637 + {
44638 + p_SavedPos = p_Pos;
44639 + break;
44640 + }
44641 + }
44642 + if (p_SavedPos)
44643 + {
44644 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44645 + {
44646 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44647 + if (p_Pos == p_SavedPos)
44648 + break;
44649 + FmPcdLockUnlock(p_Lock);
44650 + }
44651 + }
44652 + FmPcdUnlock(h_FmPcd, intFlags);
44653 +
44654 + CORE_MemoryBarrier();
44655 +
44656 + if (p_SavedPos)
44657 + return FALSE;
44658 +
44659 + return TRUE;
44660 +}
44661 +
44662 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44663 +{
44664 + uint32_t intFlags;
44665 + t_List *p_Pos;
44666 +
44667 + ASSERT_COND(h_FmPcd);
44668 + intFlags = FmPcdLock(h_FmPcd);
44669 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44670 + {
44671 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44672 + p_Lock->flag = FALSE;
44673 + }
44674 + FmPcdUnlock(h_FmPcd, intFlags);
44675 +
44676 + CORE_MemoryBarrier();
44677 +}
44678 +
44679 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44680 +{
44681 + ASSERT_COND(h_FmPcd);
44682 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44683 +
44684 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44685 +}
44686 +
44687 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44688 +{
44689 + ASSERT_COND(h_FmPcd);
44690 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44691 +}
44692 +
44693 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44694 +{
44695 + ASSERT_COND(h_FmPcd);
44696 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44697 +}
44698 +/*********************** End of inter-module routines ************************/
44699 +
44700 +
44701 +/****************************************/
44702 +/* API Init unit functions */
44703 +/****************************************/
44704 +
44705 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44706 +{
44707 + t_FmPcd *p_FmPcd = NULL;
44708 + t_FmPhysAddr physicalMuramBase;
44709 + uint8_t i;
44710 +
44711 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44712 +
44713 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44714 + if (!p_FmPcd)
44715 + {
44716 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44717 + return NULL;
44718 + }
44719 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44720 +
44721 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44722 + if (!p_FmPcd->p_FmPcdDriverParam)
44723 + {
44724 + XX_Free(p_FmPcd);
44725 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44726 + return NULL;
44727 + }
44728 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44729 +
44730 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44731 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44732 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44733 + if (p_FmPcd->h_FmMuram)
44734 + {
44735 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44736 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44737 + }
44738 +
44739 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44740 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44741 +
44742 + if (p_FmPcdParams->useHostCommand)
44743 + {
44744 + t_FmHcParams hcParams;
44745 +
44746 + memset(&hcParams, 0, sizeof(hcParams));
44747 + hcParams.h_Fm = p_FmPcd->h_Fm;
44748 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44749 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44750 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44751 + if (!p_FmPcd->h_Hc)
44752 + {
44753 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44754 + FM_PCD_Free(p_FmPcd);
44755 + return NULL;
44756 + }
44757 + }
44758 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44759 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44760 +
44761 + if (p_FmPcdParams->kgSupport)
44762 + {
44763 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44764 + if (!p_FmPcd->p_FmPcdKg)
44765 + {
44766 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44767 + FM_PCD_Free(p_FmPcd);
44768 + return NULL;
44769 + }
44770 + }
44771 +
44772 + if (p_FmPcdParams->plcrSupport)
44773 + {
44774 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44775 + if (!p_FmPcd->p_FmPcdPlcr)
44776 + {
44777 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44778 + FM_PCD_Free(p_FmPcd);
44779 + return NULL;
44780 + }
44781 + }
44782 +
44783 + if (p_FmPcdParams->prsSupport)
44784 + {
44785 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44786 + if (!p_FmPcd->p_FmPcdPrs)
44787 + {
44788 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44789 + FM_PCD_Free(p_FmPcd);
44790 + return NULL;
44791 + }
44792 + }
44793 +
44794 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44795 + if (!p_FmPcd->h_Spinlock)
44796 + {
44797 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44798 + FM_PCD_Free(p_FmPcd);
44799 + return NULL;
44800 + }
44801 + INIT_LIST(&p_FmPcd->freeLocksLst);
44802 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44803 +
44804 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44805 +
44806 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44807 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44808 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44809 +
44810 + p_FmPcd->p_CcShadow = NULL;
44811 + p_FmPcd->ccShadowSize = 0;
44812 + p_FmPcd->ccShadowAlign = 0;
44813 +
44814 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44815 + if (!p_FmPcd->h_ShadowSpinlock)
44816 + {
44817 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44818 + FM_PCD_Free(p_FmPcd);
44819 + return NULL;
44820 + }
44821 +
44822 + return p_FmPcd;
44823 +}
44824 +
44825 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44826 +{
44827 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44828 + t_Error err = E_OK;
44829 + t_FmPcdIpcMsg msg;
44830 +
44831 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44832 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44833 +
44834 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44835 +
44836 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44837 + {
44838 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44839 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44840 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44841 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44842 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44843 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44844 +
44845 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44846 + if (p_FmPcd->h_IpcSession)
44847 + {
44848 + t_FmPcdIpcReply reply;
44849 + uint32_t replyLength;
44850 + uint8_t isMasterAlive = 0;
44851 +
44852 + memset(&msg, 0, sizeof(msg));
44853 + memset(&reply, 0, sizeof(reply));
44854 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
44855 + msg.msgBody[0] = p_FmPcd->guestId;
44856 + blockingFlag = TRUE;
44857 +
44858 + do
44859 + {
44860 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
44861 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44862 + (uint8_t*)&msg,
44863 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
44864 + (uint8_t*)&reply,
44865 + &replyLength,
44866 + IpcMsgCompletionCB,
44867 + h_FmPcd)) != E_OK)
44868 + REPORT_ERROR(MAJOR, err, NO_MSG);
44869 + while (blockingFlag) ;
44870 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
44871 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44872 + isMasterAlive = *(uint8_t*)(reply.replyBody);
44873 + } while (!isMasterAlive);
44874 + }
44875 + }
44876 +
44877 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
44878 +
44879 + if (p_FmPcd->p_FmPcdKg)
44880 + {
44881 + err = KgInit(p_FmPcd);
44882 + if (err)
44883 + RETURN_ERROR(MAJOR, err, NO_MSG);
44884 + }
44885 +
44886 + if (p_FmPcd->p_FmPcdPlcr)
44887 + {
44888 + err = PlcrInit(p_FmPcd);
44889 + if (err)
44890 + RETURN_ERROR(MAJOR, err, NO_MSG);
44891 + }
44892 +
44893 + if (p_FmPcd->p_FmPcdPrs)
44894 + {
44895 + err = PrsInit(p_FmPcd);
44896 + if (err)
44897 + RETURN_ERROR(MAJOR, err, NO_MSG);
44898 + }
44899 +
44900 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44901 + {
44902 + /* register to inter-core messaging mechanism */
44903 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44904 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
44905 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44906 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
44907 + if (err)
44908 + RETURN_ERROR(MAJOR, err, NO_MSG);
44909 + }
44910 +
44911 + /* IPv6 Frame-Id used for fragmentation */
44912 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
44913 + if (!p_FmPcd->ipv6FrameIdAddr)
44914 + {
44915 + FM_PCD_Free(p_FmPcd);
44916 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
44917 + }
44918 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
44919 +
44920 + /* CAPWAP Frame-Id used for fragmentation */
44921 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
44922 + if (!p_FmPcd->capwapFrameIdAddr)
44923 + {
44924 + FM_PCD_Free(p_FmPcd);
44925 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
44926 + }
44927 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
44928 +
44929 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44930 + p_FmPcd->p_FmPcdDriverParam = NULL;
44931 +
44932 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
44933 +
44934 + return E_OK;
44935 +}
44936 +
44937 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
44938 +{
44939 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
44940 + t_Error err = E_OK;
44941 +
44942 + if (p_FmPcd->ipv6FrameIdAddr)
44943 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
44944 +
44945 + if (p_FmPcd->capwapFrameIdAddr)
44946 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
44947 +
44948 + if (p_FmPcd->enabled)
44949 + FM_PCD_Disable(p_FmPcd);
44950 +
44951 + if (p_FmPcd->p_FmPcdDriverParam)
44952 + {
44953 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44954 + p_FmPcd->p_FmPcdDriverParam = NULL;
44955 + }
44956 +
44957 + if (p_FmPcd->p_FmPcdKg)
44958 + {
44959 + if ((err = KgFree(p_FmPcd)) != E_OK)
44960 + RETURN_ERROR(MINOR, err, NO_MSG);
44961 + XX_Free(p_FmPcd->p_FmPcdKg);
44962 + p_FmPcd->p_FmPcdKg = NULL;
44963 + }
44964 +
44965 + if (p_FmPcd->p_FmPcdPlcr)
44966 + {
44967 + PlcrFree(p_FmPcd);
44968 + XX_Free(p_FmPcd->p_FmPcdPlcr);
44969 + p_FmPcd->p_FmPcdPlcr = NULL;
44970 + }
44971 +
44972 + if (p_FmPcd->p_FmPcdPrs)
44973 + {
44974 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44975 + PrsFree(p_FmPcd);
44976 + XX_Free(p_FmPcd->p_FmPcdPrs);
44977 + p_FmPcd->p_FmPcdPrs = NULL;
44978 + }
44979 +
44980 + if (p_FmPcd->h_Hc)
44981 + {
44982 + FmHcFree(p_FmPcd->h_Hc);
44983 + p_FmPcd->h_Hc = NULL;
44984 + }
44985 +
44986 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
44987 +
44988 + FmUnregisterPcd(p_FmPcd->h_Fm);
44989 +
44990 + ReleaseFreeLocksLst(p_FmPcd);
44991 +
44992 + if (p_FmPcd->h_Spinlock)
44993 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
44994 +
44995 + if (p_FmPcd->h_ShadowSpinlock)
44996 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
44997 +
44998 + XX_Free(p_FmPcd);
44999 +
45000 + return E_OK;
45001 +}
45002 +
45003 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45004 +{
45005 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45006 + uint32_t bitMask = 0;
45007 +
45008 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45009 +
45010 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45011 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
45012 +
45013 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45014 + if (bitMask)
45015 + {
45016 + if (enable)
45017 + p_FmPcd->exceptions |= bitMask;
45018 + else
45019 + p_FmPcd->exceptions &= ~bitMask;
45020 + }
45021 + else
45022 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
45023 +
45024 + return E_OK;
45025 +}
45026 +
45027 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
45028 +{
45029 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45030 +
45031 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45032 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
45033 +
45034 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
45035 +}
45036 +
45037 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
45038 +{
45039 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45040 + t_Error err = E_OK;
45041 +
45042 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45043 +
45044 + if (p_FmPcd->enabled)
45045 + return E_OK;
45046 +
45047 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45048 + p_FmPcd->h_IpcSession)
45049 + {
45050 + uint8_t enabled;
45051 + t_FmPcdIpcMsg msg;
45052 + t_FmPcdIpcReply reply;
45053 + uint32_t replyLength;
45054 +
45055 + memset(&reply, 0, sizeof(reply));
45056 + memset(&msg, 0, sizeof(msg));
45057 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
45058 + replyLength = sizeof(uint32_t) + sizeof(enabled);
45059 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45060 + (uint8_t*)&msg,
45061 + sizeof(msg.msgId),
45062 + (uint8_t*)&reply,
45063 + &replyLength,
45064 + NULL,
45065 + NULL)) != E_OK)
45066 + RETURN_ERROR(MAJOR, err, NO_MSG);
45067 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
45068 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45069 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
45070 + if (!p_FmPcd->enabled)
45071 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
45072 +
45073 + return E_OK;
45074 + }
45075 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45076 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45077 + ("running in guest-mode without IPC!"));
45078 +
45079 + if (p_FmPcd->p_FmPcdKg)
45080 + KgEnable(p_FmPcd);
45081 +
45082 + if (p_FmPcd->p_FmPcdPlcr)
45083 + PlcrEnable(p_FmPcd);
45084 +
45085 + if (p_FmPcd->p_FmPcdPrs)
45086 + PrsEnable(p_FmPcd);
45087 +
45088 + p_FmPcd->enabled = TRUE;
45089 +
45090 + return E_OK;
45091 +}
45092 +
45093 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
45094 +{
45095 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45096 + t_Error err = E_OK;
45097 +
45098 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45099 +
45100 + if (!p_FmPcd->enabled)
45101 + return E_OK;
45102 +
45103 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45104 + p_FmPcd->h_IpcSession)
45105 + {
45106 + t_FmPcdIpcMsg msg;
45107 + t_FmPcdIpcReply reply;
45108 + uint32_t replyLength;
45109 +
45110 + memset(&reply, 0, sizeof(reply));
45111 + memset(&msg, 0, sizeof(msg));
45112 + msg.msgId = FM_PCD_GUEST_DISABLE;
45113 + replyLength = sizeof(uint32_t);
45114 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45115 + (uint8_t*)&msg,
45116 + sizeof(msg.msgId),
45117 + (uint8_t*)&reply,
45118 + &replyLength,
45119 + NULL,
45120 + NULL)) != E_OK)
45121 + RETURN_ERROR(MAJOR, err, NO_MSG);
45122 + if (replyLength != sizeof(uint32_t))
45123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45124 + if (reply.error == E_OK)
45125 + p_FmPcd->enabled = FALSE;
45126 +
45127 + return (t_Error)(reply.error);
45128 + }
45129 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45130 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45131 + ("running in guest-mode without IPC!"));
45132 +
45133 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
45134 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
45135 + ("Trying to disable a master partition PCD while"
45136 + "guest partitions are still enabled!"));
45137 +
45138 + if (p_FmPcd->p_FmPcdKg)
45139 + KgDisable(p_FmPcd);
45140 +
45141 + if (p_FmPcd->p_FmPcdPlcr)
45142 + PlcrDisable(p_FmPcd);
45143 +
45144 + if (p_FmPcd->p_FmPcdPrs)
45145 + PrsDisable(p_FmPcd);
45146 +
45147 + p_FmPcd->enabled = FALSE;
45148 +
45149 + return E_OK;
45150 +}
45151 +
45152 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
45153 +{
45154 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45155 + uint32_t intFlags, specialUnits = 0;
45156 + uint8_t bitId = 0;
45157 + uint8_t i, j, k;
45158 + uint8_t netEnvCurrId;
45159 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
45160 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
45161 + uint8_t hdrNum;
45162 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
45163 +
45164 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
45165 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
45166 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
45167 +
45168 + intFlags = FmPcdLock(p_FmPcd);
45169 +
45170 + /* find a new netEnv */
45171 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
45172 + if (!p_FmPcd->netEnvs[i].used)
45173 + break;
45174 +
45175 + if (i== FM_MAX_NUM_OF_PORTS)
45176 + {
45177 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
45178 + FmPcdUnlock(p_FmPcd, intFlags);
45179 + return NULL;
45180 + }
45181 +
45182 + p_FmPcd->netEnvs[i].used = TRUE;
45183 + FmPcdUnlock(p_FmPcd, intFlags);
45184 +
45185 + /* As anyone doesn't have handle of this netEnv yet, no need
45186 + to protect it with spinlocks */
45187 +
45188 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
45189 + if (!p_ModifiedNetEnvParams)
45190 + {
45191 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
45192 + return NULL;
45193 + }
45194 +
45195 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
45196 + p_NetEnvParams = p_ModifiedNetEnvParams;
45197 +
45198 + netEnvCurrId = (uint8_t)i;
45199 +
45200 + /* clear from previous use */
45201 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
45202 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
45203 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
45204 +
45205 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
45206 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45207 +
45208 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45209 +
45210 + /* check that header with opt is not interchanged with the same header */
45211 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45212 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45213 + {
45214 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45215 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45216 + {
45217 + /* if an option exists, check that other headers are not the same header
45218 + without option */
45219 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45220 + {
45221 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45222 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45223 + {
45224 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45225 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45226 + {
45227 + REPORT_ERROR(MINOR, E_FULL,
45228 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45229 + XX_Free(p_ModifiedNetEnvParams);
45230 + return NULL;
45231 + }
45232 + }
45233 + }
45234 + }
45235 + }
45236 +
45237 + /* Specific headers checking */
45238 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45239 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45240 + {
45241 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45242 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45243 + {
45244 + /* Some headers pairs may not be defined on different units as the parser
45245 + doesn't distinguish */
45246 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45247 + /* check that header with opt is not interchanged with the same header */
45248 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45249 + {
45250 + if (ipsecEspExists && (ipsecEspUnit != i))
45251 + {
45252 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45253 + XX_Free(p_ModifiedNetEnvParams);
45254 + return NULL;
45255 + }
45256 + else
45257 + {
45258 + ipsecAhUnit = i;
45259 + ipsecAhExists = TRUE;
45260 + }
45261 + }
45262 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45263 + {
45264 + if (ipsecAhExists && (ipsecAhUnit != i))
45265 + {
45266 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45267 + XX_Free(p_ModifiedNetEnvParams);
45268 + return NULL;
45269 + }
45270 + else
45271 + {
45272 + ipsecEspUnit = i;
45273 + ipsecEspExists = TRUE;
45274 + }
45275 + }
45276 + /* ENCAP_ESP */
45277 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45278 + {
45279 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45280 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45281 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45282 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45283 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45284 + }
45285 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45286 + /* UDP_LITE */
45287 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45288 + {
45289 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45290 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45291 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45292 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45293 + }
45294 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45295 +
45296 + /* IP FRAG */
45297 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45298 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45299 + {
45300 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45301 + * IPv4 exists. If so we don't need to set an extra unit
45302 + * We consider as "having IPv4" any IPv4 without interchangable headers
45303 + * but including any options. */
45304 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45305 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45306 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45307 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45308 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45309 +
45310 + /* check if IPv4 header exists by itself */
45311 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45312 + {
45313 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45314 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45315 + }
45316 + }
45317 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45318 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45319 + {
45320 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45321 + * IPv4 exists. If so we don't need to set an extra unit
45322 + * We consider as "having IPv6" any IPv6 without interchangable headers
45323 + * but including any options. */
45324 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45325 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45326 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45327 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45328 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45329 +
45330 + /* check if IPv6 header exists by itself */
45331 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45332 + {
45333 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45334 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45335 + }
45336 + }
45337 +#if (DPAA_VERSION >= 11)
45338 + /* CAPWAP FRAG */
45339 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45340 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45341 + {
45342 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45343 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45344 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45345 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45346 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45347 + }
45348 +#endif /* (DPAA_VERSION >= 11) */
45349 + }
45350 + }
45351 +
45352 + /* if private header (shim), check that no other headers specified */
45353 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45354 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45355 + {
45356 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45357 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45358 + {
45359 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45360 + XX_Free(p_ModifiedNetEnvParams);
45361 + return NULL;
45362 + }
45363 + }
45364 +
45365 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45366 + {
45367 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45368 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45369 + {
45370 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45371 + if (shim1Selected)
45372 + {
45373 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45374 + XX_Free(p_ModifiedNetEnvParams);
45375 + return NULL;
45376 + }
45377 + shim1Selected = TRUE;
45378 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45379 + break;
45380 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45381 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45382 + break;
45383 + default:
45384 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45385 + }
45386 + else
45387 + {
45388 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45389 +
45390 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45391 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45392 + }
45393 + }
45394 +
45395 + /* define a set of hardware parser LCV's according to the defined netenv */
45396 +
45397 + /* set an array of LCV's for each header in the netEnv */
45398 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45399 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45400 + {
45401 + /* private headers have no LCV in the hard parser */
45402 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45403 + {
45404 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45405 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45406 + {
45407 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45408 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45409 + {
45410 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45411 + XX_Free(p_ModifiedNetEnvParams);
45412 + return NULL;
45413 + }
45414 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45415 + }
45416 + }
45417 + }
45418 + XX_Free(p_ModifiedNetEnvParams);
45419 +
45420 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45421 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45422 + {
45423 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45424 + return NULL;
45425 + }
45426 + return &p_FmPcd->netEnvs[netEnvCurrId];
45427 +}
45428 +
45429 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45430 +{
45431 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45432 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45433 + uint32_t intFlags;
45434 + uint8_t netEnvId = p_NetEnv->netEnvId;
45435 +
45436 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45437 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45438 +
45439 + /* check that no port is bound to this netEnv */
45440 + if (p_FmPcd->netEnvs[netEnvId].owners)
45441 + {
45442 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45443 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45444 + }
45445 +
45446 + intFlags = FmPcdLock(p_FmPcd);
45447 +
45448 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45449 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45450 +
45451 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45452 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45453 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45454 +
45455 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45456 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45457 +
45458 + FmPcdUnlock(p_FmPcd, intFlags);
45459 + return E_OK;
45460 +}
45461 +
45462 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45463 +{
45464 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45465 +
45466 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45467 +
45468 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45469 +}
45470 +
45471 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45472 +{
45473 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45474 + t_FmCtrlCodeRevisionInfo revInfo;
45475 + t_Error err;
45476 +
45477 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45478 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45479 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45480 +
45481 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45482 + {
45483 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45484 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45485 + }
45486 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45487 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45488 +
45489 + if (!p_FmPcd->h_Hc)
45490 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45491 +
45492 + p_FmPcd->advancedOffloadSupport = TRUE;
45493 +
45494 + return E_OK;
45495 +}
45496 +
45497 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45498 +{
45499 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45500 + uint32_t outCounter = 0;
45501 + t_Error err;
45502 +
45503 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45504 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45505 +
45506 + switch (counter)
45507 + {
45508 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45509 + if (!p_FmPcd->p_FmPcdKg)
45510 + {
45511 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45512 + return 0;
45513 + }
45514 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45515 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45516 + !p_FmPcd->h_IpcSession)
45517 + {
45518 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45519 + ("running in guest-mode without neither IPC nor mapped register!"));
45520 + return 0;
45521 + }
45522 + break;
45523 +
45524 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45525 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45526 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45527 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45528 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45529 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45530 + if (!p_FmPcd->p_FmPcdPlcr)
45531 + {
45532 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45533 + return 0;
45534 + }
45535 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45536 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45537 + !p_FmPcd->h_IpcSession)
45538 + {
45539 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45540 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45541 + return 0;
45542 + }
45543 +
45544 + /* check that counters are enabled */
45545 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45546 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45547 + {
45548 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45549 + return 0;
45550 + }
45551 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45552 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45553 + break;
45554 +
45555 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45556 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45557 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45558 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45559 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45560 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45561 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45562 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45563 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45564 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45565 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45566 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45567 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45568 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45569 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45570 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45571 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45572 + if (!p_FmPcd->p_FmPcdPrs)
45573 + {
45574 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45575 + return 0;
45576 + }
45577 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45578 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45579 + !p_FmPcd->h_IpcSession)
45580 + {
45581 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45582 + ("running in guest-mode without neither IPC nor mapped register!"));
45583 + return 0;
45584 + }
45585 + break;
45586 + default:
45587 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45588 + return 0;
45589 + }
45590 +
45591 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45592 + p_FmPcd->h_IpcSession)
45593 + {
45594 + t_FmPcdIpcMsg msg;
45595 + t_FmPcdIpcReply reply;
45596 + uint32_t replyLength;
45597 +
45598 + memset(&msg, 0, sizeof(msg));
45599 + memset(&reply, 0, sizeof(reply));
45600 + msg.msgId = FM_PCD_GET_COUNTER;
45601 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45602 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45603 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45604 + (uint8_t*)&msg,
45605 + sizeof(msg.msgId) +sizeof(uint32_t),
45606 + (uint8_t*)&reply,
45607 + &replyLength,
45608 + NULL,
45609 + NULL)) != E_OK)
45610 + RETURN_ERROR(MAJOR, err, NO_MSG);
45611 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45612 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45613 +
45614 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45615 + return outCounter;
45616 + }
45617 +
45618 + switch (counter)
45619 + {
45620 + /* Parser statistics */
45621 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45622 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45623 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45624 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45625 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45626 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45627 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45628 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45629 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45630 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45631 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45632 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45633 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45634 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45635 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45636 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45637 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45638 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45639 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45640 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45641 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45642 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45643 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45644 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45645 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45646 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45647 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45648 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45649 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45650 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45651 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45652 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45653 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45654 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45655 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45656 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45657 +
45658 + /* Policer statistics */
45659 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45660 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45661 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45662 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45663 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45664 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45665 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45666 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45667 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45668 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45669 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45670 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45671 + }
45672 + return 0;
45673 +}
45674 +
45675 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45676 +{
45677 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45678 + uint32_t bitMask = 0, tmpReg;
45679 +
45680 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45681 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45682 +
45683 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45684 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45685 +
45686 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45687 +
45688 + if (bitMask)
45689 + {
45690 + if (enable)
45691 + p_FmPcd->exceptions |= bitMask;
45692 + else
45693 + p_FmPcd->exceptions &= ~bitMask;
45694 +
45695 + switch (exception)
45696 + {
45697 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45698 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45699 + if (!p_FmPcd->p_FmPcdKg)
45700 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45701 + break;
45702 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45703 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45704 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45705 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45706 + if (!p_FmPcd->p_FmPcdPlcr)
45707 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45708 + break;
45709 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45710 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45711 + if (!p_FmPcd->p_FmPcdPrs)
45712 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45713 + break;
45714 + }
45715 +
45716 + switch (exception)
45717 + {
45718 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45719 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45720 + if (enable)
45721 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45722 + else
45723 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45724 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45725 + break;
45726 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45727 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45728 + if (enable)
45729 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45730 + else
45731 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45732 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45733 + break;
45734 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45735 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45736 + if (enable)
45737 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45738 + else
45739 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45740 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45741 + break;
45742 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45743 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45744 + if (enable)
45745 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45746 + else
45747 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45748 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45749 + break;
45750 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45751 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45752 + if (enable)
45753 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45754 + else
45755 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45756 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45757 + break;
45758 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45759 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45760 + if (enable)
45761 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45762 + else
45763 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45764 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45765 + break;
45766 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45767 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45768 + if (enable)
45769 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45770 + else
45771 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45772 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45773 + break;
45774 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45775 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45776 + if (enable)
45777 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45778 + else
45779 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45780 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45781 + break;
45782 + }
45783 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45784 + Driver may disable them automatically, depending on driver's status */
45785 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45786 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45787 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45788 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45789 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45790 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45791 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45792 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45793 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45794 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45795 + }
45796 +
45797 + return E_OK;
45798 +}
45799 +
45800 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45801 +{
45802 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45803 +
45804 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45805 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45806 +
45807 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45808 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45809 +
45810 + switch (exception)
45811 + {
45812 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45813 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45814 + if (!p_FmPcd->p_FmPcdKg)
45815 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45816 + break;
45817 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45818 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45819 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45820 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45821 + if (!p_FmPcd->p_FmPcdPlcr)
45822 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45823 + break;
45824 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45825 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45826 + if (!p_FmPcd->p_FmPcdPrs)
45827 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45828 + break;
45829 + default:
45830 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45831 + }
45832 + switch (exception)
45833 + {
45834 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45835 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45836 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45837 + break;
45838 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45839 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45840 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45841 + break;
45842 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45843 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45844 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45845 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45846 + break;
45847 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45848 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45849 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45850 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
45851 + break;
45852 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
45853 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
45854 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45855 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
45856 + break;
45857 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
45858 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
45859 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45860 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
45861 + break;
45862 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
45863 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
45864 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45865 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
45866 + break;
45867 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
45868 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
45869 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45870 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
45871 + break;
45872 + }
45873 +
45874 + return E_OK;
45875 +}
45876 +
45877 +
45878 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
45879 +{
45880 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45881 +
45882 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45883 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45884 +
45885 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45886 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
45887 +
45888 + switch (counter)
45889 + {
45890 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45891 + if (!p_FmPcd->p_FmPcdKg)
45892 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
45893 + break;
45894 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45895 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45896 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45897 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45898 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45899 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45900 + if (!p_FmPcd->p_FmPcdPlcr)
45901 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
45902 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45903 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45904 + break;
45905 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45906 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45907 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45908 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45909 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45910 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45911 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45912 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45913 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45914 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45915 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45916 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45917 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45918 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45919 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45920 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45921 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45922 + if (!p_FmPcd->p_FmPcdPrs)
45923 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45924 + break;
45925 + default:
45926 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45927 + }
45928 + switch (counter)
45929 + {
45930 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45931 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
45932 + break;
45933 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45934 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
45935 + break;
45936 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45937 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
45938 + break;
45939 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45940 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
45941 + break;
45942 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45943 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
45944 + break;
45945 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45946 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
45947 + break;
45948 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45949 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
45950 + break;
45951 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45952 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
45953 + break;
45954 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45955 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
45956 + break;
45957 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45958 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
45959 + break;
45960 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45961 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
45962 + break;
45963 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45964 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
45965 + break;
45966 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45967 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
45968 + break;
45969 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45970 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
45971 + break;
45972 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45973 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
45974 + break;
45975 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45976 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
45977 + break;
45978 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45979 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
45980 + break;
45981 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45982 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
45983 + break;
45984 +
45985 + /*Policer counters*/
45986 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45987 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
45988 + break;
45989 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45990 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
45991 + break;
45992 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45993 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
45994 + break;
45995 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45996 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
45997 + break;
45998 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45999 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
46000 + break;
46001 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46002 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
46003 + break;
46004 + }
46005 +
46006 + return E_OK;
46007 +}
46008 +
46009 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
46010 +{
46011 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46012 + return FmHcGetPort(p_FmPcd->h_Hc);
46013 +}
46014 +
46015 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
46016 new file mode 100644
46017 index 00000000..27ec9c5b
46018 --- /dev/null
46019 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
46020 @@ -0,0 +1,543 @@
46021 +/*
46022 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46023 + *
46024 + * Redistribution and use in source and binary forms, with or without
46025 + * modification, are permitted provided that the following conditions are met:
46026 + * * Redistributions of source code must retain the above copyright
46027 + * notice, this list of conditions and the following disclaimer.
46028 + * * Redistributions in binary form must reproduce the above copyright
46029 + * notice, this list of conditions and the following disclaimer in the
46030 + * documentation and/or other materials provided with the distribution.
46031 + * * Neither the name of Freescale Semiconductor nor the
46032 + * names of its contributors may be used to endorse or promote products
46033 + * derived from this software without specific prior written permission.
46034 + *
46035 + *
46036 + * ALTERNATIVELY, this software may be distributed under the terms of the
46037 + * GNU General Public License ("GPL") as published by the Free Software
46038 + * Foundation, either version 2 of that License or (at your option) any
46039 + * later version.
46040 + *
46041 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46042 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46043 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46044 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46045 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46046 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46047 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46048 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46049 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46050 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46051 + */
46052 +
46053 +
46054 +/******************************************************************************
46055 + @File fm_pcd.h
46056 +
46057 + @Description FM PCD ...
46058 +*//***************************************************************************/
46059 +#ifndef __FM_PCD_H
46060 +#define __FM_PCD_H
46061 +
46062 +#include "std_ext.h"
46063 +#include "error_ext.h"
46064 +#include "list_ext.h"
46065 +#include "fm_pcd_ext.h"
46066 +#include "fm_common.h"
46067 +#include "fsl_fman_prs.h"
46068 +#include "fsl_fman_kg.h"
46069 +
46070 +#define __ERR_MODULE__ MODULE_FM_PCD
46071 +
46072 +
46073 +/****************************/
46074 +/* Defaults */
46075 +/****************************/
46076 +#define DEFAULT_plcrAutoRefresh FALSE
46077 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
46078 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
46079 +#define DEFAULT_fmPcdPlcrExceptions 0
46080 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
46081 +
46082 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
46083 +#define DEFAULT_numOfUsedProfilesPerWindow 16
46084 +#define DEFAULT_numOfSharedPlcrProfiles 4
46085 +
46086 +/****************************/
46087 +/* Network defines */
46088 +/****************************/
46089 +#define UDP_HEADER_SIZE 8
46090 +
46091 +#define ESP_SPI_OFFSET 0
46092 +#define ESP_SPI_SIZE 4
46093 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
46094 +#define ESP_SEQ_NUM_SIZE 4
46095 +
46096 +/****************************/
46097 +/* General defines */
46098 +/****************************/
46099 +#define ILLEGAL_CLS_PLAN 0xff
46100 +#define ILLEGAL_NETENV 0xff
46101 +
46102 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
46103 +
46104 +/****************************/
46105 +/* Error defines */
46106 +/****************************/
46107 +
46108 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
46109 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
46110 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
46111 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
46112 +
46113 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
46114 +switch (exception){ \
46115 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
46116 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
46117 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
46118 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
46119 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
46120 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
46121 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
46122 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
46123 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
46124 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
46125 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
46126 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
46127 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
46128 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
46129 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
46130 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
46131 + default: bitMask = 0;break;}
46132 +
46133 +/***********************************************************************/
46134 +/* Policer defines */
46135 +/***********************************************************************/
46136 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
46137 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
46138 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
46139 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
46140 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
46141 +
46142 +/***********************************************************************/
46143 +/* Memory map */
46144 +/***********************************************************************/
46145 +#if defined(__MWERKS__) && !defined(__GNUC__)
46146 +#pragma pack(push,1)
46147 +#endif /* defined(__MWERKS__) && ... */
46148 +
46149 +
46150 +typedef struct {
46151 +/* General Configuration and Status Registers */
46152 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
46153 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
46154 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
46155 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
46156 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
46157 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
46158 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
46159 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
46160 +/* Global Statistic Counters */
46161 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
46162 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
46163 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
46164 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
46165 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
46166 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
46167 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
46168 +/* Profile RAM Access Registers */
46169 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
46170 + t_FmPcdPlcrProfileRegs profileRegs;
46171 +/* Error Capture Registers */
46172 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
46173 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
46174 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
46175 +/* Debug Registers */
46176 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
46177 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
46178 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
46179 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
46180 + (for port-ID 1-11, only for supported Port-ID registers) */
46181 +} t_FmPcdPlcrRegs;
46182 +
46183 +#if defined(__MWERKS__) && !defined(__GNUC__)
46184 +#pragma pack(pop)
46185 +#endif /* defined(__MWERKS__) && ... */
46186 +
46187 +
46188 +/***********************************************************************/
46189 +/* Driver's internal structures */
46190 +/***********************************************************************/
46191 +
46192 +typedef struct {
46193 + bool known;
46194 + uint8_t id;
46195 +} t_FmPcdKgSchemesExtractsEntry;
46196 +
46197 +typedef struct {
46198 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
46199 +} t_FmPcdKgSchemesExtracts;
46200 +
46201 +typedef struct {
46202 + t_Handle h_Manip;
46203 + bool keepRes;
46204 + e_FmPcdEngine nextEngine;
46205 + uint8_t parseCode;
46206 +} t_FmPcdInfoForManip;
46207 +
46208 +/**************************************************************************//**
46209 + @Description A structure of parameters to communicate
46210 + between the port and PCD regarding the KG scheme.
46211 +*//***************************************************************************/
46212 +typedef struct {
46213 + uint8_t netEnvId; /* in */
46214 + uint8_t numOfDistinctionUnits; /* in */
46215 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46216 + uint32_t vector; /* out */
46217 +} t_NetEnvParams;
46218 +
46219 +typedef struct {
46220 + bool allocated;
46221 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46222 + portId for PLCR in any environment */
46223 +} t_FmPcdAllocMng;
46224 +
46225 +typedef struct {
46226 + volatile bool lock;
46227 + bool used;
46228 + uint8_t owners;
46229 + uint8_t netEnvId;
46230 + uint8_t guestId;
46231 + uint8_t baseEntry;
46232 + uint16_t sizeOfGrp;
46233 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46234 +} t_FmPcdKgClsPlanGrp;
46235 +
46236 +typedef struct {
46237 + t_Handle h_FmPcd;
46238 + uint8_t schemeId;
46239 + t_FmPcdLock *p_Lock;
46240 + bool valid;
46241 + uint8_t netEnvId;
46242 + uint8_t owners;
46243 + uint32_t matchVector;
46244 + uint32_t ccUnits;
46245 + bool nextRelativePlcrProfile;
46246 + uint16_t relativeProfileId;
46247 + uint16_t numOfProfiles;
46248 + t_FmPcdKgKeyOrder orderedArray;
46249 + e_FmPcdEngine nextEngine;
46250 + e_FmPcdDoneAction doneAction;
46251 + bool requiredActionFlag;
46252 + uint32_t requiredAction;
46253 + bool extractedOrs;
46254 + uint8_t bitOffsetInPlcrProfile;
46255 + bool directPlcr;
46256 +#if (DPAA_VERSION >= 11)
46257 + bool vspe;
46258 +#endif
46259 +} t_FmPcdKgScheme;
46260 +
46261 +typedef union {
46262 + struct fman_kg_scheme_regs schemeRegs;
46263 + struct fman_kg_pe_regs portRegs;
46264 + struct fman_kg_cp_regs clsPlanRegs;
46265 +} u_FmPcdKgIndirectAccessRegs;
46266 +
46267 +typedef struct {
46268 + struct fman_kg_regs *p_FmPcdKgRegs;
46269 + uint32_t schemeExceptionsBitMask;
46270 + uint8_t numOfSchemes;
46271 + t_Handle h_HwSpinlock;
46272 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46273 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46274 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46275 + uint8_t emptyClsPlanGrpId;
46276 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46277 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46278 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46279 +} t_FmPcdKg;
46280 +
46281 +typedef struct {
46282 + uint16_t profilesBase;
46283 + uint16_t numOfProfiles;
46284 + t_Handle h_FmPort;
46285 +} t_FmPcdPlcrMapParam;
46286 +
46287 +typedef struct {
46288 + uint16_t absoluteProfileId;
46289 + t_Handle h_FmPcd;
46290 + bool valid;
46291 + t_FmPcdLock *p_Lock;
46292 + t_FmPcdAllocMng profilesMng;
46293 + bool requiredActionFlag;
46294 + uint32_t requiredAction;
46295 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46296 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46297 +
46298 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46299 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46300 +
46301 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46302 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46303 +} t_FmPcdPlcrProfile;
46304 +
46305 +typedef struct {
46306 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46307 + uint16_t partPlcrProfilesBase;
46308 + uint16_t partNumOfPlcrProfiles;
46309 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46310 + uint16_t numOfSharedProfiles;
46311 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46312 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46313 + t_Handle h_HwSpinlock;
46314 + t_Handle h_SwSpinlock;
46315 +} t_FmPcdPlcr;
46316 +
46317 +typedef struct {
46318 + uint32_t *p_SwPrsCode;
46319 + uint32_t *p_CurrSwPrs;
46320 + uint8_t currLabel;
46321 + struct fman_prs_regs *p_FmPcdPrsRegs;
46322 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46323 + uint32_t fmPcdPrsPortIdStatistics;
46324 +} t_FmPcdPrs;
46325 +
46326 +typedef struct {
46327 + struct {
46328 + e_NetHeaderType hdr;
46329 + protocolOpt_t opt; /* only one option !! */
46330 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46331 +} t_FmPcdIntDistinctionUnit;
46332 +
46333 +typedef struct {
46334 + e_NetHeaderType hdr;
46335 + protocolOpt_t opt; /* only one option !! */
46336 + e_NetHeaderType aliasHdr;
46337 +} t_FmPcdNetEnvAliases;
46338 +
46339 +typedef struct {
46340 + uint8_t netEnvId;
46341 + t_Handle h_FmPcd;
46342 + t_Handle h_Spinlock;
46343 + bool used;
46344 + uint8_t owners;
46345 + uint8_t clsPlanGrpId;
46346 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46347 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46348 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46349 + uint32_t macsecVector;
46350 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46351 +} t_FmPcdNetEnv;
46352 +
46353 +typedef struct {
46354 + struct fman_prs_cfg dfltCfg;
46355 + bool plcrAutoRefresh;
46356 + uint16_t prsMaxParseCycleLimit;
46357 +} t_FmPcdDriverParam;
46358 +
46359 +typedef struct {
46360 + t_Handle h_Fm;
46361 + t_Handle h_FmMuram;
46362 + t_FmRevisionInfo fmRevInfo;
46363 +
46364 + uint64_t physicalMuramBase;
46365 +
46366 + t_Handle h_Spinlock;
46367 + t_List freeLocksLst;
46368 + t_List acquiredLocksLst;
46369 +
46370 + t_Handle h_IpcSession; /* relevant for guest only */
46371 + bool enabled;
46372 + uint8_t guestId; /**< Guest Partition Id */
46373 + uint8_t numOfEnabledGuestPartitionsPcds;
46374 + char fmPcdModuleName[MODULE_NAME_SIZE];
46375 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46376 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46377 + t_FmPcdKg *p_FmPcdKg;
46378 + t_FmPcdPlcr *p_FmPcdPlcr;
46379 + t_FmPcdPrs *p_FmPcdPrs;
46380 +
46381 + void *p_CcShadow; /**< CC MURAM shadow */
46382 + uint32_t ccShadowSize;
46383 + uint32_t ccShadowAlign;
46384 + volatile bool shadowLock;
46385 + t_Handle h_ShadowSpinlock;
46386 +
46387 + t_Handle h_Hc;
46388 +
46389 + uint32_t exceptions;
46390 + t_FmPcdExceptionCallback *f_Exception;
46391 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46392 + t_Handle h_App;
46393 + uintptr_t ipv6FrameIdAddr;
46394 + uintptr_t capwapFrameIdAddr;
46395 + bool advancedOffloadSupport;
46396 +
46397 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46398 +} t_FmPcd;
46399 +
46400 +#if (DPAA_VERSION >= 11)
46401 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46402 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46403 +#define FRM_REPLIC_UPDATE_INFO 0x02
46404 +#endif /* (DPAA_VERSION >= 11) */
46405 +/***********************************************************************/
46406 +/* PCD internal routines */
46407 +/***********************************************************************/
46408 +
46409 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46410 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46411 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46412 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46413 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46414 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46415 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46416 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46417 +
46418 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46419 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46420 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46421 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46422 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46423 +
46424 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46425 +t_Error KgInit(t_FmPcd *p_FmPcd);
46426 +t_Error KgFree(t_FmPcd *p_FmPcd);
46427 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46428 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46429 +void KgEnable(t_FmPcd *p_FmPcd);
46430 +void KgDisable(t_FmPcd *p_FmPcd);
46431 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46432 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46433 +
46434 +/* only for MULTI partittion */
46435 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46436 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46437 +/* only for SINGLE partittion */
46438 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46439 +
46440 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46441 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46442 +
46443 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46444 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46445 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46446 +void PlcrEnable(t_FmPcd *p_FmPcd);
46447 +void PlcrDisable(t_FmPcd *p_FmPcd);
46448 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46449 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46450 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46451 + uint8_t hardwarePortId,
46452 + uint16_t numOfProfiles,
46453 + uint16_t base);
46454 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46455 +
46456 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46457 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46458 +void PrsEnable(t_FmPcd *p_FmPcd);
46459 +void PrsDisable(t_FmPcd *p_FmPcd);
46460 +void PrsFree(t_FmPcd *p_FmPcd );
46461 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46462 +
46463 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46464 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46465 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46466 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46467 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46468 +
46469 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46470 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46471 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46472 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46473 + t_Handle p_Ad,
46474 + t_Handle *p_AdNewPtr);
46475 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46476 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46477 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46478 +#ifdef FM_CAPWAP_SUPPORT
46479 +t_Handle FmPcdManipApplSpecificBuild(void);
46480 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46481 +#endif /* FM_CAPWAP_SUPPORT */
46482 +#if (DPAA_VERSION >= 11)
46483 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46484 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46485 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46486 +
46487 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46488 + t_Handle h_ReplicGroup,
46489 + t_List *p_AdTables,
46490 + uint32_t *p_NumOfAdTables);
46491 +#endif /* (DPAA_VERSION >= 11) */
46492 +
46493 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46494 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46495 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46496 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46497 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46498 +
46499 +typedef struct
46500 +{
46501 + t_Handle h_StatsAd;
46502 + t_Handle h_StatsCounters;
46503 +#if (DPAA_VERSION >= 11)
46504 + t_Handle h_StatsFLRs;
46505 +#endif /* (DPAA_VERSION >= 11) */
46506 +} t_FmPcdCcStatsParams;
46507 +
46508 +void NextStepAd(t_Handle h_Ad,
46509 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46510 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46511 + t_FmPcd *p_FmPcd);
46512 +void ReleaseLst(t_List *p_List);
46513 +
46514 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46515 +{
46516 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46517 + ASSERT_COND(p_FmPcd);
46518 + return p_FmPcd->h_FmMuram;
46519 +}
46520 +
46521 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46522 +{
46523 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46524 + ASSERT_COND(p_FmPcd);
46525 + return p_FmPcd->physicalMuramBase;
46526 +}
46527 +
46528 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46529 +{
46530 + ASSERT_COND(p_Lock);
46531 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46532 +}
46533 +
46534 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46535 +{
46536 + ASSERT_COND(p_Lock);
46537 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46538 +}
46539 +
46540 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46541 +{
46542 + uint32_t intFlags;
46543 +
46544 + ASSERT_COND(p_Lock);
46545 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46546 + if (p_Lock->flag)
46547 + {
46548 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46549 + return FALSE;
46550 + }
46551 + p_Lock->flag = TRUE;
46552 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46553 + return TRUE;
46554 +}
46555 +
46556 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46557 +{
46558 + ASSERT_COND(p_Lock);
46559 + p_Lock->flag = FALSE;
46560 +}
46561 +
46562 +
46563 +#endif /* __FM_PCD_H */
46564 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46565 new file mode 100644
46566 index 00000000..325d3e33
46567 --- /dev/null
46568 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46569 @@ -0,0 +1,280 @@
46570 +/*
46571 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46572 + *
46573 + * Redistribution and use in source and binary forms, with or without
46574 + * modification, are permitted provided that the following conditions are met:
46575 + * * Redistributions of source code must retain the above copyright
46576 + * notice, this list of conditions and the following disclaimer.
46577 + * * Redistributions in binary form must reproduce the above copyright
46578 + * notice, this list of conditions and the following disclaimer in the
46579 + * documentation and/or other materials provided with the distribution.
46580 + * * Neither the name of Freescale Semiconductor nor the
46581 + * names of its contributors may be used to endorse or promote products
46582 + * derived from this software without specific prior written permission.
46583 + *
46584 + *
46585 + * ALTERNATIVELY, this software may be distributed under the terms of the
46586 + * GNU General Public License ("GPL") as published by the Free Software
46587 + * Foundation, either version 2 of that License or (at your option) any
46588 + * later version.
46589 + *
46590 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46591 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46592 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46593 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46594 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46595 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46596 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46597 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46598 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46599 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46600 + */
46601 +
46602 +
46603 +/**************************************************************************//**
46604 + @File fm_pcd_ipc.h
46605 +
46606 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46607 +*//***************************************************************************/
46608 +#ifndef __FM_PCD_IPC_H
46609 +#define __FM_PCD_IPC_H
46610 +
46611 +#include "std_ext.h"
46612 +
46613 +
46614 +/**************************************************************************//**
46615 + @Group FM_grp Frame Manager API
46616 +
46617 + @Description FM API functions, definitions and enums
46618 +
46619 + @{
46620 +*//***************************************************************************/
46621 +
46622 +
46623 +#if defined(__MWERKS__) && !defined(__GNUC__)
46624 +#pragma pack(push,1)
46625 +#endif /* defined(__MWERKS__) && ... */
46626 +
46627 +/**************************************************************************//**
46628 + @Description Structure for getting a sw parser address according to a label
46629 + Fields commented 'IN' are passed by the port module to be used
46630 + by the FM module.
46631 + Fields commented 'OUT' will be filled by FM before returning to port.
46632 +*//***************************************************************************/
46633 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46634 +{
46635 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46636 + the sw parser code. */
46637 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46638 + attachments for the same header, use this
46639 +
46640 + index to distinguish between them. */
46641 +} _PackedType t_FmPcdIpcSwPrsLable;
46642 +
46643 +/**************************************************************************//**
46644 + @Description Structure for port-PCD communication.
46645 + Fields commented 'IN' are passed by the port module to be used
46646 + by the FM module.
46647 + Fields commented 'OUT' will be filled by FM before returning to port.
46648 + Some fields are optional (depending on configuration) and
46649 + will be analized by the port and FM modules accordingly.
46650 +*//***************************************************************************/
46651 +
46652 +typedef struct t_FmPcdIpcKgSchemesParams
46653 +{
46654 + uint8_t guestId;
46655 + uint8_t numOfSchemes;
46656 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46657 +} _PackedType t_FmPcdIpcKgSchemesParams;
46658 +
46659 +typedef struct t_FmPcdIpcKgClsPlanParams
46660 +{
46661 + uint8_t guestId;
46662 + uint16_t numOfClsPlanEntries;
46663 + uint8_t clsPlanBase;
46664 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46665 +
46666 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46667 +{
46668 + uint8_t hardwarePortId;
46669 + bool include;
46670 +} _PackedType t_FmPcdIpcPrsIncludePort;
46671 +
46672 +
46673 +#define FM_PCD_MAX_REPLY_SIZE 16
46674 +#define FM_PCD_MAX_MSG_SIZE 36
46675 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46676 +
46677 +typedef _Packed struct {
46678 + uint32_t msgId;
46679 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46680 +} _PackedType t_FmPcdIpcMsg;
46681 +
46682 +typedef _Packed struct t_FmPcdIpcReply {
46683 + uint32_t error;
46684 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46685 +} _PackedType t_FmPcdIpcReply;
46686 +
46687 +typedef _Packed struct t_FmIpcResourceAllocParams {
46688 + uint8_t guestId;
46689 + uint16_t base;
46690 + uint16_t num;
46691 +}_PackedType t_FmIpcResourceAllocParams;
46692 +
46693 +#if defined(__MWERKS__) && !defined(__GNUC__)
46694 +#pragma pack(pop)
46695 +#endif /* defined(__MWERKS__) && ... */
46696 +
46697 +
46698 +
46699 +/**************************************************************************//**
46700 + @Function FM_PCD_ALLOC_KG_SCHEMES
46701 +
46702 + @Description Used by FM PCD front-end in order to allocate KG resources
46703 +
46704 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46705 +*//***************************************************************************/
46706 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46707 +
46708 +/**************************************************************************//**
46709 + @Function FM_PCD_FREE_KG_SCHEMES
46710 +
46711 + @Description Used by FM PCD front-end in order to Free KG resources
46712 +
46713 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46714 +*//***************************************************************************/
46715 +#define FM_PCD_FREE_KG_SCHEMES 4
46716 +
46717 +/**************************************************************************//**
46718 + @Function FM_PCD_ALLOC_PROFILES
46719 +
46720 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46721 +
46722 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46723 +*//***************************************************************************/
46724 +#define FM_PCD_ALLOC_PROFILES 5
46725 +
46726 +/**************************************************************************//**
46727 + @Function FM_PCD_FREE_PROFILES
46728 +
46729 + @Description Used by FM PCD front-end in order to Free Policer profiles
46730 +
46731 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46732 +*//***************************************************************************/
46733 +#define FM_PCD_FREE_PROFILES 6
46734 +
46735 +/**************************************************************************//**
46736 + @Function FM_PCD_SET_PORT_PROFILES
46737 +
46738 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46739 + for specific port
46740 +
46741 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46742 +*//***************************************************************************/
46743 +#define FM_PCD_SET_PORT_PROFILES 7
46744 +
46745 +/**************************************************************************//**
46746 + @Function FM_PCD_CLEAR_PORT_PROFILES
46747 +
46748 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46749 + for specific port
46750 +
46751 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46752 +*//***************************************************************************/
46753 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46754 +
46755 +/**************************************************************************//**
46756 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46757 +
46758 + @Description Used by FM PCD front-end in order to get MURAM base address
46759 +
46760 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46761 +*//***************************************************************************/
46762 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46763 +
46764 +/**************************************************************************//**
46765 + @Function FM_PCD_GET_SW_PRS_OFFSET
46766 +
46767 + @Description Used by FM front-end to get the SW parser offset of the start of
46768 + code relevant to a given label.
46769 +
46770 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46771 +*//***************************************************************************/
46772 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46773 +
46774 +/**************************************************************************//**
46775 + @Function FM_PCD_MASTER_IS_ENABLED
46776 +
46777 + @Description Used by FM front-end in order to verify
46778 + PCD enablement.
46779 +
46780 + @Param[in] bool Pointer
46781 +*//***************************************************************************/
46782 +#define FM_PCD_MASTER_IS_ENABLED 15
46783 +
46784 +/**************************************************************************//**
46785 + @Function FM_PCD_GUEST_DISABLE
46786 +
46787 + @Description Used by FM front-end to inform back-end when
46788 + front-end PCD is disabled
46789 +
46790 + @Param[in] None
46791 +*//***************************************************************************/
46792 +#define FM_PCD_GUEST_DISABLE 16
46793 +
46794 +/**************************************************************************//**
46795 + @Function FM_PCD_FREE_KG_CLSPLAN
46796 +
46797 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46798 +
46799 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46800 +*//***************************************************************************/
46801 +#define FM_PCD_FREE_KG_CLSPLAN 22
46802 +
46803 +/**************************************************************************//**
46804 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46805 +
46806 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46807 +
46808 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46809 +*//***************************************************************************/
46810 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46811 +
46812 +/**************************************************************************//**
46813 + @Function FM_PCD_MASTER_IS_ALIVE
46814 +
46815 + @Description Used by FM front-end to check that back-end exists
46816 +
46817 + @Param[in] None
46818 +*//***************************************************************************/
46819 +#define FM_PCD_MASTER_IS_ALIVE 24
46820 +
46821 +/**************************************************************************//**
46822 + @Function FM_PCD_GET_COUNTER
46823 +
46824 + @Description Used by FM front-end to read PCD counters
46825 +
46826 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46827 +*//***************************************************************************/
46828 +#define FM_PCD_GET_COUNTER 25
46829 +
46830 +/**************************************************************************//**
46831 + @Function FM_PCD_PRS_INC_PORT_STATS
46832 +
46833 + @Description Used by FM front-end to set/clear statistics for port
46834 +
46835 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46836 +*//***************************************************************************/
46837 +#define FM_PCD_PRS_INC_PORT_STATS 26
46838 +
46839 +#if (DPAA_VERSION >= 11)
46840 +/* TODO - doc */
46841 +#define FM_PCD_ALLOC_SP 27
46842 +#endif /* (DPAA_VERSION >= 11) */
46843 +
46844 +
46845 +/** @} */ /* end of FM_PCD_IPC_grp group */
46846 +/** @} */ /* end of FM_grp group */
46847 +
46848 +
46849 +#endif /* __FM_PCD_IPC_H */
46850 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46851 new file mode 100644
46852 index 00000000..e3753305
46853 --- /dev/null
46854 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46855 @@ -0,0 +1,1847 @@
46856 +/*
46857 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46858 + *
46859 + * Redistribution and use in source and binary forms, with or without
46860 + * modification, are permitted provided that the following conditions are met:
46861 + * * Redistributions of source code must retain the above copyright
46862 + * notice, this list of conditions and the following disclaimer.
46863 + * * Redistributions in binary form must reproduce the above copyright
46864 + * notice, this list of conditions and the following disclaimer in the
46865 + * documentation and/or other materials provided with the distribution.
46866 + * * Neither the name of Freescale Semiconductor nor the
46867 + * names of its contributors may be used to endorse or promote products
46868 + * derived from this software without specific prior written permission.
46869 + *
46870 + *
46871 + * ALTERNATIVELY, this software may be distributed under the terms of the
46872 + * GNU General Public License ("GPL") as published by the Free Software
46873 + * Foundation, either version 2 of that License or (at your option) any
46874 + * later version.
46875 + *
46876 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46877 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46878 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46879 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46880 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46881 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46882 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46883 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46884 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46885 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46886 + */
46887 +
46888 +
46889 +/******************************************************************************
46890 + @File fm_plcr.c
46891 +
46892 + @Description FM PCD POLICER...
46893 +*//***************************************************************************/
46894 +#include <linux/math64.h>
46895 +#include "std_ext.h"
46896 +#include "error_ext.h"
46897 +#include "string_ext.h"
46898 +#include "debug_ext.h"
46899 +#include "net_ext.h"
46900 +#include "fm_ext.h"
46901 +
46902 +#include "fm_common.h"
46903 +#include "fm_pcd.h"
46904 +#include "fm_hc.h"
46905 +#include "fm_pcd_ipc.h"
46906 +#include "fm_plcr.h"
46907 +
46908 +
46909 +/****************************************/
46910 +/* static functions */
46911 +/****************************************/
46912 +
46913 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
46914 +{
46915 + ASSERT_COND(h_Profile);
46916 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46917 +}
46918 +
46919 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
46920 +{
46921 + ASSERT_COND(h_Profile);
46922 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
46923 +}
46924 +
46925 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
46926 +{
46927 + ASSERT_COND(h_Profile);
46928 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46929 +}
46930 +
46931 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
46932 +{
46933 + ASSERT_COND(h_Profile);
46934 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46935 +}
46936 +
46937 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
46938 +{
46939 + ASSERT_COND(h_FmPcdPlcr);
46940 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
46941 +}
46942 +
46943 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46944 +{
46945 + ASSERT_COND(h_FmPcdPlcr);
46946 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
46947 +}
46948 +
46949 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
46950 +{
46951 + ASSERT_COND(h_FmPcdPlcr);
46952 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
46953 +}
46954 +
46955 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46956 +{
46957 + ASSERT_COND(h_FmPcdPlcr);
46958 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
46959 +}
46960 +
46961 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
46962 +{
46963 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46964 + uint16_t i;
46965 +
46966 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
46967 +
46968 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
46969 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
46970 + return TRUE;
46971 + return FALSE;
46972 +}
46973 +
46974 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
46975 +{
46976 + uint32_t nia;
46977 + uint16_t absoluteProfileId;
46978 + uint8_t relativeSchemeId, physicalSchemeId;
46979 +
46980 + nia = FM_PCD_PLCR_NIA_VALID;
46981 +
46982 + switch (nextEngine)
46983 + {
46984 + case e_FM_PCD_DONE :
46985 + switch (p_NextEngineParams->action)
46986 + {
46987 + case e_FM_PCD_DROP_FRAME :
46988 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
46989 + break;
46990 + case e_FM_PCD_ENQ_FRAME:
46991 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
46992 + break;
46993 + default:
46994 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46995 + }
46996 + break;
46997 + case e_FM_PCD_KG:
46998 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
46999 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
47000 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
47001 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
47002 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
47003 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
47004 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
47005 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
47006 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
47007 + break;
47008 + case e_FM_PCD_PLCR:
47009 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
47010 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
47011 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
47012 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
47013 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
47014 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
47015 + break;
47016 + default:
47017 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47018 + }
47019 +
47020 + *nextAction = nia;
47021 +
47022 + return E_OK;
47023 +}
47024 +
47025 +static uint32_t CalcFPP(uint32_t fpp)
47026 +{
47027 + if (fpp > 15)
47028 + return 15 - (0x1f - fpp);
47029 + else
47030 + return 16 + fpp;
47031 +}
47032 +
47033 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
47034 + uint32_t rate,
47035 + uint64_t tsuInTenthNano,
47036 + uint32_t fppShift,
47037 + uint64_t *p_Integer,
47038 + uint64_t *p_Fraction)
47039 +{
47040 + uint64_t tmp, div;
47041 +
47042 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
47043 + {
47044 + /* now we calculate the initial integer for the bigger rate */
47045 + /* from Kbps to Bytes/TSU */
47046 + tmp = (uint64_t)rate;
47047 + tmp *= 1000; /* kb --> b */
47048 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47049 +
47050 + div = 1000000000; /* nano */
47051 + div *= 10; /* 10 nano */
47052 + div *= 8; /* bit to byte */
47053 + }
47054 + else
47055 + {
47056 + /* now we calculate the initial integer for the bigger rate */
47057 + /* from Kbps to Bytes/TSU */
47058 + tmp = (uint64_t)rate;
47059 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47060 +
47061 + div = 1000000000; /* nano */
47062 + div *= 10; /* 10 nano */
47063 + }
47064 + *p_Integer = div64_u64(tmp<<fppShift, div);
47065 +
47066 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
47067 + * For precision, we will multiply by 2^16. we do not divid back, since we write
47068 + * this value as fraction - see spec.
47069 + */
47070 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
47071 +}
47072 +
47073 +/* .......... */
47074 +
47075 +static void CalcRates(uint32_t bitFor1Micro,
47076 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
47077 + uint32_t *cir,
47078 + uint32_t *cbs,
47079 + uint32_t *pir_eir,
47080 + uint32_t *pbs_ebs,
47081 + uint32_t *fpp)
47082 +{
47083 + uint64_t integer, fraction;
47084 + uint32_t temp, tsuInTenthNanos;
47085 + uint8_t fppShift=0;
47086 +
47087 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
47088 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
47089 +
47090 + /* we choose the faster rate to calibrate fpp */
47091 + /* The meaning of this step:
47092 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
47093 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
47094 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
47095 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
47096 + * high rate, as many bits as possible for fraction at low rate.
47097 + */
47098 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
47099 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47100 + else
47101 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47102 +
47103 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
47104 + * the LSB bits are for the fraction */
47105 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
47106 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
47107 + * take max FP = 31.
47108 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
47109 + * limited by the 10G physical port.
47110 + */
47111 + if (temp != 0)
47112 + {
47113 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
47114 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
47115 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
47116 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
47117 + * to use these bits for the fraction. in this way we will have for fraction - the number
47118 + * of "0" bits and the rest - for integer.
47119 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
47120 + * one bit to the left - preserving the relationship and achieving more bits
47121 + * for integer in the TS.
47122 + */
47123 +
47124 + /* count zeroes left of the higher used bit (in order to shift the value such that
47125 + * unused bits may be used for fraction).
47126 + */
47127 + while ((temp & 0x80000000) == 0)
47128 + {
47129 + temp = temp << 1;
47130 + fppShift++;
47131 + }
47132 + if (fppShift > 15)
47133 + {
47134 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
47135 + return;
47136 + }
47137 + }
47138 + else
47139 + {
47140 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
47141 + if (!temp)
47142 + /* integer and fraction are 0, we set FP to its max val */
47143 + fppShift = 31;
47144 + else
47145 + {
47146 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
47147 + * + all left zeroes of the fraction. */
47148 + fppShift=16;
47149 + /* count zeroes left of the higher used bit (in order to shift the value such that
47150 + * unused bits may be used for fraction).
47151 + */
47152 + while ((temp & 0x8000) == 0)
47153 + {
47154 + temp = temp << 1;
47155 + fppShift++;
47156 + }
47157 + }
47158 + }
47159 +
47160 + /*
47161 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
47162 + * fraction and the rest for integer */
47163 + /* now we re-calculate cir and pir_eir with the calculated FP */
47164 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47165 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47166 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47167 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47168 +
47169 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
47170 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
47171 +
47172 + /* convert FP as it should be written to reg.
47173 + * 0-15 --> 16-31
47174 + * 16-31 --> 0-15
47175 + */
47176 + *fpp = CalcFPP(fppShift);
47177 +}
47178 +
47179 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
47180 +{
47181 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47182 +
47183 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47184 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
47185 +
47186 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
47187 +}
47188 +
47189 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
47190 + t_FmPcdPlcrProfileParams *p_ProfileParams,
47191 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
47192 +{
47193 + t_Error err = E_OK;
47194 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
47195 +
47196 + ASSERT_COND(p_FmPcd);
47197 +
47198 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
47199 + if (bitFor1Micro == 0)
47200 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
47201 +
47202 +/* Set G, Y, R Nia */
47203 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
47204 + if (err)
47205 + RETURN_ERROR(MAJOR, err, NO_MSG);
47206 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
47207 + if (err)
47208 + RETURN_ERROR(MAJOR, err, NO_MSG);
47209 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
47210 + if (err)
47211 + RETURN_ERROR(MAJOR, err, NO_MSG);
47212 +
47213 +/* Mode fmpl_pemode */
47214 + pemode = FM_PCD_PLCR_PEMODE_PI;
47215 +
47216 + switch (p_ProfileParams->algSelection)
47217 + {
47218 + case e_FM_PCD_PLCR_PASS_THROUGH:
47219 + p_PlcrRegs->fmpl_pecir = 0;
47220 + p_PlcrRegs->fmpl_pecbs = 0;
47221 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47222 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47223 + p_PlcrRegs->fmpl_pelts = 0;
47224 + p_PlcrRegs->fmpl_pects = 0;
47225 + p_PlcrRegs->fmpl_pepts_ets = 0;
47226 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47227 + switch (p_ProfileParams->colorMode)
47228 + {
47229 + case e_FM_PCD_PLCR_COLOR_BLIND:
47230 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47231 + switch (p_ProfileParams->color.dfltColor)
47232 + {
47233 + case e_FM_PCD_PLCR_GREEN:
47234 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47235 + break;
47236 + case e_FM_PCD_PLCR_YELLOW:
47237 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47238 + break;
47239 + case e_FM_PCD_PLCR_RED:
47240 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47241 + break;
47242 + case e_FM_PCD_PLCR_OVERRIDE:
47243 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47244 + break;
47245 + default:
47246 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47247 + }
47248 +
47249 + break;
47250 + case e_FM_PCD_PLCR_COLOR_AWARE:
47251 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47252 + break;
47253 + default:
47254 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47255 + }
47256 + break;
47257 +
47258 + case e_FM_PCD_PLCR_RFC_2698:
47259 + /* Select algorithm MODE[ALG] = "01" */
47260 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47261 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47262 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47263 + goto cont_rfc;
47264 + case e_FM_PCD_PLCR_RFC_4115:
47265 + /* Select algorithm MODE[ALG] = "10" */
47266 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47267 +cont_rfc:
47268 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47269 + switch (p_ProfileParams->colorMode)
47270 + {
47271 + case e_FM_PCD_PLCR_COLOR_BLIND:
47272 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47273 + break;
47274 + case e_FM_PCD_PLCR_COLOR_AWARE:
47275 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47276 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47277 + switch (p_ProfileParams->color.override)
47278 + {
47279 + case e_FM_PCD_PLCR_GREEN:
47280 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47281 + break;
47282 + case e_FM_PCD_PLCR_YELLOW:
47283 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47284 + break;
47285 + case e_FM_PCD_PLCR_RED:
47286 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47287 + break;
47288 + case e_FM_PCD_PLCR_OVERRIDE:
47289 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47290 + break;
47291 + default:
47292 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47293 + }
47294 + break;
47295 + default:
47296 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47297 + }
47298 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47299 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47300 + {
47301 + case e_FM_PCD_PLCR_BYTE_MODE :
47302 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47303 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47304 + {
47305 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47306 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47307 + break;
47308 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47309 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47310 + break;
47311 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47312 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47313 + break;
47314 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47315 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47316 + break;
47317 + default:
47318 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47319 + }
47320 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47321 + {
47322 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47323 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47324 + break;
47325 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47326 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47327 + break;
47328 + default:
47329 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47330 + }
47331 + break;
47332 + case e_FM_PCD_PLCR_PACKET_MODE :
47333 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47334 + break;
47335 + default:
47336 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47337 + }
47338 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47339 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47340 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47341 +
47342 + /* Configure Traffic Parameters*/
47343 + {
47344 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47345 +
47346 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47347 +
47348 + /* Set Committed Information Rate (CIR) */
47349 + p_PlcrRegs->fmpl_pecir = cir;
47350 + /* Set Committed Burst Size (CBS). */
47351 + p_PlcrRegs->fmpl_pecbs = cbs;
47352 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47353 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47354 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47355 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47356 +
47357 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47358 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47359 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47360 + /* Committed Rate Token Bucket Size (CTS) */
47361 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47362 +
47363 + /* Set the FPP based on calculation */
47364 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47365 + }
47366 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47367 + default:
47368 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47369 + }
47370 +
47371 + p_PlcrRegs->fmpl_pemode = pemode;
47372 +
47373 + p_PlcrRegs->fmpl_pegnia = gnia;
47374 + p_PlcrRegs->fmpl_peynia = ynia;
47375 + p_PlcrRegs->fmpl_pernia = rnia;
47376 +
47377 + /* Zero Counters */
47378 + p_PlcrRegs->fmpl_pegpc = 0;
47379 + p_PlcrRegs->fmpl_peypc = 0;
47380 + p_PlcrRegs->fmpl_perpc = 0;
47381 + p_PlcrRegs->fmpl_perypc = 0;
47382 + p_PlcrRegs->fmpl_perrpc = 0;
47383 +
47384 + return E_OK;
47385 +}
47386 +
47387 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47388 +{
47389 + uint32_t profilesFound;
47390 + uint16_t i, k=0;
47391 + uint32_t intFlags;
47392 +
47393 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47394 +
47395 + if (!numOfProfiles)
47396 + return E_OK;
47397 +
47398 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47399 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47400 +
47401 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47402 + /* Find numOfProfiles free profiles (may be spread) */
47403 + profilesFound = 0;
47404 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47405 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47406 + {
47407 + profilesFound++;
47408 + profilesIds[k] = i;
47409 + k++;
47410 + if (profilesFound == numOfProfiles)
47411 + break;
47412 + }
47413 +
47414 + if (profilesFound != numOfProfiles)
47415 + {
47416 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47417 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47418 + }
47419 +
47420 + for (i = 0;i<k;i++)
47421 + {
47422 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47423 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47424 + }
47425 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47426 +
47427 + return E_OK;
47428 +}
47429 +
47430 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47431 +{
47432 + uint16_t i;
47433 +
47434 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47435 +
47436 + ASSERT_COND(numOfProfiles);
47437 +
47438 + for (i=0; i < numOfProfiles; i++)
47439 + {
47440 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47441 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47442 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47443 + }
47444 +}
47445 +
47446 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47447 +{
47448 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47449 +
47450 + /* this routine is protected by calling routine */
47451 +
47452 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47453 +
47454 + if (set)
47455 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47456 + else
47457 + {
47458 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47459 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47460 + }
47461 +}
47462 +
47463 +/*********************************************/
47464 +/*............Policer Exception..............*/
47465 +/*********************************************/
47466 +static void EventsCB(t_Handle h_FmPcd)
47467 +{
47468 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47469 + uint32_t event, mask, force;
47470 +
47471 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47472 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47473 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47474 +
47475 + event &= mask;
47476 +
47477 + /* clear the forced events */
47478 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47479 + if (force & event)
47480 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47481 +
47482 +
47483 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47484 +
47485 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47486 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47487 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47488 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47489 +}
47490 +
47491 +/* ..... */
47492 +
47493 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47494 +{
47495 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47496 + uint32_t event, force, captureReg, mask;
47497 +
47498 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47499 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47500 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47501 +
47502 + event &= mask;
47503 +
47504 + /* clear the forced events */
47505 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47506 + if (force & event)
47507 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47508 +
47509 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47510 +
47511 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47512 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47513 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47514 + {
47515 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47516 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47517 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47518 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47519 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47520 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47521 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47522 + }
47523 +}
47524 +
47525 +
47526 +/*****************************************************************************/
47527 +/* Inter-module API routines */
47528 +/*****************************************************************************/
47529 +
47530 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47531 +{
47532 + t_FmPcdPlcr *p_FmPcdPlcr;
47533 + uint16_t i=0;
47534 +
47535 + UNUSED(p_FmPcd);
47536 + UNUSED(p_FmPcdParams);
47537 +
47538 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47539 + if (!p_FmPcdPlcr)
47540 + {
47541 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47542 + return NULL;
47543 + }
47544 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47545 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47546 + {
47547 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47548 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47549 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47550 + }
47551 +
47552 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47553 +
47554 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47555 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47556 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47557 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47558 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47559 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47560 +
47561 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47562 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47563 +
47564 + return p_FmPcdPlcr;
47565 +}
47566 +
47567 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47568 +{
47569 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47570 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47571 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47572 + t_Error err = E_OK;
47573 + uint32_t tmpReg32 = 0;
47574 + uint16_t base;
47575 +
47576 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47577 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47578 +
47579 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47580 + if (!p_FmPcdPlcr->h_HwSpinlock)
47581 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47582 +
47583 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47584 + if (!p_FmPcdPlcr->h_SwSpinlock)
47585 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47586 +
47587 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47588 + p_FmPcdPlcr->partPlcrProfilesBase,
47589 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47590 + p_FmPcd->guestId);
47591 + if (base == (uint16_t)ILLEGAL_BASE)
47592 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47593 +
47594 + if (p_FmPcdPlcr->numOfSharedProfiles)
47595 + {
47596 + err = AllocSharedProfiles(p_FmPcd,
47597 + p_FmPcdPlcr->numOfSharedProfiles,
47598 + p_FmPcdPlcr->sharedProfilesIds);
47599 + if (err)
47600 + RETURN_ERROR(MAJOR, err,NO_MSG);
47601 + }
47602 +
47603 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47604 + return E_OK;
47605 +
47606 + /**********************FMPL_GCR******************/
47607 + tmpReg32 = 0;
47608 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47609 + if (p_Param->plcrAutoRefresh)
47610 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47611 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47612 +
47613 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47614 + /**********************FMPL_GCR******************/
47615 +
47616 + /**********************FMPL_EEVR******************/
47617 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47618 + /**********************FMPL_EEVR******************/
47619 + /**********************FMPL_EIER******************/
47620 + tmpReg32 = 0;
47621 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47622 + {
47623 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47624 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47625 + }
47626 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47627 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47628 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47629 + /**********************FMPL_EIER******************/
47630 +
47631 + /**********************FMPL_EVR******************/
47632 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47633 + /**********************FMPL_EVR******************/
47634 + /**********************FMPL_IER******************/
47635 + tmpReg32 = 0;
47636 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47637 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47638 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47639 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47640 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47641 + /**********************FMPL_IER******************/
47642 +
47643 + /* register even if no interrupts enabled, to allow future enablement */
47644 + FmRegisterIntr(p_FmPcd->h_Fm,
47645 + e_FM_MOD_PLCR,
47646 + 0,
47647 + e_FM_INTR_TYPE_ERR,
47648 + ErrorExceptionsCB,
47649 + p_FmPcd);
47650 + FmRegisterIntr(p_FmPcd->h_Fm,
47651 + e_FM_MOD_PLCR,
47652 + 0,
47653 + e_FM_INTR_TYPE_NORMAL,
47654 + EventsCB,
47655 + p_FmPcd);
47656 +
47657 + /* driver initializes one DFLT profile at the last entry*/
47658 + /**********************FMPL_DPMR******************/
47659 + tmpReg32 = 0;
47660 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47661 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47662 +
47663 + return E_OK;
47664 +}
47665 +
47666 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47667 +{
47668 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47669 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47670 +
47671 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47672 + FreeSharedProfiles(p_FmPcd,
47673 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47674 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47675 +
47676 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47677 + PlcrFreeProfilesForPartition(p_FmPcd,
47678 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47679 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47680 + p_FmPcd->guestId);
47681 +
47682 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47683 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47684 +
47685 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47686 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47687 +
47688 + return E_OK;
47689 +}
47690 +
47691 +void PlcrEnable(t_FmPcd *p_FmPcd)
47692 +{
47693 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47694 +
47695 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47696 +}
47697 +
47698 +void PlcrDisable(t_FmPcd *p_FmPcd)
47699 +{
47700 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47701 +
47702 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47703 +}
47704 +
47705 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47706 +{
47707 + uint32_t intFlags;
47708 + uint16_t profilesFound = 0;
47709 + int i = 0;
47710 +
47711 + ASSERT_COND(p_FmPcd);
47712 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47713 +
47714 + if (!numOfProfiles)
47715 + return 0;
47716 +
47717 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47718 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47719 + return (uint16_t)ILLEGAL_BASE;
47720 +
47721 + if (p_FmPcd->h_IpcSession)
47722 + {
47723 + t_FmIpcResourceAllocParams ipcAllocParams;
47724 + t_FmPcdIpcMsg msg;
47725 + t_FmPcdIpcReply reply;
47726 + t_Error err;
47727 + uint32_t replyLength;
47728 +
47729 + memset(&msg, 0, sizeof(msg));
47730 + memset(&reply, 0, sizeof(reply));
47731 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47732 + ipcAllocParams.guestId = p_FmPcd->guestId;
47733 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47734 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47735 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47736 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47737 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47738 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47739 + (uint8_t*)&msg,
47740 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47741 + (uint8_t*)&reply,
47742 + &replyLength,
47743 + NULL,
47744 + NULL);
47745 + if ((err != E_OK) ||
47746 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47747 + {
47748 + REPORT_ERROR(MAJOR, err, NO_MSG);
47749 + return (uint16_t)ILLEGAL_BASE;
47750 + }
47751 + else
47752 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47753 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47754 + {
47755 + REPORT_ERROR(MAJOR, err, NO_MSG);
47756 + return (uint16_t)ILLEGAL_BASE;
47757 + }
47758 + }
47759 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47760 + {
47761 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47762 + return (uint16_t)ILLEGAL_BASE;
47763 + }
47764 +
47765 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47766 + for (i=base; i<(base+numOfProfiles); i++)
47767 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47768 + profilesFound++;
47769 + else
47770 + break;
47771 +
47772 + if (profilesFound == numOfProfiles)
47773 + for (i=base; i<(base+numOfProfiles); i++)
47774 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47775 + else
47776 + {
47777 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47778 + return (uint16_t)ILLEGAL_BASE;
47779 + }
47780 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47781 +
47782 + return base;
47783 +}
47784 +
47785 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47786 +{
47787 + int i = 0;
47788 +
47789 + ASSERT_COND(p_FmPcd);
47790 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47791 +
47792 + if (p_FmPcd->h_IpcSession)
47793 + {
47794 + t_FmIpcResourceAllocParams ipcAllocParams;
47795 + t_FmPcdIpcMsg msg;
47796 + t_Error err;
47797 +
47798 + memset(&msg, 0, sizeof(msg));
47799 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47800 + ipcAllocParams.guestId = p_FmPcd->guestId;
47801 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47802 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47803 + msg.msgId = FM_PCD_FREE_PROFILES;
47804 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47805 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47806 + (uint8_t*)&msg,
47807 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47808 + NULL,
47809 + NULL,
47810 + NULL,
47811 + NULL);
47812 + if (err != E_OK)
47813 + REPORT_ERROR(MAJOR, err, NO_MSG);
47814 + return;
47815 + }
47816 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47817 + {
47818 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47819 + return;
47820 + }
47821 +
47822 + for (i=base; i<(base+numOfProfiles); i++)
47823 + {
47824 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47825 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47826 + else
47827 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47828 + }
47829 +}
47830 +
47831 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47832 + uint8_t hardwarePortId,
47833 + uint16_t numOfProfiles,
47834 + uint16_t base)
47835 +{
47836 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47837 + uint32_t log2Num, tmpReg32;
47838 +
47839 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47840 + !p_Regs &&
47841 + p_FmPcd->h_IpcSession)
47842 + {
47843 + t_FmIpcResourceAllocParams ipcAllocParams;
47844 + t_FmPcdIpcMsg msg;
47845 + t_Error err;
47846 +
47847 + memset(&msg, 0, sizeof(msg));
47848 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47849 + ipcAllocParams.guestId = hardwarePortId;
47850 + ipcAllocParams.num = numOfProfiles;
47851 + ipcAllocParams.base = base;
47852 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47853 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47854 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47855 + (uint8_t*)&msg,
47856 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47857 + NULL,
47858 + NULL,
47859 + NULL,
47860 + NULL);
47861 + if (err != E_OK)
47862 + RETURN_ERROR(MAJOR, err, NO_MSG);
47863 + return E_OK;
47864 + }
47865 + else if (!p_Regs)
47866 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47867 + ("Either IPC or 'baseAddress' is required!"));
47868 +
47869 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47870 +
47871 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
47872 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
47873 + ("The requesting port has already an allocated profiles window."));
47874 +
47875 + /**********************FMPL_PMRx******************/
47876 + LOG2((uint64_t)numOfProfiles, log2Num);
47877 + tmpReg32 = base;
47878 + tmpReg32 |= log2Num << 16;
47879 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
47880 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
47881 +
47882 + return E_OK;
47883 +}
47884 +
47885 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
47886 +{
47887 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47888 +
47889 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47890 + !p_Regs &&
47891 + p_FmPcd->h_IpcSession)
47892 + {
47893 + t_FmIpcResourceAllocParams ipcAllocParams;
47894 + t_FmPcdIpcMsg msg;
47895 + t_Error err;
47896 +
47897 + memset(&msg, 0, sizeof(msg));
47898 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47899 + ipcAllocParams.guestId = hardwarePortId;
47900 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
47901 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47902 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47903 + (uint8_t*)&msg,
47904 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47905 + NULL,
47906 + NULL,
47907 + NULL,
47908 + NULL);
47909 + if (err != E_OK)
47910 + RETURN_ERROR(MAJOR, err, NO_MSG);
47911 + return E_OK;
47912 + }
47913 + else if (!p_Regs)
47914 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47915 + ("Either IPC or 'baseAddress' is required!"));
47916 +
47917 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47918 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
47919 +
47920 + return E_OK;
47921 +}
47922 +
47923 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
47924 +{
47925 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47926 + t_Error err = E_OK;
47927 + uint32_t profilesFound;
47928 + uint32_t intFlags;
47929 + uint16_t i, first, swPortIndex = 0;
47930 +
47931 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47932 +
47933 + if (!numOfProfiles)
47934 + return E_OK;
47935 +
47936 + ASSERT_COND(hardwarePortId);
47937 +
47938 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47939 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47940 +
47941 + if (!POWER_OF_2(numOfProfiles))
47942 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
47943 +
47944 + first = 0;
47945 + profilesFound = 0;
47946 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47947 +
47948 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
47949 + {
47950 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47951 + {
47952 + profilesFound++;
47953 + i++;
47954 + if (profilesFound == numOfProfiles)
47955 + break;
47956 + }
47957 + else
47958 + {
47959 + profilesFound = 0;
47960 + /* advance i to the next aligned address */
47961 + i = first = (uint16_t)(first + numOfProfiles);
47962 + }
47963 + }
47964 +
47965 + if (profilesFound == numOfProfiles)
47966 + {
47967 + for (i=first; i<first + numOfProfiles; i++)
47968 + {
47969 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
47970 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
47971 + }
47972 + }
47973 + else
47974 + {
47975 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47976 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
47977 + }
47978 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47979 +
47980 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
47981 + if (err)
47982 + {
47983 + RETURN_ERROR(MAJOR, err, NO_MSG);
47984 + }
47985 +
47986 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47987 +
47988 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
47989 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
47990 +
47991 + return E_OK;
47992 +}
47993 +
47994 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
47995 +{
47996 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47997 + t_Error err = E_OK;
47998 + uint32_t intFlags;
47999 + uint16_t i, swPortIndex = 0;
48000 +
48001 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48002 +
48003 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48004 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48005 +
48006 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48007 +
48008 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
48009 + if (err)
48010 + RETURN_ERROR(MAJOR, err,NO_MSG);
48011 +
48012 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48013 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48014 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
48015 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
48016 + i++)
48017 + {
48018 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
48019 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
48020 +
48021 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
48022 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
48023 + }
48024 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48025 +
48026 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
48027 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
48028 +
48029 + return E_OK;
48030 +}
48031 +
48032 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
48033 +{
48034 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48035 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48036 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
48037 + uint32_t tmpReg32, intFlags;
48038 + t_Error err;
48039 +
48040 + /* Calling function locked all PCD modules, so no need to lock here */
48041 +
48042 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48043 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
48044 +
48045 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
48046 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
48047 +
48048 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
48049 +
48050 + if (p_FmPcd->h_Hc)
48051 + {
48052 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
48053 +
48054 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48055 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48056 +
48057 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48058 + return err;
48059 + }
48060 +
48061 + /* lock the HW because once we read the registers we don't want them to be changed
48062 + * by another access. (We can copy to a tmp location and release the lock!) */
48063 +
48064 + intFlags = PlcrHwLock(p_FmPcdPlcr);
48065 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48066 +
48067 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
48068 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
48069 + {
48070 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
48071 + {
48072 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
48073 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
48074 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
48075 + {
48076 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48077 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48078 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
48079 + }
48080 +
48081 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
48082 + {
48083 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
48084 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48085 + {
48086 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48087 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48088 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48089 + }
48090 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48091 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
48092 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48093 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48094 + WritePar(p_FmPcd, tmpReg32);
48095 + }
48096 +
48097 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
48098 + {
48099 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
48100 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48101 + {
48102 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48103 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48104 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48105 + }
48106 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48107 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
48108 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48109 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48110 + WritePar(p_FmPcd, tmpReg32);
48111 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48112 + }
48113 +
48114 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
48115 + {
48116 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
48117 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48118 + {
48119 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48120 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48121 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48122 + }
48123 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48124 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
48125 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48126 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48127 + WritePar(p_FmPcd, tmpReg32);
48128 +
48129 + }
48130 + }
48131 + }
48132 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48133 +
48134 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48135 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48136 +
48137 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48138 +
48139 + return E_OK;
48140 +}
48141 +
48142 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48143 +{
48144 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48145 +
48146 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48147 +
48148 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
48149 +}
48150 +
48151 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48152 +{
48153 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48154 +
48155 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48156 +
48157 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
48158 +}
48159 +
48160 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48161 +{
48162 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48163 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48164 +
48165 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
48166 +
48167 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
48168 +}
48169 +
48170 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48171 +{
48172 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48173 + uint32_t intFlags;
48174 +
48175 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48176 +
48177 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48178 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
48179 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48180 +}
48181 +
48182 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48183 +{
48184 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48185 + uint32_t intFlags;
48186 +
48187 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48188 +
48189 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48190 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
48191 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48192 +}
48193 +
48194 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
48195 +{
48196 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
48197 +}
48198 +
48199 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
48200 + e_FmPcdProfileTypeSelection profileType,
48201 + t_Handle h_FmPort,
48202 + uint16_t relativeProfile,
48203 + uint16_t *p_AbsoluteId)
48204 +{
48205 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48206 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48207 + uint8_t i;
48208 +
48209 + switch (profileType)
48210 + {
48211 + case e_FM_PCD_PLCR_PORT_PRIVATE:
48212 + /* get port PCD id from port handle */
48213 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
48214 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
48215 + break;
48216 + if (i == FM_MAX_NUM_OF_PORTS)
48217 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48218 +
48219 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48220 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48221 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48222 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48223 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48224 + break;
48225 + case e_FM_PCD_PLCR_SHARED:
48226 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48227 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48228 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48229 + break;
48230 + default:
48231 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48232 + }
48233 +
48234 + return E_OK;
48235 +}
48236 +
48237 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48238 +{
48239 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48240 + uint16_t swPortIndex = 0;
48241 +
48242 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48243 +
48244 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48245 +}
48246 +
48247 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48248 +{
48249 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48250 + uint16_t swPortIndex = 0;
48251 +
48252 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48253 +
48254 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48255 +
48256 +}
48257 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48258 +{
48259 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48260 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48261 +}
48262 +
48263 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48264 +{
48265 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48266 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48267 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48268 +}
48269 +
48270 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48271 +{
48272 +
48273 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48274 + return TRUE;
48275 + else
48276 + return FALSE;
48277 +}
48278 +
48279 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48280 +{
48281 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48282 + FM_PCD_PLCR_PAR_R |
48283 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48284 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48285 +}
48286 +
48287 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48288 +{
48289 + switch (counter)
48290 + {
48291 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48292 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48293 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48294 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48295 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48296 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48297 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48298 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48299 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48300 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48301 + default:
48302 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48303 + return 0;
48304 + }
48305 +}
48306 +
48307 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48308 +{
48309 +
48310 + uint32_t tmpReg32 = 0;
48311 +
48312 + if (green)
48313 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48314 + if (yellow)
48315 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48316 + if (red)
48317 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48318 +
48319 + return tmpReg32;
48320 +}
48321 +
48322 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48323 +{
48324 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48325 +
48326 + /* this routine is protected by calling routine */
48327 +
48328 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48329 +
48330 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48331 +}
48332 +
48333 +/*********************** End of inter-module routines ************************/
48334 +
48335 +
48336 +/**************************************************/
48337 +/*............Policer API.........................*/
48338 +/**************************************************/
48339 +
48340 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48341 +{
48342 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48343 +
48344 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48345 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48346 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48347 +
48348 + if (!FmIsMaster(p_FmPcd->h_Fm))
48349 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48350 +
48351 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48352 +
48353 + return E_OK;
48354 +}
48355 +
48356 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48357 +{
48358 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48359 +
48360 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48361 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48362 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48363 +
48364 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48365 +
48366 + return E_OK;
48367 +}
48368 +
48369 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48370 +{
48371 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48372 + uint32_t tmpReg32;
48373 +
48374 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48375 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48376 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48377 +
48378 + if (!FmIsMaster(p_FmPcd->h_Fm))
48379 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48380 +
48381 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48382 + if (enable)
48383 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48384 + else
48385 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48386 +
48387 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48388 + return E_OK;
48389 +}
48390 +
48391 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48392 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48393 +{
48394 + t_FmPcd *p_FmPcd;
48395 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48396 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48397 + uint32_t intFlags;
48398 + uint16_t absoluteProfileId;
48399 + t_Error err = E_OK;
48400 + uint32_t tmpReg32;
48401 + t_FmPcdPlcrProfile *p_Profile;
48402 +
48403 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48404 +
48405 + if (p_ProfileParams->modify)
48406 + {
48407 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48408 + p_FmPcd = p_Profile->h_FmPcd;
48409 + absoluteProfileId = p_Profile->absoluteProfileId;
48410 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48411 + {
48412 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48413 + return NULL;
48414 + }
48415 +
48416 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48417 +
48418 + /* Try lock profile using flag */
48419 + if (!PlcrProfileFlagTryLock(p_Profile))
48420 + {
48421 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48422 + /* Signal to caller BUSY condition */
48423 + p_ProfileParams->id.h_Profile = NULL;
48424 + return NULL;
48425 + }
48426 + }
48427 + else
48428 + {
48429 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48430 +
48431 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48432 +
48433 + /* SMP: needs to be protected only if another core now changes the windows */
48434 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48435 + p_ProfileParams->id.newParams.profileType,
48436 + p_ProfileParams->id.newParams.h_FmPort,
48437 + p_ProfileParams->id.newParams.relativeProfileId,
48438 + &absoluteProfileId);
48439 + if (err)
48440 + {
48441 + REPORT_ERROR(MAJOR, err, NO_MSG);
48442 + return NULL;
48443 + }
48444 +
48445 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48446 + {
48447 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48448 + return NULL;
48449 + }
48450 +
48451 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48452 + {
48453 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48454 + return NULL;
48455 + }
48456 +
48457 + /* initialize profile struct */
48458 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48459 +
48460 + p_Profile->h_FmPcd = p_FmPcd;
48461 + p_Profile->absoluteProfileId = absoluteProfileId;
48462 +
48463 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48464 + if (!p_Profile->p_Lock)
48465 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48466 + }
48467 +
48468 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48469 +
48470 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48471 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48472 +
48473 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48474 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48475 +
48476 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48477 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48478 +
48479 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48480 +
48481 + /* build the policer profile registers */
48482 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48483 + if (err)
48484 + {
48485 + REPORT_ERROR(MAJOR, err, NO_MSG);
48486 + if (p_ProfileParams->modify)
48487 + /* unlock */
48488 + PlcrProfileFlagUnlock(p_Profile);
48489 + if (!p_ProfileParams->modify &&
48490 + p_Profile->p_Lock)
48491 + /* release allocated Profile lock */
48492 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48493 + return NULL;
48494 + }
48495 +
48496 + if (p_FmPcd->h_Hc)
48497 + {
48498 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48499 + if (p_ProfileParams->modify)
48500 + PlcrProfileFlagUnlock(p_Profile);
48501 + if (err)
48502 + {
48503 + /* release the allocated scheme lock */
48504 + if (!p_ProfileParams->modify &&
48505 + p_Profile->p_Lock)
48506 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48507 +
48508 + return NULL;
48509 + }
48510 + if (!p_ProfileParams->modify)
48511 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48512 + return (t_Handle)p_Profile;
48513 + }
48514 +
48515 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48516 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48517 +
48518 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48519 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48520 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48521 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48522 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48523 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48524 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48525 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48526 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48527 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48528 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48529 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48530 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48531 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48532 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48533 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48534 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48535 +
48536 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48537 + WritePar(p_FmPcd, tmpReg32);
48538 +
48539 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48540 +
48541 + if (!p_ProfileParams->modify)
48542 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48543 + else
48544 + PlcrProfileFlagUnlock(p_Profile);
48545 +
48546 + return (t_Handle)p_Profile;
48547 +}
48548 +
48549 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48550 +{
48551 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48552 + t_FmPcd *p_FmPcd;
48553 + uint16_t profileIndx;
48554 + uint32_t tmpReg32, intFlags;
48555 + t_Error err;
48556 +
48557 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48558 + p_FmPcd = p_Profile->h_FmPcd;
48559 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48560 +
48561 + profileIndx = p_Profile->absoluteProfileId;
48562 +
48563 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48564 +
48565 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48566 +
48567 + if (p_FmPcd->h_Hc)
48568 + {
48569 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48570 + if (p_Profile->p_Lock)
48571 + /* release allocated Profile lock */
48572 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48573 +
48574 + return err;
48575 + }
48576 +
48577 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48578 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48579 +
48580 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48581 + WritePar(p_FmPcd, tmpReg32);
48582 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48583 +
48584 +
48585 + if (p_Profile->p_Lock)
48586 + /* release allocated Profile lock */
48587 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48588 +
48589 + /* we do not memset profile as all its fields are being re-initialized at "set",
48590 + * plus its allocation information is still valid. */
48591 + return E_OK;
48592 +}
48593 +
48594 +/***************************************************/
48595 +/*............Policer Profile Counter..............*/
48596 +/***************************************************/
48597 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48598 +{
48599 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48600 + t_FmPcd *p_FmPcd;
48601 + uint16_t profileIndx;
48602 + uint32_t intFlags, counterVal = 0;
48603 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48604 +
48605 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48606 + p_FmPcd = p_Profile->h_FmPcd;
48607 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48608 +
48609 + if (p_FmPcd->h_Hc)
48610 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48611 +
48612 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48613 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48614 +
48615 + profileIndx = p_Profile->absoluteProfileId;
48616 +
48617 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48618 + {
48619 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48620 + return 0;
48621 + }
48622 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48623 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48624 +
48625 + switch (counter)
48626 + {
48627 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48628 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48629 + break;
48630 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48631 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48632 + break;
48633 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48634 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48635 + break;
48636 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48637 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48638 + break;
48639 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48640 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48641 + break;
48642 + default:
48643 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48644 + break;
48645 + }
48646 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48647 +
48648 + return counterVal;
48649 +}
48650 +
48651 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48652 +{
48653 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48654 + t_FmPcd *p_FmPcd;
48655 + uint16_t profileIndx;
48656 + uint32_t tmpReg32, intFlags;
48657 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48658 +
48659 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48660 +
48661 + p_FmPcd = p_Profile->h_FmPcd;
48662 + profileIndx = p_Profile->absoluteProfileId;
48663 +
48664 + if (p_FmPcd->h_Hc)
48665 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48666 +
48667 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48668 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48669 +
48670 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48671 + switch (counter)
48672 + {
48673 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48674 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48675 + break;
48676 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48677 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48678 + break;
48679 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48680 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48681 + break;
48682 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48683 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48684 + break;
48685 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48686 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48687 + break;
48688 + default:
48689 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48690 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48691 + }
48692 +
48693 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48694 + * Profile Number, PWSEL=0xFFFF (select all words).
48695 + */
48696 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48697 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48698 + WritePar(p_FmPcd, tmpReg32);
48699 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48700 +
48701 + return E_OK;
48702 +}
48703 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48704 new file mode 100644
48705 index 00000000..2bb8b969
48706 --- /dev/null
48707 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48708 @@ -0,0 +1,165 @@
48709 +/*
48710 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48711 + *
48712 + * Redistribution and use in source and binary forms, with or without
48713 + * modification, are permitted provided that the following conditions are met:
48714 + * * Redistributions of source code must retain the above copyright
48715 + * notice, this list of conditions and the following disclaimer.
48716 + * * Redistributions in binary form must reproduce the above copyright
48717 + * notice, this list of conditions and the following disclaimer in the
48718 + * documentation and/or other materials provided with the distribution.
48719 + * * Neither the name of Freescale Semiconductor nor the
48720 + * names of its contributors may be used to endorse or promote products
48721 + * derived from this software without specific prior written permission.
48722 + *
48723 + *
48724 + * ALTERNATIVELY, this software may be distributed under the terms of the
48725 + * GNU General Public License ("GPL") as published by the Free Software
48726 + * Foundation, either version 2 of that License or (at your option) any
48727 + * later version.
48728 + *
48729 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48730 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48731 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48732 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48733 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48734 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48735 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48736 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48737 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48738 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48739 + */
48740 +
48741 +
48742 +/******************************************************************************
48743 + @File fm_plcr.h
48744 +
48745 + @Description FM Policer private header
48746 +*//***************************************************************************/
48747 +#ifndef __FM_PLCR_H
48748 +#define __FM_PLCR_H
48749 +
48750 +#include "std_ext.h"
48751 +
48752 +
48753 +/***********************************************************************/
48754 +/* Policer defines */
48755 +/***********************************************************************/
48756 +
48757 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48758 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48759 +#define FM_PCD_PLCR_PAR_R 0x40000000
48760 +
48761 +/* shifts */
48762 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48763 +
48764 +/* masks */
48765 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48766 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48767 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48768 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48769 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48770 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48771 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48772 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48773 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48774 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48775 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48776 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48777 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48778 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48779 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48780 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48781 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48782 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48783 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48784 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48785 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48786 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48787 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48788 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48789 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48790 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48791 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48792 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48793 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48794 +
48795 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48796 +
48797 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48798 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48799 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48800 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48801 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48802 +
48803 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48804 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48805 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48806 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48807 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48808 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48809 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48810 +
48811 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48812 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48813 +
48814 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48815 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48816 +/* PWSEL Selctive select options */
48817 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48818 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48819 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48820 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48821 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48822 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48823 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48824 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48825 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48826 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48827 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48828 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48829 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48830 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48831 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48832 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48833 +
48834 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48835 + 1-> 2^N specific locations. */
48836 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48837 + 2-> 2^(N-1) base locations. */
48838 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48839 + 4-> 2^(N-2) base locations. */
48840 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48841 + 8->2^(N-3) base locations. */
48842 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48843 + 16-> 2^(N-4) base locations. */
48844 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48845 + 32-> 2^(N-5) base locations. */
48846 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48847 + 64-> 2^(N-6) base locations. */
48848 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48849 + 128-> 2^(N-7) base locations. */
48850 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48851 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48852 +
48853 +#define FM_PCD_PLCR_PMR_V 0x80000000
48854 +#define PLCR_ERR_ECC_CAP 0x80000000
48855 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48856 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48857 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48858 +
48859 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48860 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48861 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48862 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
48863 +
48864 +/* shifts */
48865 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
48866 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
48867 +
48868 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
48869 +
48870 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
48871 +
48872 +
48873 +#endif /* __FM_PLCR_H */
48874 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
48875 new file mode 100644
48876 index 00000000..ff4f0a2f
48877 --- /dev/null
48878 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
48879 @@ -0,0 +1,423 @@
48880 +/*
48881 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48882 + *
48883 + * Redistribution and use in source and binary forms, with or without
48884 + * modification, are permitted provided that the following conditions are met:
48885 + * * Redistributions of source code must retain the above copyright
48886 + * notice, this list of conditions and the following disclaimer.
48887 + * * Redistributions in binary form must reproduce the above copyright
48888 + * notice, this list of conditions and the following disclaimer in the
48889 + * documentation and/or other materials provided with the distribution.
48890 + * * Neither the name of Freescale Semiconductor nor the
48891 + * names of its contributors may be used to endorse or promote products
48892 + * derived from this software without specific prior written permission.
48893 + *
48894 + *
48895 + * ALTERNATIVELY, this software may be distributed under the terms of the
48896 + * GNU General Public License ("GPL") as published by the Free Software
48897 + * Foundation, either version 2 of that License or (at your option) any
48898 + * later version.
48899 + *
48900 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48901 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48902 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48903 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48904 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48905 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48906 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48907 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48908 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48909 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48910 + */
48911 +
48912 +
48913 +/******************************************************************************
48914 + @File fm_pcd.c
48915 +
48916 + @Description FM PCD ...
48917 +*//***************************************************************************/
48918 +#include <linux/math64.h>
48919 +#include "std_ext.h"
48920 +#include "error_ext.h"
48921 +#include "string_ext.h"
48922 +#include "debug_ext.h"
48923 +#include "net_ext.h"
48924 +
48925 +#include "fm_common.h"
48926 +#include "fm_pcd.h"
48927 +#include "fm_pcd_ipc.h"
48928 +#include "fm_prs.h"
48929 +#include "fsl_fman_prs.h"
48930 +
48931 +
48932 +static void PcdPrsErrorException(t_Handle h_FmPcd)
48933 +{
48934 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48935 + uint32_t event, ev_mask;
48936 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48937 +
48938 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48939 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
48940 +
48941 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
48942 +
48943 + fman_prs_ack_err_event(PrsRegs, event);
48944 +
48945 + DBG(TRACE, ("parser error - 0x%08x\n",event));
48946 +
48947 + if(event & FM_PCD_PRS_DOUBLE_ECC)
48948 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
48949 +}
48950 +
48951 +static void PcdPrsException(t_Handle h_FmPcd)
48952 +{
48953 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48954 + uint32_t event, ev_mask;
48955 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48956 +
48957 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48958 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
48959 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
48960 +
48961 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
48962 +
48963 + DBG(TRACE, ("parser event - 0x%08x\n",event));
48964 +
48965 + fman_prs_ack_expt_event(PrsRegs, event);
48966 +
48967 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
48968 +}
48969 +
48970 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
48971 +{
48972 + t_FmPcdPrs *p_FmPcdPrs;
48973 + uintptr_t baseAddr;
48974 +
48975 + UNUSED(p_FmPcd);
48976 + UNUSED(p_FmPcdParams);
48977 +
48978 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
48979 + if (!p_FmPcdPrs)
48980 + {
48981 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
48982 + return NULL;
48983 + }
48984 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
48985 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
48986 +
48987 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
48988 + {
48989 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
48990 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
48991 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
48992 + }
48993 +
48994 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
48995 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
48996 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
48997 +
48998 + return p_FmPcdPrs;
48999 +}
49000 +
49001 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49002 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
49003 +#else
49004 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
49005 +#endif /* FM_CAPWAP_SUPPORT */
49006 +
49007 +t_Error PrsInit(t_FmPcd *p_FmPcd)
49008 +{
49009 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
49010 + uint32_t *p_TmpCode;
49011 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
49012 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
49013 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49014 + uint32_t i;
49015 +
49016 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
49017 +
49018 + /* nothing to do in guest-partition */
49019 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49020 + return E_OK;
49021 +
49022 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
49023 + if (!p_TmpCode)
49024 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49025 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
49026 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
49027 +
49028 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
49029 +
49030 + /* register even if no interrupts enabled, to allow future enablement */
49031 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
49032 +
49033 + /* register even if no interrupts enabled, to allow future enablement */
49034 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
49035 +
49036 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
49037 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49038 +
49039 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
49040 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49041 +
49042 + /* load sw parser Ip-Frag patch */
49043 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
49044 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49045 +
49046 + XX_FreeSmart(p_TmpCode);
49047 +
49048 + return E_OK;
49049 +}
49050 +
49051 +void PrsFree(t_FmPcd *p_FmPcd)
49052 +{
49053 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49054 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
49055 + /* register even if no interrupts enabled, to allow future enablement */
49056 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
49057 +}
49058 +
49059 +void PrsEnable(t_FmPcd *p_FmPcd)
49060 +{
49061 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49062 +
49063 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49064 + fman_prs_enable(PrsRegs);
49065 +}
49066 +
49067 +void PrsDisable(t_FmPcd *p_FmPcd)
49068 +{
49069 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49070 +
49071 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49072 + fman_prs_disable(PrsRegs);
49073 +}
49074 +
49075 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
49076 +{
49077 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49078 +
49079 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49080 + return fman_prs_is_enabled(PrsRegs);
49081 +}
49082 +
49083 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
49084 +{
49085 + struct fman_prs_regs *PrsRegs;
49086 + uint32_t bitMask = 0;
49087 + uint8_t prsPortId;
49088 +
49089 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49090 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49091 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49092 +
49093 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49094 +
49095 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
49096 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
49097 +
49098 + if (include)
49099 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
49100 + else
49101 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
49102 +
49103 + fman_prs_set_stst_port_msk(PrsRegs,
49104 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
49105 +
49106 + return E_OK;
49107 +}
49108 +
49109 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
49110 +{
49111 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49112 + t_Error err;
49113 +
49114 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49115 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49116 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49117 +
49118 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49119 + p_FmPcd->h_IpcSession)
49120 + {
49121 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
49122 + t_FmPcdIpcMsg msg;
49123 +
49124 + prsIncludePortParams.hardwarePortId = hardwarePortId;
49125 + prsIncludePortParams.include = include;
49126 + memset(&msg, 0, sizeof(msg));
49127 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
49128 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
49129 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49130 + (uint8_t*)&msg,
49131 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
49132 + NULL,
49133 + NULL,
49134 + NULL,
49135 + NULL);
49136 + if (err != E_OK)
49137 + RETURN_ERROR(MAJOR, err, NO_MSG);
49138 + return E_OK;
49139 + }
49140 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49141 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49142 + ("running in guest-mode without IPC!"));
49143 +
49144 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
49145 +}
49146 +
49147 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
49148 +{
49149 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49150 + t_FmPcdPrsLabelParams *p_Label;
49151 + int i;
49152 +
49153 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
49154 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
49155 +
49156 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49157 + p_FmPcd->h_IpcSession)
49158 + {
49159 + t_Error err = E_OK;
49160 + t_FmPcdIpcSwPrsLable labelParams;
49161 + t_FmPcdIpcMsg msg;
49162 + uint32_t prsOffset = 0;
49163 + t_FmPcdIpcReply reply;
49164 + uint32_t replyLength;
49165 +
49166 + memset(&reply, 0, sizeof(reply));
49167 + memset(&msg, 0, sizeof(msg));
49168 + labelParams.enumHdr = (uint32_t)hdr;
49169 + labelParams.indexPerHdr = indexPerHdr;
49170 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
49171 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
49172 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
49173 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49174 + (uint8_t*)&msg,
49175 + sizeof(msg.msgId) +sizeof(labelParams),
49176 + (uint8_t*)&reply,
49177 + &replyLength,
49178 + NULL,
49179 + NULL);
49180 + if (err != E_OK)
49181 + RETURN_ERROR(MAJOR, err, NO_MSG);
49182 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
49183 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
49184 +
49185 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
49186 + return prsOffset;
49187 + }
49188 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49189 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49190 + ("running in guest-mode without IPC!"));
49191 +
49192 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
49193 +
49194 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
49195 + {
49196 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
49197 +
49198 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
49199 + return p_Label->instructionOffset;
49200 + }
49201 +
49202 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
49203 + return (uint32_t)ILLEGAL_BASE;
49204 +}
49205 +
49206 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
49207 +{
49208 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49209 + struct fman_prs_regs *PrsRegs;
49210 +
49211 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49212 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49213 +
49214 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49215 +
49216 +
49217 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49218 + {
49219 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
49220 + return;
49221 + }
49222 +
49223 + fman_prs_set_stst(PrsRegs, enable);
49224 +}
49225 +
49226 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49227 +{
49228 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49229 + uint32_t *p_LoadTarget;
49230 + uint32_t *p_TmpCode;
49231 + int i;
49232 +
49233 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49234 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49235 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49236 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49237 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49238 +
49239 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49240 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49241 +
49242 + if (!p_SwPrs->override)
49243 + {
49244 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49245 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49246 + }
49247 + else
49248 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49249 +
49250 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49251 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49252 +
49253 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49254 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49255 +
49256 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49257 + if (!p_TmpCode)
49258 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49259 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49260 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49261 +
49262 + /* save sw parser labels */
49263 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49264 + p_SwPrs->labelsTable,
49265 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49266 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49267 +
49268 + /* load sw parser code */
49269 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49270 +
49271 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49272 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49273 +
49274 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49275 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49276 +
49277 + /* copy data parameters */
49278 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49279 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49280 +
49281 + /* Clear last 4 bytes */
49282 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49283 +
49284 + XX_FreeSmart(p_TmpCode);
49285 +
49286 + return E_OK;
49287 +}
49288 +
49289 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49290 +{
49291 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49292 +
49293 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49294 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49295 +
49296 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49297 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49298 +
49299 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49300 +
49301 + return E_OK;
49302 +}
49303 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49304 new file mode 100644
49305 index 00000000..056f225e
49306 --- /dev/null
49307 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49308 @@ -0,0 +1,316 @@
49309 +/*
49310 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49311 + *
49312 + * Redistribution and use in source and binary forms, with or without
49313 + * modification, are permitted provided that the following conditions are met:
49314 + * * Redistributions of source code must retain the above copyright
49315 + * notice, this list of conditions and the following disclaimer.
49316 + * * Redistributions in binary form must reproduce the above copyright
49317 + * notice, this list of conditions and the following disclaimer in the
49318 + * documentation and/or other materials provided with the distribution.
49319 + * * Neither the name of Freescale Semiconductor nor the
49320 + * names of its contributors may be used to endorse or promote products
49321 + * derived from this software without specific prior written permission.
49322 + *
49323 + *
49324 + * ALTERNATIVELY, this software may be distributed under the terms of the
49325 + * GNU General Public License ("GPL") as published by the Free Software
49326 + * Foundation, either version 2 of that License or (at your option) any
49327 + * later version.
49328 + *
49329 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49330 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49331 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49332 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49333 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49334 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49335 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49336 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49337 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49338 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49339 + */
49340 +
49341 +
49342 +/******************************************************************************
49343 + @File fm_prs.h
49344 +
49345 + @Description FM Parser private header
49346 + *//***************************************************************************/
49347 +#ifndef __FM_PRS_H
49348 +#define __FM_PRS_H
49349 +
49350 +#include "std_ext.h"
49351 +
49352 +/***********************************************************************/
49353 +/* SW parser IP_FRAG patch */
49354 +/***********************************************************************/
49355 +
49356 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49357 +#define SW_PRS_UDP_LITE_PATCH \
49358 +{\
49359 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49360 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49361 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49362 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49363 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49364 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49365 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49366 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49367 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49368 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49369 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49370 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49371 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49372 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49373 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49374 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49375 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49376 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49377 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49378 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49379 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49380 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49381 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49382 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49383 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49384 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49385 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49386 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49387 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49388 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49389 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49390 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49391 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49392 + 0x00,0x01,0x1B,0xFF \
49393 +}
49394 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49395 +
49396 +#if (DPAA_VERSION == 10)
49397 +/* Version: 106.1.9 */
49398 +#define SW_PRS_OFFLOAD_PATCH \
49399 +{ \
49400 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49401 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49402 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49403 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49404 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49405 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49406 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49407 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49408 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49409 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49410 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49411 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49412 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49413 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49414 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49415 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49416 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49417 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49418 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49419 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49420 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49421 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49422 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49423 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49424 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49425 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49426 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49427 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49428 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49429 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49430 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49431 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49432 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49433 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49434 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49435 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49436 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49437 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49438 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49439 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49440 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49441 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49442 +}
49443 +
49444 +#else
49445 +#define SW_PRS_OFFLOAD_PATCH \
49446 +{ \
49447 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49448 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49449 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49450 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49451 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49452 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49453 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49454 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49455 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49456 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49457 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49458 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49459 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49460 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49461 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49462 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49463 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49464 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49465 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49466 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49467 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49468 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49469 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49470 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49471 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49472 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49473 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49474 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49475 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49476 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49477 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49478 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49479 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49480 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49481 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49482 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49483 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49484 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49485 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49486 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49487 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49488 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49489 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49490 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49491 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49492 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49493 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49494 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49495 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49496 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49497 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49498 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49499 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49500 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49501 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49502 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49503 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49504 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49505 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49506 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49507 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49508 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49509 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49510 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49511 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49512 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49513 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49514 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,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,0x31,0x52,0x00,0xDA, \
49518 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49519 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49520 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49521 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49522 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49523 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49524 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49525 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49526 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49527 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49528 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49529 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49530 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49531 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49532 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49533 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49534 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49535 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49536 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49537 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49538 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49539 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49540 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49541 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49542 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49543 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49544 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49545 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49546 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49547 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49548 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49549 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49550 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49551 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49552 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49553 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49554 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49555 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49556 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49557 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49558 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49559 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49560 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49561 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49562 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49563 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49564 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49565 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49566 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49567 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49568 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49569 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49570 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49571 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49572 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49573 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49574 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49575 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49576 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49577 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49578 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49579 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49580 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49581 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49582 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49583 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49584 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49585 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49586 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49587 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49588 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49589 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49590 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49591 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49592 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49593 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49594 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49595 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49596 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49597 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49598 +}
49599 +#endif /* (DPAA_VERSION == 10) */
49600 +
49601 +/****************************/
49602 +/* Parser defines */
49603 +/****************************/
49604 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49605 + the end of the SW parser area */
49606 +
49607 +/* masks */
49608 +#define PRS_ERR_CAP 0x80000000
49609 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49610 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49611 +#define PRS_ERR_ADDR_MASK 0x000001FF
49612 +
49613 +/* others */
49614 +#define PRS_MAX_CYCLE_LIMIT 8191
49615 +#define PRS_SW_DATA 0x00000800
49616 +#define PRS_REGS_OFFSET 0x00000840
49617 +
49618 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49619 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49620 +
49621 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49622 + bitMask = 0x80000000>>prsPortId
49623 +
49624 +#endif /* __FM_PRS_H */
49625 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49626 new file mode 100644
49627 index 00000000..ee82f730
49628 --- /dev/null
49629 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49630 @@ -0,0 +1,984 @@
49631 +/*
49632 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49633 + *
49634 + * Redistribution and use in source and binary forms, with or without
49635 + * modification, are permitted provided that the following conditions are met:
49636 + * * Redistributions of source code must retain the above copyright
49637 + * notice, this list of conditions and the following disclaimer.
49638 + * * Redistributions in binary form must reproduce the above copyright
49639 + * notice, this list of conditions and the following disclaimer in the
49640 + * documentation and/or other materials provided with the distribution.
49641 + * * Neither the name of Freescale Semiconductor nor the
49642 + * names of its contributors may be used to endorse or promote products
49643 + * derived from this software without specific prior written permission.
49644 + *
49645 + *
49646 + * ALTERNATIVELY, this software may be distributed under the terms of the
49647 + * GNU General Public License ("GPL") as published by the Free Software
49648 + * Foundation, either version 2 of that License or (at your option) any
49649 + * later version.
49650 + *
49651 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49652 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49653 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49654 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49655 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49656 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49657 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49658 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49659 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49660 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49661 + */
49662 +
49663 +
49664 +/******************************************************************************
49665 + @File fm_replic.c
49666 +
49667 + @Description FM frame replicator
49668 +*//***************************************************************************/
49669 +#include "std_ext.h"
49670 +#include "error_ext.h"
49671 +#include "string_ext.h"
49672 +#include "debug_ext.h"
49673 +#include "fm_pcd_ext.h"
49674 +#include "fm_muram_ext.h"
49675 +#include "fm_common.h"
49676 +#include "fm_hc.h"
49677 +#include "fm_replic.h"
49678 +#include "fm_cc.h"
49679 +#include "list_ext.h"
49680 +
49681 +
49682 +/****************************************/
49683 +/* static functions */
49684 +/****************************************/
49685 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49686 + uint32_t memberIndex,
49687 + bool isAddOperation)
49688 +{
49689 + uint8_t memberPosition;
49690 + uint32_t lastMemberIndex;
49691 +
49692 + ASSERT_COND(p_ReplicGroup);
49693 +
49694 + /* the last member index is different between add and remove operation -
49695 + in case of remove - this is exactly the last member index
49696 + in case of add - this is the last member index + 1 - e.g.
49697 + if we have 4 members, the index of the actual last member is 3(because the
49698 + index starts from 0) therefore in order to add a new member as the last
49699 + member we shall use memberIndex = 4 and not 3
49700 + */
49701 + if (isAddOperation)
49702 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49703 + else
49704 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49705 +
49706 + /* last */
49707 + if (memberIndex == lastMemberIndex)
49708 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49709 + else
49710 + {
49711 + /* first */
49712 + if (memberIndex == 0)
49713 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49714 + else
49715 + {
49716 + /* middle */
49717 + ASSERT_COND(memberIndex < lastMemberIndex);
49718 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49719 + }
49720 + }
49721 + return memberPosition;
49722 +}
49723 +
49724 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49725 + t_FmPcdCcNextEngineParams *p_MemberParams)
49726 +{
49727 + t_Error err;
49728 +
49729 +
49730 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49731 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49732 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49733 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49734 +
49735 + /* check the regular parameters of the next engine */
49736 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49737 + if (err)
49738 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49739 +
49740 + return E_OK;
49741 +}
49742 +
49743 +static t_Error CheckParams(t_Handle h_FmPcd,
49744 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49745 +{
49746 + int i;
49747 + t_Error err;
49748 +
49749 + /* check that max num of entries is at least 2 */
49750 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49751 + 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));
49752 +
49753 + /* check that number of entries is greater than zero */
49754 + if (!p_ReplicGroupParam->numOfEntries)
49755 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49756 +
49757 + /* check that max num of entries is equal or greater than number of entries */
49758 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49759 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49760 +
49761 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49762 + {
49763 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49764 + if (err)
49765 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49766 + }
49767 + return E_OK;
49768 +}
49769 +
49770 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49771 +{
49772 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49773 + t_List *p_Next;
49774 +
49775 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49776 + {
49777 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49778 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49779 + ASSERT_COND(p_ReplicMember);
49780 + LIST_DelAndInit(p_Next);
49781 + }
49782 + return p_ReplicMember;
49783 +}
49784 +
49785 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49786 + t_FmPcdFrmReplicMember *p_ReplicMember)
49787 +{
49788 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49789 +}
49790 +
49791 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49792 + t_FmPcdFrmReplicMember *p_CurrentMember,
49793 + t_List *p_ListHead)
49794 +{
49795 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49796 +
49797 + p_ReplicGroup->numOfEntries++;
49798 +}
49799 +
49800 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49801 + t_FmPcdFrmReplicMember *p_CurrentMember)
49802 +{
49803 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49804 + LIST_DelAndInit(&p_CurrentMember->node);
49805 + p_ReplicGroup->numOfEntries--;
49806 +}
49807 +
49808 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49809 + t_AdOfTypeContLookup *p_SourceTd,
49810 + t_FmPcdFrmReplicMember *p_ReplicMember)
49811 +{
49812 + t_FmPcd *p_FmPcd;
49813 +
49814 + ASSERT_COND(p_SourceTd);
49815 + ASSERT_COND(p_ReplicMember);
49816 + ASSERT_COND(p_ReplicGroup);
49817 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49818 +
49819 + /* Link the first member in the group to the source TD */
49820 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49821 +
49822 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49823 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49824 + p_FmPcd->physicalMuramBase));
49825 +}
49826 +
49827 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49828 + t_FmPcdFrmReplicMember *p_CurrentMember,
49829 + t_FmPcdFrmReplicMember *p_NextMember)
49830 +{
49831 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49832 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49833 + t_FmPcd *p_FmPcd;
49834 + uint32_t offset = 0;
49835 +
49836 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49837 + if (p_NextMember)
49838 + {
49839 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49840 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49841 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49842 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49843 + }
49844 +
49845 + /* link the current AD to point to the AD of the next member */
49846 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49847 +}
49848 +
49849 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49850 + void *p_OldDescriptor,
49851 + void *p_NewDescriptor)
49852 +{
49853 + t_Handle h_Hc;
49854 + t_Error err;
49855 + t_FmPcd *p_FmPcd;
49856 +
49857 + ASSERT_COND(p_ReplicGroup);
49858 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49859 + ASSERT_COND(p_OldDescriptor);
49860 + ASSERT_COND(p_NewDescriptor);
49861 +
49862 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49863 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49864 + if (!h_Hc)
49865 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49866 +
49867 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49868 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49869 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49870 + if (err)
49871 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
49872 +
49873 + return E_OK;
49874 +}
49875 +
49876 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
49877 +{
49878 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
49879 + uint32_t tmp;
49880 +
49881 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
49882 + if (last)
49883 + /* clear the NL bit in case it's the last member in the group*/
49884 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
49885 + else
49886 + /* set the NL bit in case it's not the last member in the group */
49887 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
49888 +
49889 + /* set FR bit in the action descriptor */
49890 + tmp = GET_UINT32(p_CurrReplicAd->nia);
49891 + WRITE_UINT32(p_CurrReplicAd->nia,
49892 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
49893 +}
49894 +
49895 +static void BuildSourceTd(void *p_Ad)
49896 +{
49897 + t_AdOfTypeContLookup *p_SourceTd;
49898 +
49899 + ASSERT_COND(p_Ad);
49900 +
49901 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
49902 +
49903 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49904 +
49905 + /* initialize the source table descriptor */
49906 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
49907 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
49908 +}
49909 +
49910 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49911 + t_FmPcdFrmReplicMember *p_NextMember,
49912 + t_FmPcdFrmReplicMember *p_CurrentMember,
49913 + bool sourceDescriptor,
49914 + bool last)
49915 +{
49916 + t_FmPcd *p_FmPcd;
49917 + t_FmPcdFrmReplicMember shadowMember;
49918 + t_Error err;
49919 +
49920 + ASSERT_COND(p_ReplicGroup);
49921 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49922 +
49923 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49924 + ASSERT_COND(p_FmPcd->p_CcShadow);
49925 +
49926 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
49927 + return ERROR_CODE(E_BUSY);
49928 +
49929 + if (sourceDescriptor)
49930 + {
49931 + BuildSourceTd(p_FmPcd->p_CcShadow);
49932 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
49933 +
49934 + /* Modify the source table descriptor according to the prepared shadow descriptor */
49935 + err = ModifyDescriptor(p_ReplicGroup,
49936 + p_ReplicGroup->p_SourceTd,
49937 + p_FmPcd->p_CcShadow/* new prepared source td */);
49938 +
49939 + RELEASE_LOCK(p_FmPcd->shadowLock);
49940 + if (err)
49941 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
49942 +
49943 + }
49944 + else
49945 + {
49946 + IO2IOCpy32(p_FmPcd->p_CcShadow,
49947 + p_CurrentMember->p_MemberAd,
49948 + FM_PCD_CC_AD_ENTRY_SIZE);
49949 +
49950 + /* update the last bit in the shadow ad */
49951 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
49952 +
49953 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
49954 +
49955 + /* update the next FR member index */
49956 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
49957 +
49958 + /* Modify the next member according to the prepared shadow descriptor */
49959 + err = ModifyDescriptor(p_ReplicGroup,
49960 + p_CurrentMember->p_MemberAd,
49961 + p_FmPcd->p_CcShadow);
49962 +
49963 + RELEASE_LOCK(p_FmPcd->shadowLock);
49964 + if (err)
49965 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
49966 + }
49967 +
49968 +
49969 + return E_OK;
49970 +}
49971 +
49972 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49973 + uint16_t memberIndex)
49974 +{
49975 + int i=0;
49976 + t_List *p_Pos;
49977 + t_FmPcdFrmReplicMember *p_Member = NULL;
49978 +
49979 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
49980 + {
49981 + if (i == memberIndex)
49982 + {
49983 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
49984 + return p_Member;
49985 + }
49986 + i++;
49987 + }
49988 + return p_Member;
49989 +}
49990 +
49991 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49992 +{
49993 + t_FmPcdFrmReplicMember *p_CurrentMember;
49994 + t_Handle h_Muram;
49995 +
49996 + ASSERT_COND(p_ReplicGroup);
49997 +
49998 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
49999 + ASSERT_COND(h_Muram);
50000 +
50001 + /* Initialize an internal structure of a member to add to the available members list */
50002 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
50003 + if (!p_CurrentMember)
50004 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
50005 +
50006 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
50007 +
50008 + /* Allocate the member AD */
50009 + p_CurrentMember->p_MemberAd =
50010 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
50011 + FM_PCD_CC_AD_ENTRY_SIZE,
50012 + FM_PCD_CC_AD_TABLE_ALIGN);
50013 + if (!p_CurrentMember->p_MemberAd)
50014 + {
50015 + XX_Free(p_CurrentMember);
50016 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
50017 + }
50018 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50019 +
50020 + /* Add the new member to the available members list */
50021 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
50022 +
50023 + return E_OK;
50024 +}
50025 +
50026 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50027 + t_FmPcdCcNextEngineParams *p_MemberParams,
50028 + bool last)
50029 +{
50030 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
50031 +
50032 + ASSERT_COND(p_ReplicGroup);
50033 +
50034 + /* Get an available member from the internal members list */
50035 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
50036 + if (!p_CurrentMember)
50037 + {
50038 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
50039 + return NULL;
50040 + }
50041 + p_CurrentMember->h_Manip = NULL;
50042 +
50043 + /* clear the Ad of the new member */
50044 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50045 +
50046 + INIT_LIST(&p_CurrentMember->node);
50047 +
50048 + /* Initialize the Ad of the member */
50049 + NextStepAd(p_CurrentMember->p_MemberAd,
50050 + NULL,
50051 + p_MemberParams,
50052 + p_ReplicGroup->h_FmPcd);
50053 +
50054 + /* save Manip handle (for free needs) */
50055 + if (p_MemberParams->h_Manip)
50056 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
50057 +
50058 + /* Initialize the relevant frame replicator fields in the AD */
50059 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
50060 +
50061 + return p_CurrentMember;
50062 +}
50063 +
50064 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50065 + t_FmPcdFrmReplicMember *p_Member)
50066 +{
50067 + /* Note: Can't free the member AD just returns the member to the available
50068 + member list - therefore only memset the AD */
50069 +
50070 + /* zero the AD */
50071 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50072 +
50073 +
50074 + /* return the member to the available members list */
50075 + PutAvailableMember(p_ReplicGroup, p_Member);
50076 +}
50077 +
50078 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50079 + uint16_t memberIndex)
50080 +{
50081 + t_FmPcd *p_FmPcd = NULL;
50082 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
50083 + t_Error err;
50084 + uint8_t memberPosition;
50085 +
50086 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50087 + ASSERT_COND(p_FmPcd);
50088 + UNUSED(p_FmPcd);
50089 +
50090 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50091 + ASSERT_COND(p_CurrentMember);
50092 +
50093 + /* determine the member position in the group */
50094 + memberPosition = GetMemberPosition(p_ReplicGroup,
50095 + memberIndex,
50096 + FALSE/*remove operation*/);
50097 +
50098 + switch (memberPosition)
50099 + {
50100 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50101 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50102 + ASSERT_COND(p_NextMember);
50103 +
50104 + /* update the source td itself by using a host command */
50105 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50106 + p_NextMember,
50107 + NULL,
50108 + TRUE/*sourceDescriptor*/,
50109 + FALSE/*last*/);
50110 + break;
50111 +
50112 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50113 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50114 + ASSERT_COND(p_PreviousMember);
50115 +
50116 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50117 + ASSERT_COND(p_NextMember);
50118 +
50119 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50120 + p_NextMember,
50121 + p_PreviousMember,
50122 + FALSE/*sourceDescriptor*/,
50123 + FALSE/*last*/);
50124 +
50125 + break;
50126 +
50127 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50128 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50129 + ASSERT_COND(p_PreviousMember);
50130 +
50131 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50132 + NULL,
50133 + p_PreviousMember,
50134 + FALSE/*sourceDescriptor*/,
50135 + TRUE/*last*/);
50136 + break;
50137 +
50138 + default:
50139 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
50140 + }
50141 +
50142 + if (err)
50143 + RETURN_ERROR(MAJOR, err, NO_MSG);
50144 +
50145 + if (p_CurrentMember->h_Manip)
50146 + {
50147 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50148 + p_CurrentMember->h_Manip = NULL;
50149 + }
50150 +
50151 + /* remove the member from the driver internal members list */
50152 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50153 +
50154 + /* return the member to the available members list */
50155 + FreeMember(p_ReplicGroup, p_CurrentMember);
50156 +
50157 + return E_OK;
50158 +}
50159 +
50160 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50161 +{
50162 + int i, j;
50163 + t_Handle h_Muram;
50164 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
50165 +
50166 + if (p_ReplicGroup)
50167 + {
50168 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50169 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50170 + ASSERT_COND(h_Muram);
50171 +
50172 + /* free the source table descriptor */
50173 + if (p_ReplicGroup->p_SourceTd)
50174 + {
50175 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
50176 + p_ReplicGroup->p_SourceTd = NULL;
50177 + }
50178 +
50179 + /* Remove all members from the members linked list (hw and sw) and
50180 + return the members to the available members list */
50181 + if (p_ReplicGroup->numOfEntries)
50182 + {
50183 + j = p_ReplicGroup->numOfEntries-1;
50184 +
50185 + /* manually removal of the member because there are no owners of
50186 + this group */
50187 + for (i=j; i>=0; i--)
50188 + {
50189 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
50190 + ASSERT_COND(p_CurrentMember);
50191 +
50192 + if (p_CurrentMember->h_Manip)
50193 + {
50194 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50195 + p_CurrentMember->h_Manip = NULL;
50196 + }
50197 +
50198 + /* remove the member from the internal driver members list */
50199 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50200 +
50201 + /* return the member to the available members list */
50202 + FreeMember(p_ReplicGroup, p_CurrentMember);
50203 + }
50204 + }
50205 +
50206 + /* Free members AD */
50207 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50208 + {
50209 + p_Member = GetAvailableMember(p_ReplicGroup);
50210 + ASSERT_COND(p_Member);
50211 + if (p_Member->p_MemberAd)
50212 + {
50213 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
50214 + p_Member->p_MemberAd = NULL;
50215 + }
50216 + XX_Free(p_Member);
50217 + }
50218 +
50219 + /* release the group lock */
50220 + if (p_ReplicGroup->p_Lock)
50221 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
50222 +
50223 + /* free the replicator group */
50224 + XX_Free(p_ReplicGroup);
50225 + }
50226 +}
50227 +
50228 +
50229 +/*****************************************************************************/
50230 +/* Inter-module API routines */
50231 +/*****************************************************************************/
50232 +
50233 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50234 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50235 +{
50236 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50237 + ASSERT_COND(p_ReplicGroup);
50238 +
50239 + return (p_ReplicGroup->p_SourceTd);
50240 +}
50241 +
50242 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50243 + void *p_Ad,
50244 + t_Handle *h_AdNew)
50245 +{
50246 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50247 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50248 + t_FmPcd *p_FmPcd;
50249 +
50250 + ASSERT_COND(p_ReplicGroup);
50251 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50252 +
50253 + /* build a bypass ad */
50254 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50255 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50256 +
50257 + *h_AdNew = NULL;
50258 +}
50259 +
50260 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50261 + bool add)
50262 +{
50263 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50264 + ASSERT_COND(p_ReplicGroup);
50265 +
50266 + /* update the group owner counter */
50267 + if (add)
50268 + p_ReplicGroup->owners++;
50269 + else
50270 + {
50271 + ASSERT_COND(p_ReplicGroup->owners);
50272 + p_ReplicGroup->owners--;
50273 + }
50274 +}
50275 +
50276 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50277 +{
50278 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50279 +
50280 + ASSERT_COND(h_ReplicGroup);
50281 +
50282 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50283 + return E_OK;
50284 +
50285 + return ERROR_CODE(E_BUSY);
50286 +}
50287 +
50288 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50289 +{
50290 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50291 +
50292 + ASSERT_COND(h_ReplicGroup);
50293 +
50294 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50295 +}
50296 +/*********************** End of inter-module routines ************************/
50297 +
50298 +
50299 +/****************************************/
50300 +/* API Init unit functions */
50301 +/****************************************/
50302 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50303 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50304 +{
50305 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50306 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50307 + int i;
50308 + t_Error err;
50309 + bool last = FALSE;
50310 + t_Handle h_Muram;
50311 +
50312 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50313 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50314 +
50315 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50316 + {
50317 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50318 + return NULL;
50319 + }
50320 +
50321 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50322 + if (err)
50323 + {
50324 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50325 + return NULL;
50326 + }
50327 +
50328 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50329 + if (!p_ReplicGroup)
50330 + {
50331 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50332 + return NULL;
50333 + }
50334 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50335 +
50336 + /* initialize lists for internal driver use */
50337 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50338 + INIT_LIST(&p_ReplicGroup->membersList);
50339 +
50340 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50341 +
50342 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50343 + ASSERT_COND(h_Muram);
50344 +
50345 + /* initialize the group lock */
50346 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50347 + if (!p_ReplicGroup->p_Lock)
50348 + {
50349 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50350 + DeleteGroup(p_ReplicGroup);
50351 + return NULL;
50352 + }
50353 +
50354 + /* Allocate the frame replicator source table descriptor */
50355 + p_ReplicGroup->p_SourceTd =
50356 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50357 + FM_PCD_CC_AD_ENTRY_SIZE,
50358 + FM_PCD_CC_AD_TABLE_ALIGN);
50359 + if (!p_ReplicGroup->p_SourceTd)
50360 + {
50361 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50362 + DeleteGroup(p_ReplicGroup);
50363 + return NULL;
50364 + }
50365 +
50366 + /* update the shadow size - required for the host commands */
50367 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50368 + FM_PCD_CC_AD_ENTRY_SIZE,
50369 + FM_PCD_CC_AD_TABLE_ALIGN);
50370 + if (err)
50371 + {
50372 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50373 + DeleteGroup(p_ReplicGroup);
50374 + return NULL;
50375 + }
50376 +
50377 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50378 +
50379 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50380 + It prevents allocation of Muram in run-time */
50381 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50382 + {
50383 + err = AllocMember(p_ReplicGroup);
50384 + if (err)
50385 + {
50386 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50387 + DeleteGroup(p_ReplicGroup);
50388 + return NULL;
50389 + }
50390 + }
50391 +
50392 + /* Initialize the members linked lists:
50393 + (hw - the one that is used by the FMan controller and
50394 + sw - the one that is managed by the driver internally) */
50395 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50396 + {
50397 + /* check if this is the last member in the group */
50398 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50399 + last = TRUE;
50400 + else
50401 + last = FALSE;
50402 +
50403 + /* Initialize a new member */
50404 + p_CurrentMember = InitMember(p_ReplicGroup,
50405 + &(p_ReplicGroupParam->nextEngineParams[i]),
50406 + last);
50407 + if (!p_CurrentMember)
50408 + {
50409 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50410 + DeleteGroup(p_ReplicGroup);
50411 + return NULL;
50412 + }
50413 +
50414 + /* Build the members group - link two consecutive members in the hw linked list */
50415 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50416 +
50417 + /* update the driver internal members list to be compatible to the hw members linked list */
50418 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50419 +
50420 + p_NextMember = p_CurrentMember;
50421 + }
50422 +
50423 + /* initialize the source table descriptor */
50424 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50425 +
50426 + /* link the source table descriptor to point to the first member in the group */
50427 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50428 +
50429 + return p_ReplicGroup;
50430 +}
50431 +
50432 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50433 +{
50434 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50435 +
50436 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50437 +
50438 + if (p_ReplicGroup->owners)
50439 + RETURN_ERROR(MAJOR,
50440 + E_INVALID_STATE,
50441 + ("the group has owners and can't be deleted"));
50442 +
50443 + DeleteGroup(p_ReplicGroup);
50444 +
50445 + return E_OK;
50446 +}
50447 +
50448 +
50449 +/*****************************************************************************/
50450 +/* API Run-time Frame replicator Control unit functions */
50451 +/*****************************************************************************/
50452 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50453 + uint16_t memberIndex,
50454 + t_FmPcdCcNextEngineParams *p_MemberParams)
50455 +{
50456 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50457 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50458 + t_Error err;
50459 + uint8_t memberPosition;
50460 +
50461 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50462 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50463 +
50464 + /* group lock */
50465 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50466 + if (GET_ERROR_TYPE(err) == E_BUSY)
50467 + return ERROR_CODE(E_BUSY);
50468 +
50469 + if (memberIndex > p_ReplicGroup->numOfEntries)
50470 + {
50471 + /* unlock */
50472 + FrmReplicGroupUnlock(p_ReplicGroup);
50473 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50474 + ("memberIndex is greater than the members in the list"));
50475 + }
50476 +
50477 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50478 + {
50479 + /* unlock */
50480 + FrmReplicGroupUnlock(p_ReplicGroup);
50481 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50482 + }
50483 +
50484 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50485 + {
50486 + /* unlock */
50487 + FrmReplicGroupUnlock(p_ReplicGroup);
50488 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50489 + ("numOfEntries with new entry can not be larger than %d\n",
50490 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50491 + }
50492 +
50493 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50494 + if (err)
50495 + {
50496 + /* unlock */
50497 + FrmReplicGroupUnlock(p_ReplicGroup);
50498 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50499 + }
50500 + /* determine the member position in the group */
50501 + memberPosition = GetMemberPosition(p_ReplicGroup,
50502 + memberIndex,
50503 + TRUE/* add operation */);
50504 +
50505 + /* Initialize a new member */
50506 + p_NewMember = InitMember(p_ReplicGroup,
50507 + p_MemberParams,
50508 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50509 + if (!p_NewMember)
50510 + {
50511 + /* unlock */
50512 + FrmReplicGroupUnlock(p_ReplicGroup);
50513 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50514 + }
50515 +
50516 + switch (memberPosition)
50517 + {
50518 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50519 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50520 + ASSERT_COND(p_CurrentMember);
50521 +
50522 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50523 +
50524 + /* update the internal group source TD */
50525 + LinkSourceToMember(p_ReplicGroup,
50526 + p_ReplicGroup->p_SourceTd,
50527 + p_NewMember);
50528 +
50529 + /* add member to the internal sw member list */
50530 + AddMemberToList(p_ReplicGroup,
50531 + p_NewMember,
50532 + &p_ReplicGroup->membersList);
50533 + break;
50534 +
50535 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50536 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50537 + ASSERT_COND(p_CurrentMember);
50538 +
50539 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50540 + ASSERT_COND(p_PreviousMember);
50541 +
50542 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50543 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50544 +
50545 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50546 + break;
50547 +
50548 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50549 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50550 + ASSERT_COND(p_PreviousMember);
50551 +
50552 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50553 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50554 +
50555 + /* add the new member to the internal sw member list */
50556 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50557 + break;
50558 +
50559 + default:
50560 + /* unlock */
50561 + FrmReplicGroupUnlock(p_ReplicGroup);
50562 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50563 +
50564 + }
50565 +
50566 + /* unlock */
50567 + FrmReplicGroupUnlock(p_ReplicGroup);
50568 +
50569 + return E_OK;
50570 +}
50571 +
50572 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50573 + uint16_t memberIndex)
50574 +{
50575 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50576 + t_Error err;
50577 +
50578 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50579 +
50580 + /* lock */
50581 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50582 + if (GET_ERROR_TYPE(err) == E_BUSY)
50583 + return ERROR_CODE(E_BUSY);
50584 +
50585 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50586 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50587 +
50588 + /* Design decision: group must contain at least one member
50589 + No possibility to remove the last member from the group */
50590 + if (p_ReplicGroup->numOfEntries == 1)
50591 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50592 +
50593 + err = RemoveMember(p_ReplicGroup, memberIndex);
50594 +
50595 + /* unlock */
50596 + FrmReplicGroupUnlock(p_ReplicGroup);
50597 +
50598 + switch (GET_ERROR_TYPE(err))
50599 + {
50600 + case E_OK:
50601 + return E_OK;
50602 +
50603 + case E_BUSY:
50604 + DBG(TRACE, ("E_BUSY error"));
50605 + return ERROR_CODE(E_BUSY);
50606 +
50607 + default:
50608 + RETURN_ERROR(MAJOR, err, NO_MSG);
50609 + }
50610 +}
50611 +
50612 +/*********************** End of API routines ************************/
50613 +
50614 +
50615 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50616 new file mode 100644
50617 index 00000000..0e8e8bc0
50618 --- /dev/null
50619 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50620 @@ -0,0 +1,101 @@
50621 +/*
50622 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50623 + *
50624 + * Redistribution and use in source and binary forms, with or without
50625 + * modification, are permitted provided that the following conditions are met:
50626 + * * Redistributions of source code must retain the above copyright
50627 + * notice, this list of conditions and the following disclaimer.
50628 + * * Redistributions in binary form must reproduce the above copyright
50629 + * notice, this list of conditions and the following disclaimer in the
50630 + * documentation and/or other materials provided with the distribution.
50631 + * * Neither the name of Freescale Semiconductor nor the
50632 + * names of its contributors may be used to endorse or promote products
50633 + * derived from this software without specific prior written permission.
50634 + *
50635 + *
50636 + * ALTERNATIVELY, this software may be distributed under the terms of the
50637 + * GNU General Public License ("GPL") as published by the Free Software
50638 + * Foundation, either version 2 of that License or (at your option) any
50639 + * later version.
50640 + *
50641 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50642 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50643 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50644 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50645 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50646 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50647 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50648 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50649 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50650 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50651 + */
50652 +
50653 +
50654 +/******************************************************************************
50655 + @File fm_replic.h
50656 +
50657 + @Description FM frame replicator
50658 +*//***************************************************************************/
50659 +#ifndef __FM_REPLIC_H
50660 +#define __FM_REPLIC_H
50661 +
50662 +#include "std_ext.h"
50663 +#include "error_ext.h"
50664 +
50665 +
50666 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
50667 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
50668 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
50669 +#define FRM_REPLIC_FR_BIT 0x08000000
50670 +#define FRM_REPLIC_NL_BIT 0x10000000
50671 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
50672 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
50673 +
50674 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
50675 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
50676 +
50677 +#define SOURCE_TD_ITSELF_OPTION 0x01
50678 +#define SOURCE_TD_COPY_OPTION 0x02
50679 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
50680 +#define SOURCE_TD_NONE 0x04
50681 +
50682 +/*typedef enum e_SourceTdOption
50683 +{
50684 + e_SOURCE_TD_NONE = 0,
50685 + e_SOURCE_TD_ITSELF_OPTION = 1,
50686 + e_SOURCE_TD_COPY_OPTION = 2,
50687 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
50688 +} e_SourceTdOption;
50689 +*/
50690 +
50691 +typedef struct
50692 +{
50693 + volatile uint32_t type;
50694 + volatile uint32_t frGroupPointer;
50695 + volatile uint32_t operationCode;
50696 + volatile uint32_t reserved;
50697 +} t_FrmReplicGroupSourceAd;
50698 +
50699 +typedef struct t_FmPcdFrmReplicMember
50700 +{
50701 + void *p_MemberAd; /**< pointer to the member AD */
50702 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
50703 + t_Handle h_Manip; /**< manip handle - need for free routines */
50704 + t_List node;
50705 +} t_FmPcdFrmReplicMember;
50706 +
50707 +typedef struct t_FmPcdFrmReplicGroup
50708 +{
50709 + t_Handle h_FmPcd;
50710 +
50711 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
50712 + uint8_t numOfEntries; /**< actual number of members in the group */
50713 + uint16_t owners; /**< how many keys share this frame replicator group */
50714 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
50715 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
50716 + t_List availableMembersList;/**< list of all the available members in the group */
50717 + t_FmPcdLock *p_Lock;
50718 +} t_FmPcdFrmReplicGroup;
50719 +
50720 +
50721 +#endif /* __FM_REPLIC_H */
50722 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50723 new file mode 100644
50724 index 00000000..49b86e8e
50725 --- /dev/null
50726 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50727 @@ -0,0 +1,888 @@
50728 +/*
50729 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50730 + *
50731 + * Redistribution and use in source and binary forms, with or without
50732 + * modification, are permitted provided that the following conditions are met:
50733 + * * Redistributions of source code must retain the above copyright
50734 + * notice, this list of conditions and the following disclaimer.
50735 + * * Redistributions in binary form must reproduce the above copyright
50736 + * notice, this list of conditions and the following disclaimer in the
50737 + * documentation and/or other materials provided with the distribution.
50738 + * * Neither the name of Freescale Semiconductor nor the
50739 + * names of its contributors may be used to endorse or promote products
50740 + * derived from this software without specific prior written permission.
50741 + *
50742 + *
50743 + * ALTERNATIVELY, this software may be distributed under the terms of the
50744 + * GNU General Public License ("GPL") as published by the Free Software
50745 + * Foundation, either version 2 of that License or (at your option) any
50746 + * later version.
50747 + *
50748 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50749 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50750 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50751 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50752 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50753 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50754 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50755 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50756 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50757 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50758 + */
50759 +
50760 +#include "fsl_fman_kg.h"
50761 +
50762 +/****************************************/
50763 +/* static functions */
50764 +/****************************************/
50765 +
50766 +
50767 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50768 +{
50769 + uint32_t rw;
50770 +
50771 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50772 +
50773 + return (uint32_t)(FM_KG_KGAR_GO |
50774 + rw |
50775 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50776 + hwport_id |
50777 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50778 +}
50779 +
50780 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50781 +{
50782 + uint32_t ar;
50783 +
50784 + fman_kg_write_sp(regs, 0xffffffff, 0);
50785 +
50786 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50787 + fman_kg_write_ar_wait(regs, ar);
50788 +}
50789 +
50790 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50791 +{
50792 + uint32_t rw;
50793 +
50794 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50795 +
50796 + return (uint32_t)(FM_KG_KGAR_GO |
50797 + rw |
50798 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50799 + hwport_id |
50800 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50801 +}
50802 +
50803 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50804 +{
50805 + uint32_t ar;
50806 +
50807 + fman_kg_write_cpp(regs, 0);
50808 +
50809 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50810 + fman_kg_write_ar_wait(regs, ar);
50811 +}
50812 +
50813 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50814 + bool no_validation,
50815 + uint8_t *offset)
50816 +{
50817 + int code;
50818 +
50819 + switch (src) {
50820 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50821 + code = no_validation ? 0x73 : 0x3;
50822 + break;
50823 +
50824 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50825 + code = no_validation ? 0x77 : 0x7;
50826 + break;
50827 +
50828 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50829 + code = no_validation ? 0x74 : 0x4;
50830 + break;
50831 +
50832 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50833 + code = no_validation ? 0x75 : 0x5;
50834 + break;
50835 +
50836 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50837 + code = no_validation ? 0x76 : 0x6;
50838 + break;
50839 +
50840 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50841 + code = no_validation ? 0x78 : 0x8;
50842 + break;
50843 +
50844 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50845 + code = no_validation ? 0x79 : 0x9;
50846 + break;
50847 +
50848 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50849 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50850 + break;
50851 +
50852 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50853 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50854 + break;
50855 +
50856 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50857 + code = no_validation ? 0x7a : 0xa;
50858 + break;
50859 +
50860 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50861 + code = no_validation ? 0x7b : 0xb;
50862 + break;
50863 +
50864 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50865 + code = no_validation ? 0x7b : 0x1b;
50866 + break;
50867 +
50868 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50869 + code = no_validation ? 0x7c : 0xc;
50870 + break;
50871 +
50872 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50873 + code = no_validation ? 0x7c : 0x1c;
50874 + break;
50875 +
50876 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
50877 + code = no_validation ? 0x7c : 0x2c;
50878 + break;
50879 +
50880 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
50881 + code = no_validation ? 0x72 : 0x2;
50882 + break;
50883 +
50884 + case E_FMAN_KG_GEN_EXTRACT_GRE:
50885 + code = no_validation ? 0x7d : 0xd;
50886 + break;
50887 +
50888 + case E_FMAN_KG_GEN_EXTRACT_TCP:
50889 + code = no_validation ? 0x7e : 0xe;
50890 + break;
50891 +
50892 + case E_FMAN_KG_GEN_EXTRACT_UDP:
50893 + code = no_validation ? 0x7e : 0x1e;
50894 + break;
50895 +
50896 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
50897 + code = no_validation ? 0x7e : 0x3e;
50898 + break;
50899 +
50900 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
50901 + code = no_validation ? 0x7e : 0x4e;
50902 + break;
50903 +
50904 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
50905 + code = no_validation ? 0x7e : 0x2e;
50906 + break;
50907 +
50908 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
50909 + code = no_validation ? 0x7e : 0x6e;
50910 + break;
50911 +
50912 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
50913 + code = 0x70;
50914 + break;
50915 +
50916 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
50917 + code = 0x71;
50918 + break;
50919 +
50920 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
50921 + code = 0x10;
50922 + break;
50923 +
50924 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
50925 + code = 0x40;
50926 + break;
50927 +
50928 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
50929 + code = 0x20;
50930 + break;
50931 +
50932 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
50933 + code = 0x7f;
50934 + break;
50935 +
50936 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
50937 + code = 0x20;
50938 + *offset += 0x20;
50939 + break;
50940 +
50941 + default:
50942 + code = FM_KG_SCH_GEN_HT_INVALID;
50943 + }
50944 +
50945 + return (uint8_t)code;
50946 +}
50947 +
50948 +static uint32_t build_ar_scheme(uint8_t scheme,
50949 + uint8_t hwport_id,
50950 + bool update_counter,
50951 + bool write)
50952 +{
50953 + uint32_t rw;
50954 +
50955 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50956 +
50957 + return (uint32_t)(FM_KG_KGAR_GO |
50958 + rw |
50959 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
50960 + hwport_id |
50961 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
50962 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
50963 +}
50964 +
50965 +static uint32_t build_ar_cls_plan(uint8_t grp,
50966 + uint8_t entries_mask,
50967 + uint8_t hwport_id,
50968 + bool write)
50969 +{
50970 + uint32_t rw;
50971 +
50972 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50973 +
50974 + return (uint32_t)(FM_KG_KGAR_GO |
50975 + rw |
50976 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
50977 + hwport_id |
50978 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
50979 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
50980 +}
50981 +
50982 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
50983 +{
50984 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
50985 + /* Wait for GO to be idle and read error */
50986 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
50987 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
50988 + return -EINVAL;
50989 + return 0;
50990 +}
50991 +
50992 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
50993 +{
50994 +
50995 + struct fman_kg_pe_regs *kgpe_regs;
50996 + uint32_t tmp;
50997 +
50998 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50999 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
51000 +
51001 + if (add)
51002 + tmp |= sp;
51003 + else /* clear */
51004 + tmp &= ~sp;
51005 +
51006 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
51007 +
51008 +}
51009 +
51010 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
51011 +{
51012 + struct fman_kg_pe_regs *kgpe_regs;
51013 +
51014 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51015 +
51016 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
51017 +}
51018 +
51019 +void fman_kg_get_event(struct fman_kg_regs *regs,
51020 + uint32_t *event,
51021 + uint32_t *scheme_idx)
51022 +{
51023 + uint32_t mask, force;
51024 +
51025 + *event = ioread32be(&regs->fmkg_eer);
51026 + mask = ioread32be(&regs->fmkg_eeer);
51027 + *scheme_idx = ioread32be(&regs->fmkg_seer);
51028 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
51029 +
51030 + *event &= mask;
51031 +
51032 + /* clear the forced events */
51033 + force = ioread32be(&regs->fmkg_feer);
51034 + if (force & *event)
51035 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
51036 +
51037 + iowrite32be(*event, &regs->fmkg_eer);
51038 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
51039 +}
51040 +
51041 +
51042 +void fman_kg_init(struct fman_kg_regs *regs,
51043 + uint32_t exceptions,
51044 + uint32_t dflt_nia)
51045 +{
51046 + uint32_t tmp;
51047 + int i;
51048 +
51049 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
51050 + &regs->fmkg_eer);
51051 +
51052 + tmp = 0;
51053 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
51054 + tmp |= FM_EX_KG_DOUBLE_ECC;
51055 +
51056 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
51057 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
51058 +
51059 + iowrite32be(tmp, &regs->fmkg_eeer);
51060 + iowrite32be(0, &regs->fmkg_fdor);
51061 + iowrite32be(0, &regs->fmkg_gdv0r);
51062 + iowrite32be(0, &regs->fmkg_gdv1r);
51063 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
51064 +
51065 + /* Clear binding between ports to schemes and classification plans
51066 + * so that all ports are not bound to any scheme/classification plan */
51067 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
51068 + clear_pe_all_scheme(regs, (uint8_t)i);
51069 + clear_pe_all_cls_plan(regs, (uint8_t)i);
51070 + }
51071 +}
51072 +
51073 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
51074 +{
51075 + /* enable and enable all scheme interrupts */
51076 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
51077 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
51078 +}
51079 +
51080 +void fman_kg_enable(struct fman_kg_regs *regs)
51081 +{
51082 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
51083 + &regs->fmkg_gcr);
51084 +}
51085 +
51086 +void fman_kg_disable(struct fman_kg_regs *regs)
51087 +{
51088 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
51089 + &regs->fmkg_gcr);
51090 +}
51091 +
51092 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
51093 +{
51094 + iowrite32be(offset, &regs->fmkg_fdor);
51095 +}
51096 +
51097 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
51098 + uint8_t def_id,
51099 + uint32_t val)
51100 +{
51101 + if(def_id == 0)
51102 + iowrite32be(val, &regs->fmkg_gdv0r);
51103 + else
51104 + iowrite32be(val, &regs->fmkg_gdv1r);
51105 +}
51106 +
51107 +
51108 +void fman_kg_set_exception(struct fman_kg_regs *regs,
51109 + uint32_t exception,
51110 + bool enable)
51111 +{
51112 + uint32_t tmp;
51113 +
51114 + tmp = ioread32be(&regs->fmkg_eeer);
51115 +
51116 + if (enable) {
51117 + tmp |= exception;
51118 + } else {
51119 + tmp &= ~exception;
51120 + }
51121 +
51122 + iowrite32be(tmp, &regs->fmkg_eeer);
51123 +}
51124 +
51125 +void fman_kg_get_exception(struct fman_kg_regs *regs,
51126 + uint32_t *events,
51127 + uint32_t *scheme_ids,
51128 + bool clear)
51129 +{
51130 + uint32_t mask;
51131 +
51132 + *events = ioread32be(&regs->fmkg_eer);
51133 + mask = ioread32be(&regs->fmkg_eeer);
51134 + *events &= mask;
51135 +
51136 + *scheme_ids = 0;
51137 +
51138 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
51139 + *scheme_ids = ioread32be(&regs->fmkg_seer);
51140 + mask = ioread32be(&regs->fmkg_seeer);
51141 + *scheme_ids &= mask;
51142 + }
51143 +
51144 + if (clear) {
51145 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
51146 + iowrite32be(*events, &regs->fmkg_eer);
51147 + }
51148 +}
51149 +
51150 +void fman_kg_get_capture(struct fman_kg_regs *regs,
51151 + struct fman_kg_ex_ecc_attr *ecc_attr,
51152 + bool clear)
51153 +{
51154 + uint32_t tmp;
51155 +
51156 + tmp = ioread32be(&regs->fmkg_serc);
51157 +
51158 + if (tmp & KG_FMKG_SERC_CAP) {
51159 + /* Captured data is valid */
51160 + ecc_attr->valid = TRUE;
51161 + ecc_attr->double_ecc =
51162 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
51163 + ecc_attr->single_ecc_count =
51164 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
51165 + KG_FMKG_SERC_CNT_SHIFT);
51166 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
51167 +
51168 + if (clear)
51169 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
51170 + } else {
51171 + /* No ECC error is captured */
51172 + ecc_attr->valid = FALSE;
51173 + }
51174 +}
51175 +
51176 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
51177 + struct fman_kg_scheme_regs *scheme_regs)
51178 +{
51179 + struct fman_kg_extract_params *extract_params;
51180 + struct fman_kg_gen_extract_params *gen_params;
51181 + uint32_t tmp_reg, i, select, mask, fqb;
51182 + uint8_t offset, shift, ht;
51183 +
51184 + /* Zero out all registers so no need to care about unused ones */
51185 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
51186 +
51187 + /* Mode register */
51188 + tmp_reg = fm_kg_build_nia(params->next_engine,
51189 + params->next_engine_action);
51190 + if (tmp_reg == KG_NIA_INVALID) {
51191 + return -EINVAL;
51192 + }
51193 +
51194 + if (params->next_engine == E_FMAN_PCD_PLCR) {
51195 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
51196 + }
51197 + else if (params->next_engine == E_FMAN_PCD_CC) {
51198 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
51199 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
51200 + }
51201 +
51202 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
51203 + scheme_regs->kgse_mode = tmp_reg;
51204 +
51205 + /* Match vector */
51206 + scheme_regs->kgse_mv = params->match_vector;
51207 +
51208 + extract_params = &params->extract_params;
51209 +
51210 + /* Scheme default values registers */
51211 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
51212 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
51213 +
51214 + /* Extract Known Fields Command register */
51215 + scheme_regs->kgse_ekfc = extract_params->known_fields;
51216 +
51217 + /* Entry Extract Known Default Value register */
51218 + tmp_reg = 0;
51219 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
51220 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
51221 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
51222 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
51223 + tmp_reg |= extract_params->known_fields_def.etype <<
51224 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
51225 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
51226 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
51227 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
51228 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
51229 + tmp_reg |= extract_params->known_fields_def.mpls <<
51230 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
51231 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
51232 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
51233 + tmp_reg |= extract_params->known_fields_def.ptype <<
51234 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51235 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51236 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51237 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51238 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51239 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51240 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51241 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51242 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51243 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51244 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51245 +
51246 + scheme_regs->kgse_ekdv = tmp_reg;
51247 +
51248 + /* Generic extract registers */
51249 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51250 + return -EINVAL;
51251 + }
51252 +
51253 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51254 + gen_params = extract_params->gen_extract + i;
51255 +
51256 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51257 + tmp_reg |= (uint32_t)gen_params->def_val <<
51258 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51259 +
51260 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51261 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51262 + (gen_params->extract == 0)) {
51263 + return -EINVAL;
51264 + }
51265 + } else {
51266 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51267 + }
51268 +
51269 + tmp_reg |= (uint32_t)gen_params->extract <<
51270 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51271 + tmp_reg |= (uint32_t)gen_params->mask <<
51272 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51273 +
51274 + offset = gen_params->offset;
51275 + ht = get_gen_ht_code(gen_params->src,
51276 + gen_params->no_validation,
51277 + &offset);
51278 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51279 + tmp_reg |= offset;
51280 +
51281 + scheme_regs->kgse_gec[i] = tmp_reg;
51282 + }
51283 +
51284 + /* Masks registers */
51285 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51286 + return -EINVAL;
51287 + }
51288 +
51289 + select = 0;
51290 + mask = 0;
51291 + fqb = 0;
51292 + for (i = 0; i < extract_params->masks_num; i++) {
51293 + /* MCSx fields */
51294 + KG_GET_MASK_SEL_SHIFT(shift, i);
51295 + if (extract_params->masks[i].is_known) {
51296 + /* Mask known field */
51297 + select |= extract_params->masks[i].field_or_gen_idx <<
51298 + shift;
51299 + } else {
51300 + /* Mask generic extract */
51301 + select |= (extract_params->masks[i].field_or_gen_idx +
51302 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51303 + }
51304 +
51305 + /* MOx fields - spread between se_bmch and se_fqb registers */
51306 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51307 + if (i < 2) {
51308 + select |= (uint32_t)extract_params->masks[i].offset <<
51309 + shift;
51310 + } else {
51311 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51312 + shift;
51313 + }
51314 +
51315 + /* BMx fields */
51316 + KG_GET_MASK_SHIFT(shift, i);
51317 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51318 + }
51319 +
51320 + /* Finish with rest of BMx fileds -
51321 + * don't mask bits for unused masks by setting
51322 + * corresponding BMx field = 0xFF */
51323 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51324 + KG_GET_MASK_SHIFT(shift, i);
51325 + mask |= 0xFF << shift;
51326 + }
51327 +
51328 + scheme_regs->kgse_bmch = select;
51329 + scheme_regs->kgse_bmcl = mask;
51330 +
51331 + /* Finish with FQB register initialization.
51332 + * Check fqid is 24-bit value. */
51333 + if (params->base_fqid & ~0x00FFFFFF) {
51334 + return -EINVAL;
51335 + }
51336 +
51337 + fqb |= params->base_fqid;
51338 + scheme_regs->kgse_fqb = fqb;
51339 +
51340 + /* Hash Configuration register */
51341 + tmp_reg = 0;
51342 + if (params->hash_params.use_hash) {
51343 + /* Check hash mask is 24-bit value */
51344 + if (params->hash_params.mask & ~0x00FFFFFF) {
51345 + return -EINVAL;
51346 + }
51347 +
51348 + /* Hash function produces 64-bit value, 24 bits of that
51349 + * are used to generate fq_id and policer profile.
51350 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51351 + */
51352 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51353 + return -EINVAL;
51354 + }
51355 +
51356 + tmp_reg |= params->hash_params.mask;
51357 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51358 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51359 +
51360 + if (params->hash_params.sym) {
51361 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51362 + }
51363 +
51364 + }
51365 +
51366 + if (params->bypass_fqid_gen) {
51367 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51368 + }
51369 +
51370 + scheme_regs->kgse_hc = tmp_reg;
51371 +
51372 + /* Policer Profile register */
51373 + if (params->policer_params.bypass_pp_gen) {
51374 + tmp_reg = 0;
51375 + } else {
51376 + /* Lower 8 bits of 24-bits extracted from hash result
51377 + * are used for policer profile generation.
51378 + * That leaves maximum shift value = 23. */
51379 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51380 + return -EINVAL;
51381 + }
51382 +
51383 + tmp_reg = params->policer_params.base;
51384 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51385 + FMAN_KG_SCH_PP_SH_SHIFT) &
51386 + FMAN_KG_SCH_PP_SH_MASK;
51387 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51388 + FMAN_KG_SCH_PP_SL_SHIFT) &
51389 + FMAN_KG_SCH_PP_SL_MASK;
51390 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51391 + FMAN_KG_SCH_PP_MASK_SHIFT;
51392 + }
51393 +
51394 + scheme_regs->kgse_ppc = tmp_reg;
51395 +
51396 + /* Coarse Classification Bit Select register */
51397 + if (params->next_engine == E_FMAN_PCD_CC) {
51398 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51399 + }
51400 +
51401 + /* Packets Counter register */
51402 + if (params->update_counter) {
51403 + scheme_regs->kgse_spc = params->counter_value;
51404 + }
51405 +
51406 + return 0;
51407 +}
51408 +
51409 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51410 + uint8_t scheme_id,
51411 + uint8_t hwport_id,
51412 + struct fman_kg_scheme_regs *scheme_regs,
51413 + bool update_counter)
51414 +{
51415 + struct fman_kg_scheme_regs *kgse_regs;
51416 + uint32_t tmp_reg;
51417 + int err, i;
51418 +
51419 + /* Write indirect scheme registers */
51420 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51421 +
51422 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51423 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51424 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51425 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51426 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51427 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51428 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51429 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51430 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51431 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51432 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51433 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51434 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51435 +
51436 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51437 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51438 +
51439 + /* Write AR (Action register) */
51440 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51441 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51442 + return err;
51443 +}
51444 +
51445 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51446 + uint8_t scheme_id,
51447 + uint8_t hwport_id)
51448 +{
51449 + struct fman_kg_scheme_regs *kgse_regs;
51450 + uint32_t tmp_reg;
51451 + int err, i;
51452 +
51453 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51454 +
51455 + /* Clear all registers including enable bit in mode register */
51456 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51457 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51458 + }
51459 +
51460 + /* Write AR (Action register) */
51461 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51462 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51463 + return err;
51464 +}
51465 +
51466 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51467 + uint8_t scheme_id,
51468 + uint8_t hwport_id,
51469 + uint32_t *counter)
51470 +{
51471 + struct fman_kg_scheme_regs *kgse_regs;
51472 + uint32_t tmp_reg;
51473 + int err;
51474 +
51475 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51476 +
51477 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51478 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51479 +
51480 + if (err != 0)
51481 + return err;
51482 +
51483 + *counter = ioread32be(&kgse_regs->kgse_spc);
51484 +
51485 + return 0;
51486 +}
51487 +
51488 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51489 + uint8_t scheme_id,
51490 + uint8_t hwport_id,
51491 + uint32_t counter)
51492 +{
51493 + struct fman_kg_scheme_regs *kgse_regs;
51494 + uint32_t tmp_reg;
51495 + int err;
51496 +
51497 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51498 +
51499 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51500 +
51501 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51502 + if (err != 0)
51503 + return err;
51504 +
51505 + /* Keygen indirect access memory contains all scheme_id registers
51506 + * by now. Change only counter value. */
51507 + iowrite32be(counter, &kgse_regs->kgse_spc);
51508 +
51509 + /* Write back scheme registers */
51510 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51511 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51512 +
51513 + return err;
51514 +}
51515 +
51516 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51517 +{
51518 + return ioread32be(&regs->fmkg_tpc);
51519 +}
51520 +
51521 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51522 + struct fman_kg_cp_regs *cls_plan_regs)
51523 +{
51524 + uint8_t entries_set, entry_bit;
51525 + int i;
51526 +
51527 + /* Zero out all group's register */
51528 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51529 +
51530 + /* Go over all classification entries in params->entries_mask and
51531 + * configure the corresponding cpe register */
51532 + entries_set = params->entries_mask;
51533 + for (i = 0; entries_set; i++) {
51534 + entry_bit = (uint8_t)(0x80 >> i);
51535 + if ((entry_bit & entries_set) == 0)
51536 + continue;
51537 + entries_set ^= entry_bit;
51538 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51539 + }
51540 +
51541 + return 0;
51542 +}
51543 +
51544 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51545 + uint8_t grp_id,
51546 + uint8_t entries_mask,
51547 + uint8_t hwport_id,
51548 + struct fman_kg_cp_regs *cls_plan_regs)
51549 +{
51550 + struct fman_kg_cp_regs *kgcpe_regs;
51551 + uint32_t tmp_reg;
51552 + int i, err;
51553 +
51554 + /* Check group index is valid and the group isn't empty */
51555 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51556 + return -EINVAL;
51557 +
51558 + /* Write indirect classification plan registers */
51559 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51560 +
51561 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51562 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51563 + }
51564 +
51565 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51566 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51567 + return err;
51568 +}
51569 +
51570 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51571 + uint8_t hwport_id,
51572 + uint32_t schemes)
51573 +{
51574 + struct fman_kg_pe_regs *kg_pe_regs;
51575 + uint32_t tmp_reg;
51576 + int err;
51577 +
51578 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51579 +
51580 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51581 +
51582 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51583 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51584 + return err;
51585 +}
51586 +
51587 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51588 + uint8_t grp_mask,
51589 + uint32_t *bind_cls_plans)
51590 +{
51591 + /* Check grp_base and grp_mask are 5-bits values */
51592 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51593 + return -EINVAL;
51594 +
51595 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51596 + return 0;
51597 +}
51598 +
51599 +
51600 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51601 + uint8_t hwport_id,
51602 + uint32_t bind_cls_plans)
51603 +{
51604 + struct fman_kg_pe_regs *kg_pe_regs;
51605 + uint32_t tmp_reg;
51606 + int err;
51607 +
51608 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51609 +
51610 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51611 +
51612 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51613 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51614 + return err;
51615 +}
51616 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51617 new file mode 100644
51618 index 00000000..108779db
51619 --- /dev/null
51620 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51621 @@ -0,0 +1,129 @@
51622 +/*
51623 + * Copyright 2012 Freescale Semiconductor Inc.
51624 + *
51625 + * Redistribution and use in source and binary forms, with or without
51626 + * modification, are permitted provided that the following conditions are met:
51627 + * * Redistributions of source code must retain the above copyright
51628 + * notice, this list of conditions and the following disclaimer.
51629 + * * Redistributions in binary form must reproduce the above copyright
51630 + * notice, this list of conditions and the following disclaimer in the
51631 + * documentation and/or other materials provided with the distribution.
51632 + * * Neither the name of Freescale Semiconductor nor the
51633 + * names of its contributors may be used to endorse or promote products
51634 + * derived from this software without specific prior written permission.
51635 + *
51636 + *
51637 + * ALTERNATIVELY, this software may be distributed under the terms of the
51638 + * GNU General Public License ("GPL") as published by the Free Software
51639 + * Foundation, either version 2 of that License or (at your option) any
51640 + * later version.
51641 + *
51642 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51643 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51644 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51645 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51646 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51647 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51648 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51649 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51650 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51651 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51652 + */
51653 +
51654 +#include "fsl_fman_prs.h"
51655 +
51656 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51657 +{
51658 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51659 +}
51660 +
51661 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51662 +{
51663 + return ioread32be(&regs->fmpr_perer);
51664 +}
51665 +
51666 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51667 +{
51668 + iowrite32be(event, &regs->fmpr_perr);
51669 +}
51670 +
51671 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51672 +{
51673 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51674 +}
51675 +
51676 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51677 +{
51678 + return ioread32be(&regs->fmpr_pever);
51679 +}
51680 +
51681 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51682 +{
51683 + iowrite32be(event, &regs->fmpr_pevr);
51684 +}
51685 +
51686 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51687 +{
51688 + cfg->port_id_stat = 0;
51689 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51690 + cfg->prs_exceptions = 0x03000000;
51691 +}
51692 +
51693 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51694 +{
51695 + uint32_t tmp;
51696 +
51697 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51698 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51699 + &regs->fmpr_pevr);
51700 +
51701 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51702 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51703 + else
51704 + iowrite32be(0, &regs->fmpr_pever);
51705 +
51706 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51707 +
51708 + tmp = 0;
51709 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51710 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51711 + iowrite32be(tmp, &regs->fmpr_perer);
51712 +
51713 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51714 +
51715 + return 0;
51716 +}
51717 +
51718 +void fman_prs_enable(struct fman_prs_regs *regs)
51719 +{
51720 + uint32_t tmp;
51721 +
51722 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51723 + iowrite32be(tmp, &regs->fmpr_rpimac);
51724 +}
51725 +
51726 +void fman_prs_disable(struct fman_prs_regs *regs)
51727 +{
51728 + uint32_t tmp;
51729 +
51730 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51731 + iowrite32be(tmp, &regs->fmpr_rpimac);
51732 +}
51733 +
51734 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51735 +{
51736 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51737 +}
51738 +
51739 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51740 +{
51741 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51742 +}
51743 +
51744 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51745 +{
51746 + if (enable)
51747 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51748 + else
51749 + iowrite32be(0, &regs->fmpr_ppsc);
51750 +}
51751 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51752 new file mode 100644
51753 index 00000000..7d928e0a
51754 --- /dev/null
51755 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51756 @@ -0,0 +1,15 @@
51757 +#
51758 +# Makefile for the Freescale Ethernet controllers
51759 +#
51760 +ccflags-y += -DVERSION=\"\"
51761 +#
51762 +#Include netcomm SW specific definitions
51763 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51764 +
51765 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51766 +
51767 +ccflags-y += -I$(NCSW_FM_INC)
51768 +
51769 +obj-y += fsl-ncsw-Pcd.o
51770 +
51771 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51772 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51773 new file mode 100644
51774 index 00000000..ec6e0ed5
51775 --- /dev/null
51776 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51777 @@ -0,0 +1,6436 @@
51778 +/*
51779 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51780 + *
51781 + * Redistribution and use in source and binary forms, with or without
51782 + * modification, are permitted provided that the following conditions are met:
51783 + * * Redistributions of source code must retain the above copyright
51784 + * notice, this list of conditions and the following disclaimer.
51785 + * * Redistributions in binary form must reproduce the above copyright
51786 + * notice, this list of conditions and the following disclaimer in the
51787 + * documentation and/or other materials provided with the distribution.
51788 + * * Neither the name of Freescale Semiconductor nor the
51789 + * names of its contributors may be used to endorse or promote products
51790 + * derived from this software without specific prior written permission.
51791 + *
51792 + *
51793 + * ALTERNATIVELY, this software may be distributed under the terms of the
51794 + * GNU General Public License ("GPL") as published by the Free Software
51795 + * Foundation, either version 2 of that License or (at your option) any
51796 + * later version.
51797 + *
51798 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51799 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51800 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51801 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51802 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51803 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51804 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51805 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51806 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51807 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51808 + */
51809 +
51810 +
51811 +/******************************************************************************
51812 + @File fm_port.c
51813 +
51814 + @Description FM driver routines implementation.
51815 + *//***************************************************************************/
51816 +#include "error_ext.h"
51817 +#include "std_ext.h"
51818 +#include "string_ext.h"
51819 +#include "sprint_ext.h"
51820 +#include "debug_ext.h"
51821 +#include "fm_muram_ext.h"
51822 +
51823 +#include "fman_common.h"
51824 +#include "fm_port.h"
51825 +#include "fm_port_dsar.h"
51826 +#include "common/general.h"
51827 +
51828 +/****************************************/
51829 +/* static functions */
51830 +/****************************************/
51831 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51832 +
51833 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51834 +{
51835 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51836 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51837 + t_Error ans = E_OK;
51838 + uint32_t unusedMask;
51839 +
51840 + if (p_FmPort->imEn)
51841 + {
51842 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51843 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51844 + > 2)
51845 + RETURN_ERROR(
51846 + MAJOR,
51847 + E_INVALID_VALUE,
51848 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51849 +
51850 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51851 + return ERROR_CODE(ans);
51852 + }
51853 + else
51854 + {
51855 + /****************************************/
51856 + /* Rx only */
51857 + /****************************************/
51858 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51859 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51860 + {
51861 + /* external buffer pools */
51862 + if (!p_Params->extBufPools.numOfPoolsUsed)
51863 + RETURN_ERROR(
51864 + MAJOR,
51865 + E_INVALID_VALUE,
51866 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51867 +
51868 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51869 + p_Params->p_BackupBmPools,
51870 + &p_Params->bufPoolDepletion) != E_OK)
51871 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51872 +
51873 + /* Check that part of IC that needs copying is small enough to enter start margin */
51874 + if (p_Params->intContext.size
51875 + && (p_Params->intContext.size
51876 + + p_Params->intContext.extBufOffset
51877 + > p_Params->bufMargins.startMargins))
51878 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51879 + ("intContext.size is larger than start margins"));
51880 +
51881 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
51882 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
51883 + RETURN_ERROR(
51884 + MAJOR,
51885 + E_INVALID_VALUE,
51886 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
51887 +
51888 +#ifdef FM_NO_BACKUP_POOLS
51889 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
51890 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
51891 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
51892 +#endif /* FM_NO_BACKUP_POOLS */
51893 + }
51894 +
51895 + /****************************************/
51896 + /* Non Rx ports */
51897 + /****************************************/
51898 + else
51899 + {
51900 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
51901 + RETURN_ERROR(
51902 + MAJOR,
51903 + E_INVALID_VALUE,
51904 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
51905 +
51906 + /* to protect HW internal-context from overwrite */
51907 + if ((p_Params->intContext.size)
51908 + && (p_Params->intContext.intContextOffset
51909 + < MIN_TX_INT_OFFSET))
51910 + RETURN_ERROR(
51911 + MAJOR,
51912 + E_INVALID_VALUE,
51913 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
51914 +
51915 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51916 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
51917 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
51918 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51919 + != DEFAULT_notSupported))
51920 + {
51921 + /* Check that not larger than 8 */
51922 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
51923 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51924 + > MAX_FIFO_PIPELINE_DEPTH))
51925 + RETURN_ERROR(
51926 + MAJOR,
51927 + E_INVALID_VALUE,
51928 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
51929 + }
51930 + }
51931 +
51932 + /****************************************/
51933 + /* Rx Or Offline Parsing */
51934 + /****************************************/
51935 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51936 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51937 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51938 + {
51939 + if (!p_Params->dfltFqid)
51940 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51941 + ("dfltFqid must be between 1 and 2^24-1"));
51942 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
51943 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
51944 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
51945 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
51946 + }
51947 +
51948 + /****************************************/
51949 + /* All ports */
51950 + /****************************************/
51951 + /* common BMI registers values */
51952 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
51953 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
51954 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51955 + ("errFqid must be between 1 and 2^24-1"));
51956 + if (p_Params->dfltFqid & ~0x00FFFFFF)
51957 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51958 + ("dfltFqid must be between 1 and 2^24-1"));
51959 + }
51960 +
51961 + /****************************************/
51962 + /* Rx only */
51963 + /****************************************/
51964 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51965 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51966 + {
51967 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
51968 + RETURN_ERROR(
51969 + MAJOR,
51970 + E_INVALID_VALUE,
51971 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
51972 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
51973 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
51974 + RETURN_ERROR(
51975 + MAJOR,
51976 + E_INVALID_VALUE,
51977 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51978 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
51979 + RETURN_ERROR(
51980 + MAJOR,
51981 + E_INVALID_VALUE,
51982 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
51983 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
51984 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
51985 + RETURN_ERROR(
51986 + MAJOR,
51987 + E_INVALID_VALUE,
51988 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51989 +
51990 + /* Check that not larger than 16 */
51991 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
51992 + RETURN_ERROR(
51993 + MAJOR,
51994 + E_INVALID_VALUE,
51995 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51996 +
51997 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
51998 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51999 +
52000 + /* extra FIFO size (allowed only to Rx ports) */
52001 + if (p_Params->setSizeOfFifo
52002 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
52003 + RETURN_ERROR(
52004 + MAJOR,
52005 + E_INVALID_VALUE,
52006 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
52007 +
52008 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
52009 + && !p_Params->bufPoolDepletion.numOfPools)
52010 + RETURN_ERROR(
52011 + MAJOR,
52012 + E_INVALID_VALUE,
52013 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
52014 +#ifdef FM_CSI_CFED_LIMIT
52015 + if (p_FmPort->fmRevInfo.majorRev == 4)
52016 + {
52017 + /* Check that not larger than 16 */
52018 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
52019 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
52020 + }
52021 +#endif /* FM_CSI_CFED_LIMIT */
52022 + }
52023 +
52024 + /****************************************/
52025 + /* Non Rx ports */
52026 + /****************************************/
52027 + /* extra FIFO size (allowed only to Rx ports) */
52028 + else
52029 + if (p_FmPort->fifoBufs.extra)
52030 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52031 + (" No fifoBufs.extra for non Rx ports"));
52032 +
52033 + /****************************************/
52034 + /* Tx only */
52035 + /****************************************/
52036 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52037 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52038 + {
52039 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
52040 + RETURN_ERROR(
52041 + MAJOR,
52042 + E_INVALID_VALUE,
52043 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
52044 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
52045 + RETURN_ERROR(
52046 + MAJOR,
52047 + E_INVALID_VALUE,
52048 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
52049 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
52050 + RETURN_ERROR(
52051 + MAJOR,
52052 + E_INVALID_VALUE,
52053 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
52054 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
52055 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
52056 + RETURN_ERROR(
52057 + MAJOR,
52058 + E_INVALID_VALUE,
52059 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52060 +
52061 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
52062 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52063 + > 2)
52064 + RETURN_ERROR(
52065 + MAJOR, E_INVALID_VALUE,
52066 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
52067 + }
52068 +
52069 + /****************************************/
52070 + /* Non Tx Ports */
52071 + /****************************************/
52072 + /* If discard override was selected , no frames may be discarded. */
52073 + else
52074 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
52075 + RETURN_ERROR(
52076 + MAJOR,
52077 + E_CONFLICT,
52078 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
52079 +
52080 + /****************************************/
52081 + /* Rx and Offline parsing */
52082 + /****************************************/
52083 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52084 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52085 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52086 + {
52087 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52088 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
52089 + else
52090 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
52091 +
52092 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
52093 + if (p_Params->errorsToDiscard & unusedMask)
52094 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
52095 + ("errorsToDiscard contains undefined bits"));
52096 + }
52097 +
52098 + /****************************************/
52099 + /* Offline Ports */
52100 + /****************************************/
52101 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
52102 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
52103 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52104 + && p_Params->setNumOfOpenDmas
52105 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
52106 + RETURN_ERROR(
52107 + MAJOR,
52108 + E_INVALID_VALUE,
52109 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
52110 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
52111 +
52112 + /****************************************/
52113 + /* Offline & HC Ports */
52114 + /****************************************/
52115 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52116 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52117 + {
52118 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
52119 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
52120 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
52121 + /* this is an indication that user called config for this mode which is not supported in this integration */
52122 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
52123 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
52124 +
52125 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
52126 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
52127 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
52128 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
52129 + /* this is an indication that user called config for this mode which is not supported in this integration */
52130 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
52131 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
52132 + }
52133 +
52134 + /****************************************/
52135 + /* All ports */
52136 + /****************************************/
52137 + /* Check that not larger than 16 */
52138 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
52139 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
52140 + RETURN_ERROR(
52141 + MAJOR,
52142 + E_INVALID_VALUE,
52143 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
52144 +
52145 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
52146 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52147 +
52148 + /* common BMI registers values */
52149 + if (p_Params->setNumOfTasks
52150 + && ((!p_FmPort->tasks.num)
52151 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
52152 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52153 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
52154 + if (p_Params->setNumOfTasks
52155 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
52156 + RETURN_ERROR(
52157 + MAJOR,
52158 + E_INVALID_VALUE,
52159 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
52160 + if (p_Params->setNumOfOpenDmas
52161 + && ((!p_FmPort->openDmas.num)
52162 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
52163 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52164 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
52165 + if (p_Params->setNumOfOpenDmas
52166 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
52167 + RETURN_ERROR(
52168 + MAJOR,
52169 + E_INVALID_VALUE,
52170 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
52171 + if (p_Params->setSizeOfFifo
52172 + && (!p_FmPort->fifoBufs.num
52173 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
52174 + RETURN_ERROR(
52175 + MAJOR,
52176 + E_INVALID_VALUE,
52177 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52178 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
52179 + RETURN_ERROR(
52180 + MAJOR, E_INVALID_VALUE,
52181 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
52182 +
52183 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
52184 + if (p_FmPort->fmRevInfo.majorRev == 4)
52185 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
52186 + /* this is an indication that user called config for this mode which is not supported in this integration */
52187 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
52188 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
52189 +
52190 + return E_OK;
52191 +}
52192 +
52193 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
52194 +{
52195 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
52196 +
52197 + /*************************/
52198 + /* TX PORTS */
52199 + /*************************/
52200 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52201 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52202 + {
52203 + minFifoSizeRequired =
52204 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52205 + + (3 * BMI_FIFO_UNITS));
52206 + if (!p_FmPort->imEn)
52207 + minFifoSizeRequired +=
52208 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52209 + * BMI_FIFO_UNITS;
52210 +
52211 + optFifoSizeForB2B = minFifoSizeRequired;
52212 +
52213 + /* Add some margin for back-to-back capability to improve performance,
52214 + allows the hardware to pipeline new frame dma while the previous
52215 + frame not yet transmitted. */
52216 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52217 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52218 + else
52219 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
52220 + }
52221 +
52222 + /*************************/
52223 + /* RX IM PORTS */
52224 + /*************************/
52225 + else
52226 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52227 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52228 + && p_FmPort->imEn)
52229 + {
52230 + optFifoSizeForB2B =
52231 + minFifoSizeRequired =
52232 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52233 + + (4 * BMI_FIFO_UNITS));
52234 + }
52235 +
52236 + /*************************/
52237 + /* RX non-IM PORTS */
52238 + /*************************/
52239 + else
52240 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52241 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52242 + && !p_FmPort->imEn)
52243 + {
52244 + if (p_FmPort->fmRevInfo.majorRev == 4)
52245 + {
52246 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52247 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52248 + else
52249 + minFifoSizeRequired =
52250 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52251 + + (7 * BMI_FIFO_UNITS));
52252 + }
52253 + else
52254 + {
52255 +#if (DPAA_VERSION >= 11)
52256 + minFifoSizeRequired =
52257 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52258 + + (5 * BMI_FIFO_UNITS));
52259 + /* 4 according to spec + 1 for FOF>0 */
52260 +#else
52261 + minFifoSizeRequired = (uint32_t)
52262 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52263 + + (7*BMI_FIFO_UNITS));
52264 +#endif /* (DPAA_VERSION >= 11) */
52265 + }
52266 +
52267 + optFifoSizeForB2B = minFifoSizeRequired;
52268 +
52269 + /* Add some margin for back-to-back capability to improve performance,
52270 + allows the hardware to pipeline new frame dma while the previous
52271 + frame not yet transmitted. */
52272 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52273 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52274 + else
52275 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52276 + }
52277 +
52278 + /* For O/H ports, check fifo size and update if necessary */
52279 + else
52280 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52281 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52282 + {
52283 +#if (DPAA_VERSION >= 11)
52284 + optFifoSizeForB2B =
52285 + minFifoSizeRequired =
52286 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52287 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52288 + + 5) * BMI_FIFO_UNITS));
52289 + /* 4 according to spec + 1 for FOF>0 */
52290 +#else
52291 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52292 +#endif /* (DPAA_VERSION >= 11) */
52293 + }
52294 +
52295 + ASSERT_COND(minFifoSizeRequired > 0);
52296 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52297 +
52298 + /* Verify the size */
52299 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52300 + DBG(INFO,
52301 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52302 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52303 + DBG(INFO,
52304 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52305 +
52306 + return E_OK;
52307 +}
52308 +
52309 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52310 +{
52311 + if (p_FmPort->p_FmPortDriverParam)
52312 + {
52313 + XX_Free(p_FmPort->p_FmPortDriverParam);
52314 + p_FmPort->p_FmPortDriverParam = NULL;
52315 + }
52316 +}
52317 +
52318 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52319 +{
52320 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52321 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52322 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52323 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52324 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52325 + int i = 0, j = 0, err;
52326 + struct fman_port_bpools bpools;
52327 +
52328 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52329 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52330 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52331 +
52332 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52333 + sizesArray);
52334 +
52335 + /* Prepare flibs bpools structure */
52336 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52337 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52338 + bpools.counters_enable = TRUE;
52339 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52340 + {
52341 + bpools.bpool[i].bpid = orderedArray[i];
52342 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52343 + /* functionality available only for some derivatives (limited by config) */
52344 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52345 + for (j = 0;
52346 + j
52347 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52348 + j++)
52349 + if (orderedArray[i]
52350 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52351 + {
52352 + bpools.bpool[i].is_backup = TRUE;
52353 + break;
52354 + }
52355 + }
52356 +
52357 + /* save pools parameters for later use */
52358 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52359 + p_FmPort->rxPoolsParams.largestBufSize =
52360 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52361 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52362 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52363 +
52364 + /* FMBM_RMPD reg. - pool depletion */
52365 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52366 + {
52367 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52368 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52369 + {
52370 + if (p_BufPoolDepletion->poolsToConsider[i])
52371 + {
52372 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52373 + {
52374 + if (i == orderedArray[j])
52375 + {
52376 + bpools.bpool[j].grp_bp_depleted = TRUE;
52377 + break;
52378 + }
52379 + }
52380 + }
52381 + }
52382 + }
52383 +
52384 + if (p_BufPoolDepletion->singlePoolModeEnable)
52385 + {
52386 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52387 + {
52388 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52389 + {
52390 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52391 + {
52392 + if (i == orderedArray[j])
52393 + {
52394 + bpools.bpool[j].single_bp_depleted = TRUE;
52395 + break;
52396 + }
52397 + }
52398 + }
52399 + }
52400 + }
52401 +
52402 +#if (DPAA_VERSION >= 11)
52403 + /* fill QbbPEV */
52404 + if (p_BufPoolDepletion->poolsGrpModeEnable
52405 + || p_BufPoolDepletion->singlePoolModeEnable)
52406 + {
52407 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52408 + {
52409 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52410 + {
52411 + bpools.bpool[i].pfc_priorities_en = TRUE;
52412 + }
52413 + }
52414 + }
52415 +#endif /* (DPAA_VERSION >= 11) */
52416 +
52417 + /* Issue flibs function */
52418 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52419 + if (err != 0)
52420 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52421 +
52422 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52423 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52424 +
52425 + return E_OK;
52426 +}
52427 +
52428 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52429 +{
52430 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52431 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52432 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52433 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52434 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52435 + return E_OK;
52436 +}
52437 +
52438 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52439 +{
52440 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52441 + struct fman_port_params portParams;
52442 + uint32_t tmpVal;
52443 + t_Error err;
52444 +
52445 + /* Set up flibs parameters and issue init function */
52446 +
52447 + memset(&portParams, 0, sizeof(struct fman_port_params));
52448 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52449 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52450 + portParams.err_fqid = p_DriverParams->errFqid;
52451 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52452 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52453 + switch (p_FmPort->portType)
52454 + {
52455 + case (e_FM_PORT_TYPE_RX_10G):
52456 + case (e_FM_PORT_TYPE_RX):
52457 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52458 + if (!p_FmPort->imEn)
52459 + {
52460 + if (p_DriverParams->forwardReuseIntContext)
52461 + p_DriverParams->dfltCfg.rx_fd_bits =
52462 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52463 + }
52464 + break;
52465 +
52466 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52467 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52468 + break;
52469 + break;
52470 +
52471 + default:
52472 + break;
52473 + }
52474 +
52475 + tmpVal =
52476 + (uint32_t)(
52477 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52478 + / OFFSET_UNITS + 1) :
52479 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52480 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52481 + p_DriverParams->dfltCfg.int_buf_start_margin =
52482 + p_FmPort->internalBufferOffset;
52483 +
52484 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52485 + p_DriverParams->bufMargins.startMargins;
52486 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52487 + p_DriverParams->bufMargins.endMargins;
52488 +
52489 + p_DriverParams->dfltCfg.ic_ext_offset =
52490 + p_DriverParams->intContext.extBufOffset;
52491 + p_DriverParams->dfltCfg.ic_int_offset =
52492 + p_DriverParams->intContext.intContextOffset;
52493 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52494 +
52495 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52496 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52497 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52498 +
52499 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52500 + (uint8_t)p_FmPort->tasks.num;
52501 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52502 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52503 + else
52504 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52505 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52506 + (uint8_t)p_FmPort->openDmas.num;
52507 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52508 +
52509 + if (0
52510 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52511 + &portParams))
52512 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52513 +
52514 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52515 + RETURN_ERROR(MAJOR, err, NO_MSG);
52516 + else
52517 + {
52518 + // from QMIInit
52519 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52520 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52521 + {
52522 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52523 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52524 + FALSE);
52525 + else
52526 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52527 + TRUE);
52528 + }
52529 + }
52530 + /* The code bellow is a trick so the FM will not release the buffer
52531 + to BM nor will try to enqueue the frame to QM */
52532 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52533 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52534 + {
52535 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52536 + {
52537 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52538 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52539 + * buffers to BM regardless of fmbm_tfene
52540 + */
52541 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52542 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52543 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52544 + }
52545 + }
52546 +
52547 + return E_OK;
52548 +}
52549 +
52550 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52551 +{
52552 + UNUSED(p_FmPort);
52553 +
52554 + switch (counter)
52555 + {
52556 + case (e_FM_PORT_COUNTERS_CYCLE):
52557 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52558 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52559 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52560 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52561 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52562 + case (e_FM_PORT_COUNTERS_FRAME):
52563 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52564 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52565 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52566 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52567 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52568 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52569 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52570 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52571 + return TRUE;
52572 + default:
52573 + return FALSE;
52574 + }
52575 +}
52576 +
52577 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52578 +{
52579 + UNUSED(p_FmPort);
52580 +
52581 + switch (counter)
52582 + {
52583 + case (e_FM_PORT_COUNTERS_CYCLE):
52584 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52585 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52586 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52587 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52588 + case (e_FM_PORT_COUNTERS_FRAME):
52589 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52590 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52591 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52592 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52593 + return TRUE;
52594 + default:
52595 + return FALSE;
52596 + }
52597 +}
52598 +
52599 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52600 +{
52601 + switch (counter)
52602 + {
52603 + case (e_FM_PORT_COUNTERS_CYCLE):
52604 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52605 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52606 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52607 + case (e_FM_PORT_COUNTERS_FRAME):
52608 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52609 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52610 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52611 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52612 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52613 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52614 + return TRUE;
52615 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52616 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52617 + return FALSE;
52618 + else
52619 + return TRUE;
52620 + default:
52621 + return FALSE;
52622 + }
52623 +}
52624 +
52625 +static t_Error BmiPortCheckAndGetCounterType(
52626 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52627 + enum fman_port_stats_counters *p_StatsType,
52628 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52629 +{
52630 + volatile uint32_t *p_Reg;
52631 + bool isValid;
52632 +
52633 + switch (p_FmPort->portType)
52634 + {
52635 + case (e_FM_PORT_TYPE_RX_10G):
52636 + case (e_FM_PORT_TYPE_RX):
52637 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52638 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52639 + break;
52640 + case (e_FM_PORT_TYPE_TX_10G):
52641 + case (e_FM_PORT_TYPE_TX):
52642 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52643 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52644 + break;
52645 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52646 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52647 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52648 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52649 + break;
52650 + default:
52651 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52652 + }
52653 +
52654 + if (!isValid)
52655 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52656 + ("Requested counter is not available for this port type"));
52657 +
52658 + /* check that counters are enabled */
52659 + switch (counter)
52660 + {
52661 + case (e_FM_PORT_COUNTERS_CYCLE):
52662 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52663 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52664 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52665 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52666 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52667 + /* performance counters - may be read when disabled */
52668 + *p_IsStats = FALSE;
52669 + break;
52670 + case (e_FM_PORT_COUNTERS_FRAME):
52671 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52672 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52673 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52674 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52675 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52676 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52677 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52678 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52679 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52680 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52681 + *p_IsStats = TRUE;
52682 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52683 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52684 + ("Requested counter was not enabled"));
52685 + break;
52686 + default:
52687 + break;
52688 + }
52689 +
52690 + /* Set counter */
52691 + switch (counter)
52692 + {
52693 + case (e_FM_PORT_COUNTERS_CYCLE):
52694 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52695 + break;
52696 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52697 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52698 + break;
52699 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52700 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52701 + break;
52702 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52703 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52704 + break;
52705 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52706 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52707 + break;
52708 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52709 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52710 + break;
52711 + case (e_FM_PORT_COUNTERS_FRAME):
52712 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52713 + break;
52714 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52715 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52716 + break;
52717 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52718 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52719 + break;
52720 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52721 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52722 + break;
52723 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52724 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52725 + break;
52726 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52727 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52728 + break;
52729 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52730 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52731 + break;
52732 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52733 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52734 + break;
52735 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52736 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52737 + break;
52738 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52739 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52740 + break;
52741 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52742 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52743 + break;
52744 + default:
52745 + break;
52746 + }
52747 +
52748 + return E_OK;
52749 +}
52750 +
52751 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52752 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52753 + uint32_t *p_SoftSeqAttachReg)
52754 +{
52755 + uint8_t hdrNum, Ipv4HdrNum;
52756 + u_FmPcdHdrPrsOpts *p_prsOpts;
52757 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52758 +
52759 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52760 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52761 + RETURN_ERROR(
52762 + MAJOR, E_NOT_SUPPORTED,
52763 + ("No additional parameters for private or special headers."));
52764 +
52765 + if (p_HdrParams->errDisable)
52766 + tmpReg |= PRS_HDR_ERROR_DIS;
52767 +
52768 + /* Set parser options */
52769 + if (p_HdrParams->usePrsOpts)
52770 + {
52771 + p_prsOpts = &p_HdrParams->prsOpts;
52772 + switch (p_HdrParams->hdr)
52773 + {
52774 + case (HEADER_TYPE_MPLS):
52775 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52776 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52777 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52778 + if (hdrNum == ILLEGAL_HDR_NUM)
52779 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52780 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52781 + if (hdrNum < Ipv4HdrNum)
52782 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52783 + ("Header must be equal or higher than IPv4"));
52784 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52785 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52786 + break;
52787 + case (HEADER_TYPE_PPPoE):
52788 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52789 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52790 + break;
52791 + case (HEADER_TYPE_IPv6):
52792 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52793 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52794 + break;
52795 + case (HEADER_TYPE_TCP):
52796 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52797 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52798 + else
52799 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52800 + break;
52801 + case (HEADER_TYPE_UDP):
52802 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52803 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52804 + else
52805 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52806 + break;
52807 + default:
52808 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52809 + }
52810 + }
52811 +
52812 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52813 + if (p_HdrParams->swPrsEnable)
52814 + {
52815 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52816 + p_HdrParams->indexPerHdr);
52817 + if (tmpPrsOffset == ILLEGAL_BASE)
52818 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52819 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52820 + }
52821 + *p_SoftSeqAttachReg = tmpReg;
52822 +
52823 + return E_OK;
52824 +}
52825 +
52826 +static uint32_t GetPortSchemeBindParams(
52827 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52828 +{
52829 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52830 + uint32_t walking1Mask = 0x80000000, tmp;
52831 + uint8_t idx = 0;
52832 +
52833 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52834 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52835 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52836 + p_SchemeBind->numOfSchemes = 0;
52837 + tmp = p_FmPort->schemesPerPortVector;
52838 + if (tmp)
52839 + {
52840 + while (tmp)
52841 + {
52842 + if (tmp & walking1Mask)
52843 + {
52844 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52845 + p_SchemeBind->numOfSchemes++;
52846 + tmp &= ~walking1Mask;
52847 + }
52848 + walking1Mask >>= 1;
52849 + idx++;
52850 + }
52851 + }
52852 +
52853 + return tmp;
52854 +}
52855 +
52856 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52857 +{
52858 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52859 + volatile uint32_t *p_BmiCfgReg = NULL;
52860 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52861 + uint32_t lcv, walking1Mask = 0x80000000;
52862 + uint8_t cnt = 0;
52863 +
52864 + ASSERT_COND(p_FmPort);
52865 + ASSERT_COND(p_FmPort->h_FmPcd);
52866 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52867 +
52868 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52869 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52870 + return;
52871 +
52872 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52873 + /* get LCV for MACSEC */
52874 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
52875 + != 0)
52876 + {
52877 + while (!(lcv & walking1Mask))
52878 + {
52879 + cnt++;
52880 + walking1Mask >>= 1;
52881 + }
52882 +
52883 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
52884 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
52885 + }
52886 +}
52887 +
52888 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
52889 +{
52890 + t_Error err = E_OK;
52891 + uint32_t tmpReg;
52892 + volatile uint32_t *p_BmiNia = NULL;
52893 + volatile uint32_t *p_BmiPrsNia = NULL;
52894 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
52895 + volatile uint32_t *p_BmiInitPrsResult = NULL;
52896 + volatile uint32_t *p_BmiCcBase = NULL;
52897 + uint16_t hdrNum, L3HdrNum, greHdrNum;
52898 + int i;
52899 + bool isEmptyClsPlanGrp;
52900 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
52901 + uint16_t absoluteProfileId;
52902 + uint8_t physicalSchemeId;
52903 + uint32_t ccTreePhysOffset;
52904 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
52905 + uint32_t initialSwPrs = 0;
52906 +
52907 + ASSERT_COND(p_FmPort);
52908 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
52909 +
52910 + if (p_FmPort->imEn)
52911 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52912 + ("available for non-independant mode ports only"));
52913 +
52914 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52915 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
52916 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52917 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52918 + ("available for Rx and offline parsing ports only"));
52919 +
52920 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
52921 +
52922 + p_FmPort->pcdEngines = 0;
52923 +
52924 + /* initialize p_FmPort->pcdEngines field in port's structure */
52925 + switch (p_PcdParams->pcdSupport)
52926 + {
52927 + case (e_FM_PORT_PCD_SUPPORT_NONE):
52928 + RETURN_ERROR(
52929 + MAJOR,
52930 + E_INVALID_STATE,
52931 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
52932 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
52933 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52934 + break;
52935 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
52936 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52937 + break;
52938 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
52939 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52940 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52941 + break;
52942 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
52943 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52944 + p_FmPort->pcdEngines |= FM_PCD_KG;
52945 + break;
52946 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
52947 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52948 + p_FmPort->pcdEngines |= FM_PCD_CC;
52949 + p_FmPort->pcdEngines |= FM_PCD_KG;
52950 + break;
52951 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
52952 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52953 + p_FmPort->pcdEngines |= FM_PCD_KG;
52954 + p_FmPort->pcdEngines |= FM_PCD_CC;
52955 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52956 + break;
52957 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
52958 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52959 + p_FmPort->pcdEngines |= FM_PCD_CC;
52960 + break;
52961 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
52962 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52963 + p_FmPort->pcdEngines |= FM_PCD_CC;
52964 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52965 + break;
52966 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
52967 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52968 + p_FmPort->pcdEngines |= FM_PCD_KG;
52969 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52970 + break;
52971 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
52972 + p_FmPort->pcdEngines |= FM_PCD_CC;
52973 + break;
52974 +#ifdef FM_CAPWAP_SUPPORT
52975 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
52976 + p_FmPort->pcdEngines |= FM_PCD_CC;
52977 + p_FmPort->pcdEngines |= FM_PCD_KG;
52978 + break;
52979 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
52980 + p_FmPort->pcdEngines |= FM_PCD_CC;
52981 + p_FmPort->pcdEngines |= FM_PCD_KG;
52982 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52983 + break;
52984 +#endif /* FM_CAPWAP_SUPPORT */
52985 +
52986 + default:
52987 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
52988 + }
52989 +
52990 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
52991 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
52992 + > FM_PCD_PRS_NUM_OF_HDRS))
52993 + RETURN_ERROR(
52994 + MAJOR,
52995 + E_INVALID_VALUE,
52996 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
52997 +
52998 + /* check that parameters exist for each and only each defined engine */
52999 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
53000 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
53001 + != !!p_PcdParams->p_KgParams)
53002 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
53003 + != !!p_PcdParams->p_CcParams))
53004 + RETURN_ERROR(
53005 + MAJOR,
53006 + E_INVALID_STATE,
53007 + ("PCD initialization structure is not consistent with pcdSupport"));
53008 +
53009 + /* get PCD registers pointers */
53010 + switch (p_FmPort->portType)
53011 + {
53012 + case (e_FM_PORT_TYPE_RX_10G):
53013 + case (e_FM_PORT_TYPE_RX):
53014 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53015 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
53016 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53017 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
53018 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
53019 + break;
53020 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53021 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53022 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
53023 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53024 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
53025 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
53026 + break;
53027 + default:
53028 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53029 + }
53030 +
53031 + /* set PCD port parameter */
53032 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53033 + {
53034 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
53035 + p_PcdParams->p_CcParams->h_CcTree,
53036 + &ccTreePhysOffset, p_FmPort);
53037 + if (err)
53038 + RETURN_ERROR(MAJOR, err, NO_MSG);
53039 +
53040 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
53041 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
53042 + }
53043 +
53044 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53045 + {
53046 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
53047 + RETURN_ERROR(
53048 + MAJOR,
53049 + E_INVALID_VALUE,
53050 + ("For ports using Keygen, at least one scheme must be bound. "));
53051 +
53052 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
53053 + p_FmPort->hardwarePortId,
53054 + p_FmPort->netEnvId,
53055 + p_FmPort->optArray,
53056 + &p_FmPort->clsPlanGrpId,
53057 + &isEmptyClsPlanGrp);
53058 + if (err)
53059 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53060 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
53061 +
53062 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
53063 +
53064 + schemeBind.netEnvId = p_FmPort->netEnvId;
53065 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
53066 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
53067 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
53068 +
53069 + /* for each scheme */
53070 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53071 + {
53072 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
53073 + physicalSchemeId = FmPcdKgGetSchemeId(
53074 + p_PcdParams->p_KgParams->h_Schemes[i]);
53075 + schemeBind.schemesIds[i] = physicalSchemeId;
53076 + /* build vector */
53077 + p_FmPort->schemesPerPortVector |= 1
53078 + << (31 - (uint32_t)physicalSchemeId);
53079 +#if (DPAA_VERSION >= 11)
53080 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
53081 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
53082 + if (!p_FmPort->vspe
53083 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
53084 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53085 + ("VSPE is not at port level"));
53086 +#endif /* (DPAA_VERSION >= 11) */
53087 + }
53088 +
53089 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53090 + if (err)
53091 + RETURN_ERROR(MAJOR, err, NO_MSG);
53092 + }
53093 +
53094 + /***************************/
53095 + /* configure NIA after BMI */
53096 + /***************************/
53097 + /* rfne may contain FDCS bits, so first we read them. */
53098 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
53099 +
53100 + /* If policer is used directly after BMI or PRS */
53101 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
53102 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
53103 + || (p_PcdParams->pcdSupport
53104 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
53105 + {
53106 + if (!p_PcdParams->p_PlcrParams->h_Profile)
53107 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53108 + ("Profile should be initialized"));
53109 +
53110 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
53111 + p_PcdParams->p_PlcrParams->h_Profile);
53112 +
53113 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
53114 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53115 + ("Private port profile not valid."));
53116 +
53117 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
53118 +
53119 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
53120 + /* update BMI HPNIA */
53121 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
53122 + else
53123 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
53124 + /* update BMI NIA */
53125 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
53126 + }
53127 +
53128 + /* if CC is used directly after BMI */
53129 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
53130 +#ifdef FM_CAPWAP_SUPPORT
53131 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
53132 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
53133 +#endif /* FM_CAPWAP_SUPPORT */
53134 + )
53135 + {
53136 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53137 + RETURN_ERROR(
53138 + MAJOR,
53139 + E_INVALID_OPERATION,
53140 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
53141 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
53142 + /* check that prs start offset == RIM[FOF] */
53143 + }
53144 +
53145 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53146 + {
53147 + ASSERT_COND(p_PcdParams->p_PrsParams);
53148 +#if (DPAA_VERSION >= 11)
53149 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
53150 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
53151 + else
53152 + {
53153 +#endif /* (DPAA_VERSION >= 11) */
53154 + /* if PRS is used it is always first */
53155 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
53156 + if (hdrNum == ILLEGAL_HDR_NUM)
53157 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
53158 +#if (DPAA_VERSION >= 11)
53159 + }
53160 +#endif /* (DPAA_VERSION >= 11) */
53161 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
53162 + /* set after parser NIA */
53163 + tmpReg = 0;
53164 + switch (p_PcdParams->pcdSupport)
53165 + {
53166 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53167 + WRITE_UINT32(*p_BmiPrsNia,
53168 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
53169 + break;
53170 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53171 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53172 + tmpReg = NIA_KG_CC_EN;
53173 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53174 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53175 + if (p_PcdParams->p_KgParams->directScheme)
53176 + {
53177 + physicalSchemeId = FmPcdKgGetSchemeId(
53178 + p_PcdParams->p_KgParams->h_DirectScheme);
53179 + /* check that this scheme was bound to this port */
53180 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53181 + if (p_PcdParams->p_KgParams->h_DirectScheme
53182 + == p_PcdParams->p_KgParams->h_Schemes[i])
53183 + break;
53184 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
53185 + RETURN_ERROR(
53186 + MAJOR,
53187 + E_INVALID_VALUE,
53188 + ("Direct scheme is not one of the port selected schemes."));
53189 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
53190 + }
53191 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
53192 + break;
53193 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53194 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53195 + WRITE_UINT32(*p_BmiPrsNia,
53196 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
53197 + break;
53198 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53199 + break;
53200 + default:
53201 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
53202 + }
53203 +
53204 + /* set start parsing offset */
53205 + WRITE_UINT32(*p_BmiPrsStartOffset,
53206 + p_PcdParams->p_PrsParams->parsingOffset);
53207 +
53208 + /************************************/
53209 + /* Parser port parameters */
53210 + /************************************/
53211 + /* stop before configuring */
53212 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53213 + /* wait for parser to be in idle state */
53214 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53215 + ;
53216 +
53217 + /* set soft seq attachment register */
53218 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
53219 +
53220 + /* set protocol options */
53221 + for (i = 0; p_FmPort->optArray[i]; i++)
53222 + switch (p_FmPort->optArray[i])
53223 + {
53224 + case (ETH_BROADCAST):
53225 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53226 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
53227 + break;
53228 + case (ETH_MULTICAST):
53229 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53230 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
53231 + break;
53232 + case (VLAN_STACKED):
53233 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
53234 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
53235 + break;
53236 + case (MPLS_STACKED):
53237 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53238 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
53239 + break;
53240 + case (IPV4_BROADCAST_1):
53241 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53242 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53243 + break;
53244 + case (IPV4_MULTICAST_1):
53245 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53246 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53247 + break;
53248 + case (IPV4_UNICAST_2):
53249 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53250 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53251 + break;
53252 + case (IPV4_MULTICAST_BROADCAST_2):
53253 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53254 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53255 + break;
53256 + case (IPV6_MULTICAST_1):
53257 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53258 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53259 + break;
53260 + case (IPV6_UNICAST_2):
53261 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53262 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53263 + break;
53264 + case (IPV6_MULTICAST_2):
53265 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53266 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53267 + break;
53268 + }
53269 +
53270 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53271 + HEADER_TYPE_UDP_ENCAP_ESP))
53272 + {
53273 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53274 + RETURN_ERROR(
53275 + MINOR, E_INVALID_VALUE,
53276 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53277 +
53278 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53279 + HEADER_TYPE_UDP;
53280 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53281 + TRUE;
53282 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53283 + }
53284 +
53285 + /* set MPLS default next header - HW reset workaround */
53286 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53287 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53288 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53289 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53290 +
53291 + /* for GRE, disable errors */
53292 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53293 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53294 +
53295 + /* For UDP remove PAD from L4 checksum calculation */
53296 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53297 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53298 + /* For TCP remove PAD from L4 checksum calculation */
53299 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53300 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53301 +
53302 + /* config additional params for specific headers */
53303 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53304 + i++)
53305 + {
53306 + /* case for using sw parser as the initial NIA address, before
53307 + * HW parsing
53308 + */
53309 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53310 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53311 + {
53312 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53313 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53314 + if (initialSwPrs == ILLEGAL_BASE)
53315 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53316 +
53317 + /* clear parser first HXS */
53318 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53319 + /* rewrite with soft parser start */
53320 + p_FmPort->savedBmiNia |= initialSwPrs;
53321 + continue;
53322 + }
53323 +
53324 + hdrNum =
53325 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53326 + if (hdrNum == ILLEGAL_HDR_NUM)
53327 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53328 + if (hdrNum == NO_HDR_NUM)
53329 + RETURN_ERROR(
53330 + MAJOR, E_INVALID_VALUE,
53331 + ("Private headers may not use additional parameters"));
53332 +
53333 + err = AdditionalPrsParams(
53334 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53335 + &tmpHxs[hdrNum]);
53336 + if (err)
53337 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53338 + }
53339 +
53340 + /* Check if ip-reassembly port - need to link sw-parser code */
53341 + if (p_FmPort->h_IpReassemblyManip)
53342 + {
53343 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53344 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53345 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53346 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
53347 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53348 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53349 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
53350 + } else {
53351 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53352 + {
53353 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53354 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53355 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53356 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53357 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53358 + {
53359 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53360 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53361 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53362 + }
53363 + }
53364 +
53365 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53366 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53367 + HEADER_TYPE_UDP_LITE))
53368 + {
53369 + /* link to sw parser code for udp lite - only if no other code is applied. */
53370 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53371 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53372 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53373 + }
53374 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53375 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53376 + {
53377 + /* For all header set LCV as taken from netEnv*/
53378 + WRITE_UINT32(
53379 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53380 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53381 + /* set HXS register according to default+Additional params+protocol options */
53382 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53383 + tmpHxs[i]);
53384 + }
53385 +
53386 + /* set tpid. */
53387 + tmpReg = PRS_TPID_DFLT;
53388 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53389 + {
53390 + tmpReg &= PRS_TPID2_MASK;
53391 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53392 + << PRS_PCTPID_SHIFT;
53393 + }
53394 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53395 + {
53396 + tmpReg &= PRS_TPID1_MASK;
53397 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53398 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53399 +
53400 + /* enable parser */
53401 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53402 +
53403 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53404 + p_FmPort->privateInfo =
53405 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53406 +
53407 + } /* end parser */
53408 + else {
53409 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53410 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53411 + {
53412 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53413 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53414 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53415 + }
53416 +
53417 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53418 +
53419 + p_FmPort->privateInfo = 0;
53420 + }
53421 +
53422 + FmPortCheckNApplyMacsec(p_FmPort);
53423 +
53424 + WRITE_UINT32(
53425 + *p_BmiPrsStartOffset,
53426 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53427 +
53428 + /* set initial parser result - used for all engines */
53429 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53430 + {
53431 + if (!i)
53432 + WRITE_UINT32(
53433 + *(p_BmiInitPrsResult),
53434 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53435 + else
53436 + {
53437 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53438 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53439 + else
53440 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53441 + }
53442 + }
53443 +
53444 + return E_OK;
53445 +}
53446 +
53447 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53448 +{
53449 + t_Error err = E_OK;
53450 + volatile uint32_t *p_BmiNia = NULL;
53451 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53452 +
53453 + ASSERT_COND(p_FmPort);
53454 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53455 +
53456 + if (p_FmPort->imEn)
53457 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53458 + ("available for non-independant mode ports only"));
53459 +
53460 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53461 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53462 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53463 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53464 + ("available for Rx and offline parsing ports only"));
53465 +
53466 + if (!p_FmPort->pcdEngines)
53467 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53468 +
53469 + /* get PCD registers pointers */
53470 + switch (p_FmPort->portType)
53471 + {
53472 + case (e_FM_PORT_TYPE_RX_10G):
53473 + case (e_FM_PORT_TYPE_RX):
53474 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53475 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53476 + break;
53477 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53478 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53479 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53480 + break;
53481 + default:
53482 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53483 + }
53484 +
53485 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53486 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53487 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53488 + ("port has to be detached previousely"));
53489 +
53490 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53491 +
53492 + /* "cut" PCD out of the port's flow - go to BMI */
53493 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53494 +
53495 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53496 + {
53497 + /* stop parser */
53498 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53499 + /* wait for parser to be in idle state */
53500 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53501 + ;
53502 + }
53503 +
53504 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53505 + {
53506 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53507 +
53508 + /* unbind all schemes */
53509 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53510 + &schemeBind);
53511 +
53512 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53513 + if (err)
53514 + RETURN_ERROR(MAJOR, err, NO_MSG);
53515 +
53516 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53517 + p_FmPort->hardwarePortId,
53518 + p_FmPort->clsPlanGrpId);
53519 + if (err)
53520 + RETURN_ERROR(MAJOR, err, NO_MSG);
53521 + p_FmPort->useClsPlan = FALSE;
53522 + }
53523 +
53524 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53525 + {
53526 + /* unbind - we need to get the treeId too */
53527 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53528 + if (err)
53529 + RETURN_ERROR(MAJOR, err, NO_MSG);
53530 + }
53531 +
53532 + p_FmPort->pcdEngines = 0;
53533 +
53534 + return E_OK;
53535 +}
53536 +
53537 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53538 +{
53539 + volatile uint32_t *p_BmiNia = NULL;
53540 +
53541 + ASSERT_COND(p_FmPort);
53542 +
53543 + /* get PCD registers pointers */
53544 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53545 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53546 + else
53547 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53548 +
53549 + /* check that current NIA is BMI to BMI */
53550 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53551 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53552 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53553 + ("may be called only for ports in BMI-to-BMI state."));
53554 +
53555 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53556 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53557 + p_FmPort->orFmanCtrl) != E_OK)
53558 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53559 +
53560 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53561 + {
53562 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53563 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53564 + p_FmPort->savedBmiCmne);
53565 + else
53566 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53567 + p_FmPort->savedBmiCmne);
53568 + }
53569 +
53570 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53571 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53572 + p_FmPort->savedQmiPnen);
53573 +
53574 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53575 + {
53576 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53577 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53578 + p_FmPort->savedBmiFene);
53579 + else
53580 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53581 + p_FmPort->savedBmiFene);
53582 + }
53583 +
53584 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53585 + {
53586 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53587 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53588 + p_FmPort->savedBmiFpne);
53589 + else
53590 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53591 + p_FmPort->savedBmiFpne);
53592 + }
53593 +
53594 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53595 + {
53596 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53597 +
53598 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53599 + p_FmPort->savedBmiOfp);
53600 + }
53601 +
53602 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53603 +
53604 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53605 + {
53606 + p_FmPort->origNonRxQmiRegsPndn =
53607 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53608 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53609 + p_FmPort->savedNonRxQmiRegsPndn);
53610 + }
53611 +
53612 + return E_OK;
53613 +}
53614 +
53615 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53616 +{
53617 + volatile uint32_t *p_BmiNia = NULL;
53618 +
53619 + ASSERT_COND(p_FmPort);
53620 +
53621 + /* get PCD registers pointers */
53622 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53623 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53624 + p_FmPort->origNonRxQmiRegsPndn);
53625 +
53626 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53627 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53628 + else
53629 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53630 +
53631 + WRITE_UINT32(
53632 + *p_BmiNia,
53633 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53634 +
53635 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53636 + FmPcdHcSync(p_FmPort->h_FmPcd);
53637 +
53638 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53639 + {
53640 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53641 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53642 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53643 + else
53644 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53645 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53646 + }
53647 +
53648 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53649 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53650 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53651 +
53652 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53653 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53654 + p_FmPort->orFmanCtrl) != E_OK)
53655 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53656 +
53657 + p_FmPort->requiredAction = 0;
53658 +
53659 + return E_OK;
53660 +}
53661 +
53662 +/*****************************************************************************/
53663 +/* Inter-module API routines */
53664 +/*****************************************************************************/
53665 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53666 +{
53667 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53668 + volatile uint32_t *p_BmiCfgReg = NULL;
53669 + uint32_t tmpReg;
53670 +
53671 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53672 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53673 +
53674 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53675 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53676 + {
53677 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53678 + return;
53679 + }
53680 +
53681 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53682 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53683 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53684 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53685 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53686 +
53687 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53688 +}
53689 +
53690 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53691 +{
53692 + return ((t_FmPort*)h_FmPort)->netEnvId;
53693 +}
53694 +
53695 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53696 +{
53697 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53698 +}
53699 +
53700 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53701 +{
53702 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53703 +}
53704 +
53705 +#if (DPAA_VERSION >= 11)
53706 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53707 + void **p_Value)
53708 +{
53709 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53710 + uint32_t muramPageOffset;
53711 +
53712 + ASSERT_COND(p_FmPort);
53713 + ASSERT_COND(p_Value);
53714 +
53715 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53716 + {
53717 + if (p_FmPort->gprFunc != gprFunc)
53718 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53719 + ("gpr was assigned with different func"));
53720 + }
53721 + else
53722 + {
53723 + switch (gprFunc)
53724 + {
53725 + case (e_FM_PORT_GPR_MURAM_PAGE):
53726 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53727 + 256, 8);
53728 + if (!p_FmPort->p_ParamsPage)
53729 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53730 +
53731 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53732 + muramPageOffset =
53733 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53734 + - p_FmPort->fmMuramPhysBaseAddr);
53735 + switch (p_FmPort->portType)
53736 + {
53737 + case (e_FM_PORT_TYPE_RX_10G):
53738 + case (e_FM_PORT_TYPE_RX):
53739 + WRITE_UINT32(
53740 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53741 + muramPageOffset);
53742 + break;
53743 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53744 + WRITE_UINT32(
53745 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53746 + muramPageOffset);
53747 + break;
53748 + default:
53749 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53750 + ("Invalid port type"));
53751 + }
53752 + break;
53753 + default:
53754 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53755 + }
53756 + p_FmPort->gprFunc = gprFunc;
53757 + }
53758 +
53759 + switch (p_FmPort->gprFunc)
53760 + {
53761 + case (e_FM_PORT_GPR_MURAM_PAGE):
53762 + *p_Value = p_FmPort->p_ParamsPage;
53763 + break;
53764 + default:
53765 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53766 + }
53767 +
53768 + return E_OK;
53769 +}
53770 +#endif /* (DPAA_VERSION >= 11) */
53771 +
53772 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53773 + t_FmPortGetSetCcParams *p_CcParams)
53774 +{
53775 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53776 + int tmpInt;
53777 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53778 +
53779 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53780 +
53781 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53782 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53783 + {
53784 + p_CcParams->getCcParams.prOffset =
53785 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53786 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53787 + }
53788 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53789 + {
53790 + p_CcParams->getCcParams.hardwarePortId =
53791 + (uint8_t)p_FmPort->hardwarePortId;
53792 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53793 + }
53794 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53795 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53796 + {
53797 + p_CcParams->getCcParams.dataOffset =
53798 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53799 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53800 + }
53801 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53802 + {
53803 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53804 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53805 + }
53806 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53807 + {
53808 + p_CcParams->getCcParams.numOfExtraTasks =
53809 + (uint8_t)p_FmPort->tasks.extra;
53810 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53811 + }
53812 + if (p_CcParams->getCcParams.type & FM_REV)
53813 + {
53814 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53815 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53816 + p_CcParams->getCcParams.type &= ~FM_REV;
53817 + }
53818 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53819 + {
53820 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53821 + p_CcParams->getCcParams.discardMask =
53822 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53823 + else
53824 + p_CcParams->getCcParams.discardMask =
53825 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53826 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53827 + }
53828 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53829 + {
53830 + p_CcParams->getCcParams.internalBufferOffset =
53831 + p_FmPort->internalBufferOffset;
53832 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53833 + }
53834 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53835 + {
53836 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53837 + p_CcParams->getCcParams.nia =
53838 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53839 + else
53840 + p_CcParams->getCcParams.nia =
53841 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53842 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53843 + }
53844 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53845 + {
53846 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53847 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53848 + p_CcParams->getCcParams.nia =
53849 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53850 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53851 + }
53852 +
53853 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53854 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53855 + {
53856 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53857 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53858 + }
53859 +
53860 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53861 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53862 + {
53863 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53864 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53865 + }
53866 + else
53867 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53868 + {
53869 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53870 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53871 + ("PNEN was defined previously different"));
53872 + }
53873 +
53874 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53875 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
53876 + {
53877 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
53878 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
53879 + }
53880 + else
53881 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53882 + {
53883 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
53884 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53885 + ("PNDN was defined previously different"));
53886 + }
53887 +
53888 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53889 + && (p_CcParams->setCcParams.overwrite
53890 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
53891 + {
53892 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
53893 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
53894 + }
53895 + else
53896 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53897 + {
53898 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
53899 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53900 + ("xFENE was defined previously different"));
53901 + }
53902 +
53903 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53904 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
53905 + {
53906 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
53907 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
53908 + }
53909 + else
53910 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53911 + {
53912 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
53913 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53914 + ("xFPNE was defined previously different"));
53915 + }
53916 +
53917 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53918 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
53919 + {
53920 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
53921 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
53922 + }
53923 + else
53924 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53925 + {
53926 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
53927 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53928 + ("xCMNE was defined previously different"));
53929 + }
53930 +
53931 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
53932 + && !(p_FmPort->requiredAction & UPDATE_PSO))
53933 + {
53934 + /* get PCD registers pointers */
53935 + switch (p_FmPort->portType)
53936 + {
53937 + case (e_FM_PORT_TYPE_RX_10G):
53938 + case (e_FM_PORT_TYPE_RX):
53939 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53940 + break;
53941 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53942 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53943 + break;
53944 + default:
53945 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53946 + }
53947 +
53948 + /* set start parsing offset */
53949 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
53950 + + p_CcParams->setCcParams.psoSize;
53951 + if (tmpInt > 0)
53952 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
53953 +
53954 + p_FmPort->requiredAction |= UPDATE_PSO;
53955 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
53956 + }
53957 + else
53958 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
53959 + {
53960 + if (p_FmPort->savedPrsStartOffset
53961 + != p_CcParams->setCcParams.psoSize)
53962 + RETURN_ERROR(
53963 + MAJOR,
53964 + E_INVALID_STATE,
53965 + ("parser start offset was defoned previousley different"));
53966 + }
53967 +
53968 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
53969 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
53970 + {
53971 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53972 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53973 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
53974 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
53975 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
53976 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
53977 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
53978 + }
53979 +
53980 + return E_OK;
53981 +}
53982 +/*********************** End of inter-module routines ************************/
53983 +
53984 +/****************************************/
53985 +/* API Init unit functions */
53986 +/****************************************/
53987 +
53988 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
53989 +{
53990 + t_FmPort *p_FmPort;
53991 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
53992 + uint32_t tmpReg;
53993 +
53994 + /* Allocate FM structure */
53995 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
53996 + if (!p_FmPort)
53997 + {
53998 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
53999 + return NULL;
54000 + }
54001 + memset(p_FmPort, 0, sizeof(t_FmPort));
54002 +
54003 + /* Allocate the FM driver's parameters structure */
54004 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
54005 + sizeof(t_FmPortDriverParam));
54006 + if (!p_FmPort->p_FmPortDriverParam)
54007 + {
54008 + XX_Free(p_FmPort);
54009 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
54010 + return NULL;
54011 + }
54012 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
54013 +
54014 + /* Initialize FM port parameters which will be kept by the driver */
54015 + p_FmPort->portType = p_FmPortParams->portType;
54016 + p_FmPort->portId = p_FmPortParams->portId;
54017 + p_FmPort->pcdEngines = FM_PCD_NONE;
54018 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
54019 + p_FmPort->h_App = p_FmPortParams->h_App;
54020 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
54021 +
54022 + /* get FM revision */
54023 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
54024 +
54025 + /* calculate global portId number */
54026 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
54027 + p_FmPortParams->portId,
54028 + p_FmPort->fmRevInfo.majorRev,
54029 + p_FmPort->fmRevInfo.minorRev);
54030 +
54031 + if (p_FmPort->fmRevInfo.majorRev >= 6)
54032 + {
54033 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54034 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54035 + DBG(WARNING,
54036 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
54037 + FM_OH_PORT_ID));
54038 +
54039 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54040 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
54041 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
54042 + }
54043 +
54044 + /* Set up FM port parameters for initialization phase only */
54045 +
54046 + /* First, fill in flibs struct */
54047 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
54048 + (enum fman_port_type)p_FmPort->portType);
54049 + /* Overwrite some integration specific parameters */
54050 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
54051 + DEFAULT_PORT_rxFifoPriElevationLevel;
54052 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
54053 + DEFAULT_PORT_rxFifoThreshold;
54054 +
54055 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
54056 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
54057 +#else
54058 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
54059 +#endif
54060 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54061 + && (p_FmPort->fmRevInfo.minorRev == 0))
54062 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
54063 + else
54064 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
54065 +
54066 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
54067 + if (p_FmPort->fmRevInfo.majorRev < 6)
54068 + {
54069 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
54070 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54071 + TRUE;
54072 +#endif
54073 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
54074 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
54075 + }
54076 + else
54077 + {
54078 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54079 + FALSE;
54080 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
54081 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
54082 + }
54083 + if (p_FmPort->fmRevInfo.majorRev == 4)
54084 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
54085 + else
54086 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
54087 +
54088 + /* Continue with other parameters */
54089 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
54090 + /* set memory map pointers */
54091 + p_FmPort->p_FmPortQmiRegs =
54092 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
54093 + p_FmPort->p_FmPortBmiRegs =
54094 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
54095 + p_FmPort->p_FmPortPrsRegs =
54096 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
54097 +
54098 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
54099 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
54100 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
54101 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
54102 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
54103 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54104 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
54105 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54106 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54107 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54108 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
54109 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
54110 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
54111 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
54112 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
54113 + */
54114 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
54115 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
54116 + DEFAULT_PORT_cheksumLastBytesIgnore;
54117 +
54118 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
54119 + /* resource distribution. */
54120 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
54121 + * BMI_FIFO_UNITS;
54122 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
54123 + * BMI_FIFO_UNITS;
54124 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
54125 + p_FmPort->openDmas.extra =
54126 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
54127 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
54128 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
54129 +
54130 +
54131 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
54132 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54133 + && (p_FmPort->fmRevInfo.minorRev == 0)
54134 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54135 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
54136 + {
54137 + p_FmPort->openDmas.num = 16;
54138 + p_FmPort->openDmas.extra = 0;
54139 + }
54140 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
54141 +
54142 + /* Port type specific initialization: */
54143 + switch (p_FmPort->portType)
54144 + {
54145 + case (e_FM_PORT_TYPE_RX):
54146 + case (e_FM_PORT_TYPE_RX_10G):
54147 + /* Initialize FM port parameters for initialization phase only */
54148 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
54149 + DEFAULT_PORT_cutBytesFromEnd;
54150 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
54151 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
54152 + DEFAULT_PORT_frmDiscardOverride;
54153 +
54154 + tmpReg =
54155 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
54156 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
54157 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
54158 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
54159 + * BMI_FIFO_UNITS;
54160 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
54161 + & BMI_RX_FIFO_THRESHOLD_MASK)
54162 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
54163 +
54164 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
54165 + DEFAULT_PORT_BufMargins_endMargins;
54166 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54167 + DEFAULT_PORT_errorsToDiscard;
54168 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
54169 + DEFAULT_PORT_forwardIntContextReuse;
54170 +#if (DPAA_VERSION >= 11)
54171 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54172 + DEFAULT_PORT_noScatherGather;
54173 +#endif /* (DPAA_VERSION >= 11) */
54174 + break;
54175 +
54176 + case (e_FM_PORT_TYPE_TX):
54177 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
54178 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
54179 + tmpReg = 0x00001013;
54180 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
54181 + tmpReg);
54182 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
54183 + case (e_FM_PORT_TYPE_TX_10G):
54184 + tmpReg =
54185 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
54186 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
54187 + & BMI_TX_FIFO_MIN_FILL_MASK)
54188 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
54189 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54190 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54191 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54192 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
54193 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
54194 + * BMI_FIFO_UNITS;
54195 +
54196 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54197 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54198 + DEFAULT_PORT_deqPrefetchOption;
54199 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54200 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
54201 + DEFAULT_PORT_deqHighPriority_10G);
54202 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54203 + (uint16_t)(
54204 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
54205 + DEFAULT_PORT_deqByteCnt_10G);
54206 + break;
54207 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54208 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54209 + DEFAULT_PORT_errorsToDiscard;
54210 +#if (DPAA_VERSION >= 11)
54211 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54212 + DEFAULT_PORT_noScatherGather;
54213 +#endif /* (DPAA_VERSION >= 11) */
54214 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54215 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54216 + DEFAULT_PORT_deqPrefetchOption_HC;
54217 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54218 + DEFAULT_PORT_deqHighPriority_1G;
54219 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54220 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54221 + DEFAULT_PORT_deqByteCnt_1G;
54222 +
54223 + tmpReg =
54224 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
54225 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54226 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54227 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54228 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54229 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54230 + {
54231 + /* Overwrite HC defaults */
54232 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54233 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
54234 + }
54235 +
54236 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
54237 + if (p_FmPort->fmRevInfo.majorRev < 6)
54238 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
54239 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
54240 +
54241 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54242 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54243 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54244 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54245 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54246 + break;
54247 +
54248 + default:
54249 + XX_Free(p_FmPort->p_FmPortDriverParam);
54250 + XX_Free(p_FmPort);
54251 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54252 + return NULL;
54253 + }
54254 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54255 + if (p_FmPort->fmRevInfo.majorRev == 4)
54256 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54257 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54258 +
54259 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54260 +
54261 + if (p_FmPort->imEn)
54262 + {
54263 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54264 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54265 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54266 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54267 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54268 + }
54269 + else
54270 + {
54271 + switch (p_FmPort->portType)
54272 + {
54273 + case (e_FM_PORT_TYPE_RX):
54274 + case (e_FM_PORT_TYPE_RX_10G):
54275 + /* Initialize FM port parameters for initialization phase only */
54276 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54277 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54278 + sizeof(t_FmExtPools));
54279 + p_FmPort->p_FmPortDriverParam->errFqid =
54280 + p_FmPortParams->specificParams.rxParams.errFqid;
54281 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54282 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54283 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54284 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54285 + break;
54286 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54287 + case (e_FM_PORT_TYPE_TX):
54288 + case (e_FM_PORT_TYPE_TX_10G):
54289 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54290 + p_FmPort->p_FmPortDriverParam->errFqid =
54291 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54292 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54293 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54294 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54295 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54296 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54297 + break;
54298 + default:
54299 + XX_Free(p_FmPort->p_FmPortDriverParam);
54300 + XX_Free(p_FmPort);
54301 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54302 + return NULL;
54303 + }
54304 + }
54305 +
54306 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54307 + if (Sprint(
54308 + p_FmPort->name,
54309 + "FM-%d-port-%s-%d",
54310 + FmGetId(p_FmPort->h_Fm),
54311 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54312 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54313 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54314 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54315 + (p_FmPort->portType
54316 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54317 + "10g-TX")))),
54318 + p_FmPort->portId) == 0)
54319 + {
54320 + XX_Free(p_FmPort->p_FmPortDriverParam);
54321 + XX_Free(p_FmPort);
54322 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54323 + return NULL;
54324 + }
54325 +
54326 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54327 + if (!p_FmPort->h_Spinlock)
54328 + {
54329 + XX_Free(p_FmPort->p_FmPortDriverParam);
54330 + XX_Free(p_FmPort);
54331 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54332 + return NULL;
54333 + }
54334 +
54335 + return p_FmPort;
54336 +}
54337 +
54338 +t_FmPort *rx_port = 0;
54339 +t_FmPort *tx_port = 0;
54340 +
54341 +/**************************************************************************//**
54342 + @Function FM_PORT_Init
54343 +
54344 + @Description Initializes the FM module
54345 +
54346 + @Param[in] h_FmPort - FM module descriptor
54347 +
54348 + @Return E_OK on success; Error code otherwise.
54349 + *//***************************************************************************/
54350 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54351 +{
54352 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54353 + t_FmPortDriverParam *p_DriverParams;
54354 + t_Error errCode;
54355 + t_FmInterModulePortInitParams fmParams;
54356 + t_FmRevisionInfo revInfo;
54357 +
54358 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54359 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54360 +
54361 + errCode = FmSpBuildBufferStructure(
54362 + &p_FmPort->p_FmPortDriverParam->intContext,
54363 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54364 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54365 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54366 + if (errCode != E_OK)
54367 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54368 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54369 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54370 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54371 + {
54372 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54373 + if (!p_FmPort->fifoBufs.num)
54374 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54375 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54376 + }
54377 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54378 +
54379 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54380 +
54381 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54382 +
54383 + /* Set up flibs port structure */
54384 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54385 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54386 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54387 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54388 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54389 + p_FmPort->port.bmi_regs =
54390 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54391 + p_FmPort->port.qmi_regs =
54392 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54393 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54394 + p_FmPort->port.im_en = p_FmPort->imEn;
54395 + p_FmPort->p_FmPortPrsRegs =
54396 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54397 +
54398 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54399 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54400 + {
54401 + /* Call the external Buffer routine which also checks fifo
54402 + size and updates it if necessary */
54403 + /* define external buffer pools and pool depletion*/
54404 + errCode = SetExtBufferPools(p_FmPort);
54405 + if (errCode)
54406 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54407 + /* check if the largest external buffer pool is large enough */
54408 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54409 + + p_DriverParams->bufMargins.endMargins
54410 + > p_FmPort->rxPoolsParams.largestBufSize)
54411 + RETURN_ERROR(
54412 + MAJOR,
54413 + E_INVALID_VALUE,
54414 + ("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));
54415 + }
54416 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54417 + {
54418 + {
54419 +#ifdef FM_NO_OP_OBSERVED_POOLS
54420 + t_FmRevisionInfo revInfo;
54421 +
54422 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54423 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54424 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54425 + {
54426 + /* define external buffer pools */
54427 + errCode = SetExtBufferPools(p_FmPort);
54428 + if (errCode)
54429 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54430 + }
54431 + }
54432 + }
54433 +
54434 + /************************************************************/
54435 + /* Call FM module routine for communicating parameters */
54436 + /************************************************************/
54437 + memset(&fmParams, 0, sizeof(fmParams));
54438 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54439 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54440 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54441 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54442 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54443 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54444 +
54445 + if (p_FmPort->fifoBufs.num)
54446 + {
54447 + errCode = VerifySizeOfFifo(p_FmPort);
54448 + if (errCode != E_OK)
54449 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54450 + }
54451 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54452 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54453 + fmParams.independentMode = p_FmPort->imEn;
54454 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54455 + fmParams.liodnBase = p_DriverParams->liodnBase;
54456 + fmParams.deqPipelineDepth =
54457 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54458 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54459 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54460 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54461 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54462 + {
54463 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54464 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54465 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54466 + * for deq threshold calculation.
54467 + */
54468 + fmParams.deqPipelineDepth = 2;
54469 + }
54470 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54471 +
54472 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54473 + if (errCode)
54474 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54475 +
54476 + /* get params for use in init */
54477 + p_FmPort->fmMuramPhysBaseAddr =
54478 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54479 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54480 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54481 +
54482 + errCode = InitLowLevelDriver(p_FmPort);
54483 + if (errCode != E_OK)
54484 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54485 +
54486 + FmPortDriverParamFree(p_FmPort);
54487 +
54488 +#if (DPAA_VERSION >= 11)
54489 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54490 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54491 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54492 + {
54493 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54494 +
54495 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54496 + (void**)&p_ParamsPage);
54497 + ASSERT_COND(p_ParamsPage);
54498 +
54499 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54500 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54501 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54502 + {
54503 + WRITE_UINT32(
54504 + p_ParamsPage->misc,
54505 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54506 + WRITE_UINT32(
54507 + p_ParamsPage->discardMask,
54508 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54509 + }
54510 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54511 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54512 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54513 + WRITE_UINT32(
54514 + p_ParamsPage->errorsDiscardMask,
54515 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54516 + else
54517 + WRITE_UINT32(
54518 + p_ParamsPage->errorsDiscardMask,
54519 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54520 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54521 + }
54522 +#endif /* (DPAA_VERSION >= 11) */
54523 +
54524 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54525 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54526 + return E_OK;
54527 +}
54528 +
54529 +/**************************************************************************//**
54530 + @Function FM_PORT_Free
54531 +
54532 + @Description Frees all resources that were assigned to FM module.
54533 +
54534 + Calling this routine invalidates the descriptor.
54535 +
54536 + @Param[in] h_FmPort - FM module descriptor
54537 +
54538 + @Return E_OK on success; Error code otherwise.
54539 + *//***************************************************************************/
54540 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54541 +{
54542 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54543 + t_FmInterModulePortFreeParams fmParams;
54544 +
54545 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54546 +
54547 + if (p_FmPort->pcdEngines)
54548 + RETURN_ERROR(
54549 + MAJOR,
54550 + E_INVALID_STATE,
54551 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54552 +
54553 + if (p_FmPort->enabled)
54554 + {
54555 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54556 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54557 + }
54558 +
54559 + if (p_FmPort->imEn)
54560 + FmPortImFree(p_FmPort);
54561 +
54562 + FmPortDriverParamFree(p_FmPort);
54563 +
54564 + memset(&fmParams, 0, sizeof(fmParams));
54565 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54566 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54567 + fmParams.deqPipelineDepth =
54568 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54569 +
54570 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54571 +
54572 +#if (DPAA_VERSION >= 11)
54573 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54574 + != E_OK)
54575 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54576 +
54577 + if (p_FmPort->p_ParamsPage)
54578 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54579 +#endif /* (DPAA_VERSION >= 11) */
54580 +
54581 + if (p_FmPort->h_Spinlock)
54582 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54583 +
54584 + XX_Free(p_FmPort);
54585 +
54586 + return E_OK;
54587 +}
54588 +
54589 +/*************************************************/
54590 +/* API Advanced Init unit functions */
54591 +/*************************************************/
54592 +
54593 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54594 +{
54595 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54596 +
54597 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54598 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54599 +
54600 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54601 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54602 +
54603 + return E_OK;
54604 +}
54605 +
54606 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54607 +{
54608 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54609 +
54610 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54611 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54612 +
54613 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54614 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54615 + return E_OK;
54616 +}
54617 +
54618 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54619 +{
54620 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54621 +
54622 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54623 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54624 +
54625 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54626 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54627 +
54628 + return E_OK;
54629 +}
54630 +
54631 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54632 +{
54633 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54634 +
54635 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54636 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54637 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54638 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54639 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54640 +
54641 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54642 +
54643 + return E_OK;
54644 +}
54645 +
54646 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54647 +{
54648 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54649 +
54650 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54651 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54652 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54653 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54654 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54655 + ("not available for Rx ports"));
54656 +
54657 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54658 + (enum fman_port_deq_type)deqType;
54659 +
54660 + return E_OK;
54661 +}
54662 +
54663 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54664 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54665 +{
54666 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54667 +
54668 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54669 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54670 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54671 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54672 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54673 + ("not available for Rx ports"));
54674 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54675 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54676 +
54677 + return E_OK;
54678 +}
54679 +
54680 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54681 + t_FmBackupBmPools *p_BackupBmPools)
54682 +{
54683 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54684 +
54685 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54686 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54687 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54688 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54689 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54690 + ("available for Rx ports only"));
54691 +
54692 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54693 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54694 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54695 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54696 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54697 + sizeof(t_FmBackupBmPools));
54698 +
54699 + return E_OK;
54700 +}
54701 +
54702 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54703 +{
54704 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54705 +
54706 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54707 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54708 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54709 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54710 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54711 + ("not available for Rx ports"));
54712 +
54713 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54714 +
54715 + return E_OK;
54716 +}
54717 +
54718 +t_Error FM_PORT_ConfigBufferPrefixContent(
54719 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54720 +{
54721 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54722 +
54723 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54724 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54725 +
54726 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54727 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54728 + /* if dataAlign was not initialized by user, we return to driver's default */
54729 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54730 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54731 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54732 +
54733 + return E_OK;
54734 +}
54735 +
54736 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54737 + uint8_t checksumLastBytesIgnore)
54738 +{
54739 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54740 +
54741 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54742 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54743 +
54744 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54745 + checksumLastBytesIgnore;
54746 +
54747 + return E_OK;
54748 +}
54749 +
54750 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54751 + uint8_t cutBytesFromEnd)
54752 +{
54753 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54754 +
54755 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54756 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54757 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54758 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54759 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54760 + ("available for Rx ports only"));
54761 +
54762 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54763 +
54764 + return E_OK;
54765 +}
54766 +
54767 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54768 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54769 +{
54770 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54771 +
54772 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54773 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54774 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54775 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54776 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54777 + ("available for Rx ports only"));
54778 +
54779 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54780 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54781 + sizeof(t_FmBufPoolDepletion));
54782 +
54783 + return E_OK;
54784 +}
54785 +
54786 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54787 + t_Handle h_FmPort,
54788 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54789 +{
54790 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54791 +
54792 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54793 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54794 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54795 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54796 + ("available for OP ports only"));
54797 +
54798 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54799 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54800 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54801 + sizeof(t_FmBufPoolDepletion));
54802 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54803 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54804 + sizeof(t_FmExtPools));
54805 +
54806 + return E_OK;
54807 +}
54808 +
54809 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54810 +{
54811 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54812 +
54813 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54814 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54815 +
54816 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54817 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54818 + ("available for OP ports only"));
54819 +
54820 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54821 + sizeof(t_FmExtPools));
54822 +
54823 + return E_OK;
54824 +}
54825 +
54826 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54827 +{
54828 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54829 +
54830 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54831 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54832 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54833 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54834 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54835 + ("available for Tx ports only"));
54836 +
54837 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54838 +
54839 + return E_OK;
54840 +}
54841 +
54842 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54843 +{
54844 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54845 +
54846 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54847 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54848 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54849 +
54850 + return E_OK;
54851 +}
54852 +
54853 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
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 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54861 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54862 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54863 + ("Not available for Tx ports"));
54864 +
54865 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54866 +
54867 + return E_OK;
54868 +}
54869 +
54870 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54871 +{
54872 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54873 +
54874 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54875 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54876 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54877 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54878 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54879 + ("Not available for Tx ports"));
54880 +
54881 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
54882 +
54883 + return E_OK;
54884 +}
54885 +
54886 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
54887 + fmPortFrameErrSelect_t errs)
54888 +{
54889 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54890 +
54891 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54892 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54893 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54894 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54895 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54896 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54897 + ("available for Rx and offline parsing ports only"));
54898 +
54899 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
54900 +
54901 + return E_OK;
54902 +}
54903 +
54904 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
54905 +{
54906 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54907 +
54908 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54909 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54910 +
54911 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
54912 + (enum fman_port_dma_swap)swapData;
54913 +
54914 + return E_OK;
54915 +}
54916 +
54917 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
54918 + e_FmDmaCacheOption intContextCacheAttr)
54919 +{
54920 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54921 +
54922 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54923 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54924 +
54925 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
54926 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
54927 +
54928 + return E_OK;
54929 +}
54930 +
54931 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
54932 + e_FmDmaCacheOption headerCacheAttr)
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->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
54940 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
54941 +
54942 + return E_OK;
54943 +}
54944 +
54945 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
54946 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
54947 +{
54948 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54949 +
54950 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54951 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54952 +
54953 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
54954 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
54955 +
54956 + return E_OK;
54957 +}
54958 +
54959 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
54960 +{
54961 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54962 +
54963 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54964 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54965 +
54966 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54967 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54968 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54969 + ("Not available for Tx ports"));
54970 +
54971 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
54972 +
54973 + return E_OK;
54974 +}
54975 +
54976 +#if (DPAA_VERSION >= 11)
54977 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
54978 +{
54979 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54980 +
54981 + UNUSED(noScatherGather);
54982 + UNUSED(p_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 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
54988 +
54989 + return E_OK;
54990 +}
54991 +#endif /* (DPAA_VERSION >= 11) */
54992 +
54993 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
54994 + bool forwardReuse)
54995 +{
54996 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54997 +
54998 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54999 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55000 +
55001 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55002 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55003 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55004 + ("available for Rx ports only"));
55005 +
55006 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
55007 +
55008 + return E_OK;
55009 +}
55010 +
55011 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
55012 +{
55013 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55014 +
55015 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55016 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55017 +
55018 + p_FmPort->maxFrameLength = length;
55019 +
55020 + return E_OK;
55021 +}
55022 +
55023 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
55024 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
55025 +{
55026 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55027 +
55028 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55029 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55030 +
55031 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
55032 +
55033 + return E_OK;
55034 +}
55035 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
55036 +
55037 +/****************************************************/
55038 +/* Hidden-DEBUG Only API */
55039 +/****************************************************/
55040 +
55041 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
55042 + uint32_t minFillLevel)
55043 +{
55044 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55045 +
55046 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55047 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55048 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55049 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55050 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55051 + ("available for Tx ports only"));
55052 +
55053 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
55054 +
55055 + return E_OK;
55056 +}
55057 +
55058 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
55059 + uint8_t deqPipelineDepth)
55060 +{
55061 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55062 +
55063 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55064 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55065 +
55066 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55067 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
55068 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55069 + ("Not available for Rx ports"));
55070 +
55071 + if (p_FmPort->imEn)
55072 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55073 + ("Not available for IM ports!"));
55074 +
55075 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55076 + deqPipelineDepth;
55077 +
55078 + return E_OK;
55079 +}
55080 +
55081 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
55082 + uint32_t fifoLowComfLevel)
55083 +{
55084 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55085 +
55086 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55087 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55088 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55089 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55090 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55091 + ("available for Tx ports only"));
55092 +
55093 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
55094 + fifoLowComfLevel;
55095 +
55096 + return E_OK;
55097 +}
55098 +
55099 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
55100 +{
55101 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55102 +
55103 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55104 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55105 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55106 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55107 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55108 + ("available for Rx ports only"));
55109 +
55110 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
55111 +
55112 + return E_OK;
55113 +}
55114 +
55115 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
55116 + uint32_t priElevationLevel)
55117 +{
55118 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55119 +
55120 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55121 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55122 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55123 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55124 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55125 + ("available for Rx ports only"));
55126 +
55127 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
55128 +
55129 + return E_OK;
55130 +}
55131 +/****************************************************/
55132 +/* API Run-time Control unit functions */
55133 +/****************************************************/
55134 +
55135 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
55136 + t_FmPortRsrc *p_NumOfOpenDmas)
55137 +{
55138 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55139 + t_Error err;
55140 +
55141 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55142 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55143 +
55144 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
55145 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
55146 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
55147 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
55148 + RETURN_ERROR(
55149 + MAJOR,
55150 + E_INVALID_VALUE,
55151 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
55152 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55153 + (uint8_t*)&p_NumOfOpenDmas->num,
55154 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
55155 + if (err)
55156 + RETURN_ERROR(MAJOR, err, NO_MSG);
55157 +
55158 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
55159 +
55160 + return E_OK;
55161 +}
55162 +
55163 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
55164 +{
55165 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55166 + t_Error err;
55167 +
55168 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55169 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55170 +
55171 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
55172 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
55173 +
55174 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
55175 + RETURN_ERROR(
55176 + MAJOR, E_INVALID_VALUE,
55177 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
55178 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
55179 + RETURN_ERROR(
55180 + MAJOR,
55181 + E_INVALID_VALUE,
55182 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
55183 +
55184 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55185 + (uint8_t*)&p_NumOfTasks->num,
55186 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
55187 + if (err)
55188 + RETURN_ERROR(MAJOR, err, NO_MSG);
55189 +
55190 + /* update driver's struct */
55191 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
55192 + return E_OK;
55193 +}
55194 +
55195 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
55196 +{
55197 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55198 + t_Error err;
55199 +
55200 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55201 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55202 +
55203 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
55204 + RETURN_ERROR(
55205 + MAJOR,
55206 + E_INVALID_VALUE,
55207 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
55208 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
55209 + RETURN_ERROR(
55210 + MAJOR, E_INVALID_VALUE,
55211 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
55212 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55213 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55214 + {
55215 + /* extra FIFO size (allowed only to Rx ports) */
55216 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
55217 + RETURN_ERROR(
55218 + MAJOR,
55219 + E_INVALID_VALUE,
55220 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
55221 + }
55222 + else
55223 + if (p_SizeOfFifo->extra)
55224 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
55225 + (" No SizeOfFifo-extra for non Rx ports"));
55226 +
55227 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
55228 +
55229 + /* we do not change user's parameter */
55230 + err = VerifySizeOfFifo(p_FmPort);
55231 + if (err)
55232 + RETURN_ERROR(MAJOR, err, NO_MSG);
55233 +
55234 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55235 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
55236 + if (err)
55237 + RETURN_ERROR(MAJOR, err, NO_MSG);
55238 +
55239 + return E_OK;
55240 +}
55241 +
55242 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55243 +{
55244 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55245 +
55246 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55247 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55248 + 0);
55249 +
55250 + return p_FmPort->bufferOffsets.dataOffset;
55251 +}
55252 +
55253 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55254 +{
55255 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55256 +
55257 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55258 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55259 + NULL);
55260 +
55261 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55262 + return NULL;
55263 +
55264 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55265 +}
55266 +
55267 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55268 +{
55269 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55270 +
55271 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55272 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55273 + NULL);
55274 +
55275 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55276 + return NULL;
55277 +
55278 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55279 +}
55280 +
55281 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55282 +{
55283 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55284 +
55285 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55286 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55287 + NULL);
55288 +
55289 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55290 + return NULL;
55291 +
55292 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55293 +}
55294 +
55295 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55296 +{
55297 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55298 +
55299 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55300 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55301 + NULL);
55302 +
55303 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55304 + return NULL;
55305 +
55306 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55307 +}
55308 +
55309 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55310 +{
55311 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55312 + int err;
55313 +
55314 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55315 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55316 +
55317 + if (p_FmPort->imEn)
55318 + FmPortImDisable(p_FmPort);
55319 +
55320 + err = fman_port_disable(&p_FmPort->port);
55321 + if (err == -EBUSY)
55322 + {
55323 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55324 + p_FmPort->name));
55325 + }
55326 + else
55327 + if (err != 0)
55328 + {
55329 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55330 + }
55331 +
55332 + p_FmPort->enabled = FALSE;
55333 +
55334 + return E_OK;
55335 +}
55336 +
55337 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55338 +{
55339 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55340 + int err;
55341 +
55342 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55343 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55344 +
55345 + /* Used by FM_PORT_Free routine as indication
55346 + if to disable port. Thus set it to TRUE prior
55347 + to enabling itself. This way if part of enable
55348 + process fails there will be still things
55349 + to disable during Free. For example, if BMI
55350 + enable succeeded but QMI failed, still BMI
55351 + needs to be disabled by Free. */
55352 + p_FmPort->enabled = TRUE;
55353 +
55354 + if (p_FmPort->imEn)
55355 + FmPortImEnable(p_FmPort);
55356 +
55357 + err = fman_port_enable(&p_FmPort->port);
55358 + if (err != 0)
55359 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55360 +
55361 + return E_OK;
55362 +}
55363 +
55364 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55365 +{
55366 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55367 + uint8_t factor, countUnitBit;
55368 + uint16_t baseGran;
55369 + struct fman_port_rate_limiter params;
55370 + int err;
55371 +
55372 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55373 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55374 +
55375 + switch (p_FmPort->portType)
55376 + {
55377 + case (e_FM_PORT_TYPE_TX_10G):
55378 + case (e_FM_PORT_TYPE_TX):
55379 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55380 + break;
55381 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55382 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55383 + break;
55384 + default:
55385 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55386 + ("available for Tx and Offline parsing ports only"));
55387 + }
55388 +
55389 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55390 + /* normally, we use 1 usec as the reference count */
55391 + factor = 1;
55392 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55393 + while (p_RateLimit->rateLimit < baseGran / factor)
55394 + {
55395 + if (countUnitBit == 31)
55396 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55397 +
55398 + countUnitBit++;
55399 + factor <<= 1;
55400 + }
55401 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55402 + if (p_RateLimit->rateLimit
55403 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55404 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55405 +
55406 + if (!p_RateLimit->maxBurstSize
55407 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55408 + RETURN_ERROR(
55409 + MAJOR,
55410 + E_INVALID_VALUE,
55411 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55412 +
55413 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55414 + params.high_burst_size_gran = FALSE;
55415 + params.burst_size = p_RateLimit->maxBurstSize;
55416 + params.rate = p_RateLimit->rateLimit;
55417 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55418 +
55419 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55420 + {
55421 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55422 +
55423 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55424 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55425 + {
55426 + params.high_burst_size_gran = TRUE;
55427 + }
55428 + else
55429 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55430 + {
55431 + if (p_RateLimit->rateLimitDivider
55432 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55433 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55434 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55435 +
55436 + if (p_RateLimit->maxBurstSize % 1000)
55437 + {
55438 + p_RateLimit->maxBurstSize =
55439 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55440 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55441 + }
55442 + else
55443 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55444 + / 1000);
55445 + }
55446 + params.rate_factor =
55447 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55448 + params.burst_size = p_RateLimit->maxBurstSize;
55449 + }
55450 +
55451 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55452 + if (err != 0)
55453 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55454 +
55455 + return E_OK;
55456 +}
55457 +
55458 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55459 +{
55460 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55461 + int err;
55462 +
55463 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55464 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55465 +
55466 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55467 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55468 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55469 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55470 + ("available for Tx and Offline parsing ports only"));
55471 +
55472 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55473 + if (err != 0)
55474 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55475 + return E_OK;
55476 +}
55477 +
55478 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55479 + uint8_t wq)
55480 +{
55481 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55482 + uint32_t tmpReg;
55483 + uint32_t wqTmpReg;
55484 +
55485 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55486 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55487 +
55488 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55489 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55490 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55491 + ("PFC mapping is available for Tx ports only"));
55492 +
55493 + if (prio > 7)
55494 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55495 + ("PFC priority (%d) is out of range (0-7)", prio));
55496 + if (wq > 7)
55497 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55498 + ("WQ (%d) is out of range (0-7)", wq));
55499 +
55500 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55501 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55502 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55503 + tmpReg |= wqTmpReg;
55504 +
55505 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55506 + tmpReg);
55507 +
55508 + return E_OK;
55509 +}
55510 +
55511 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55512 +{
55513 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55514 +
55515 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55516 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55517 +
55518 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55519 +
55520 + return E_OK;
55521 +}
55522 +
55523 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55524 +{
55525 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55526 + int err;
55527 +
55528 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55529 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55530 +
55531 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55532 + if (err != 0)
55533 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55534 + return E_OK;
55535 +}
55536 +
55537 +t_Error FM_PORT_SetPerformanceCountersParams(
55538 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55539 +{
55540 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55541 + struct fman_port_perf_cnt_params params;
55542 + int err;
55543 +
55544 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55545 +
55546 + /* check parameters */
55547 + if (!p_FmPortPerformanceCnt->taskCompVal
55548 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55549 + RETURN_ERROR(
55550 + MAJOR,
55551 + E_INVALID_VALUE,
55552 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55553 + if (!p_FmPortPerformanceCnt->dmaCompVal
55554 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55555 + RETURN_ERROR(
55556 + MAJOR,
55557 + E_INVALID_VALUE,
55558 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55559 + if (!p_FmPortPerformanceCnt->fifoCompVal
55560 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55561 + RETURN_ERROR(
55562 + MAJOR,
55563 + E_INVALID_VALUE,
55564 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55565 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55566 + RETURN_ERROR(
55567 + MAJOR,
55568 + E_INVALID_VALUE,
55569 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55570 +
55571 + switch (p_FmPort->portType)
55572 + {
55573 + case (e_FM_PORT_TYPE_RX_10G):
55574 + case (e_FM_PORT_TYPE_RX):
55575 + if (!p_FmPortPerformanceCnt->queueCompVal
55576 + || (p_FmPortPerformanceCnt->queueCompVal
55577 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55578 + RETURN_ERROR(
55579 + MAJOR,
55580 + E_INVALID_VALUE,
55581 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55582 + break;
55583 + case (e_FM_PORT_TYPE_TX_10G):
55584 + case (e_FM_PORT_TYPE_TX):
55585 + if (!p_FmPortPerformanceCnt->queueCompVal
55586 + || (p_FmPortPerformanceCnt->queueCompVal
55587 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55588 + RETURN_ERROR(
55589 + MAJOR,
55590 + E_INVALID_VALUE,
55591 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55592 + break;
55593 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55594 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55595 + if (p_FmPortPerformanceCnt->queueCompVal)
55596 + RETURN_ERROR(
55597 + MAJOR,
55598 + E_INVALID_VALUE,
55599 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55600 + break;
55601 + default:
55602 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55603 + }
55604 +
55605 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55606 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55607 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55608 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55609 +
55610 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55611 + if (err != 0)
55612 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55613 +
55614 + return E_OK;
55615 +}
55616 +
55617 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55618 +{
55619 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55620 + t_FmPortPerformanceCnt currParams, savedParams;
55621 + t_Error err;
55622 + bool underTest, failed = FALSE;
55623 +
55624 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55625 +
55626 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55627 + p_FmPort->portType, p_FmPort->portId);
55628 +
55629 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55630 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55631 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55632 + currParams.queueCompVal = 0;
55633 + else
55634 + currParams.queueCompVal = 1;
55635 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55636 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55637 +
55638 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55639 + ClearPerfCnts(p_FmPort);
55640 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55641 + != E_OK)
55642 + RETURN_ERROR(MAJOR, err, NO_MSG);
55643 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55644 + XX_UDelay(1000000);
55645 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55646 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55647 + {
55648 + XX_Print(
55649 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55650 + p_FmPort->tasks.num);
55651 + failed = TRUE;
55652 + }
55653 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55654 + {
55655 + XX_Print(
55656 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55657 + p_FmPort->openDmas.num);
55658 + failed = TRUE;
55659 + }
55660 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55661 + {
55662 + XX_Print(
55663 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55664 + p_FmPort->fifoBufs.num);
55665 + failed = TRUE;
55666 + }
55667 + if (failed)
55668 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55669 +
55670 + memset(&savedParams, 0, sizeof(savedParams));
55671 + while (TRUE)
55672 + {
55673 + underTest = FALSE;
55674 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55675 + {
55676 + currParams.taskCompVal--;
55677 + underTest = TRUE;
55678 + }
55679 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55680 + {
55681 + currParams.dmaCompVal--;
55682 + underTest = TRUE;
55683 + }
55684 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55685 + && !savedParams.fifoCompVal)
55686 + {
55687 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55688 + underTest = TRUE;
55689 + }
55690 + if (!underTest)
55691 + break;
55692 +
55693 + ClearPerfCnts(p_FmPort);
55694 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55695 + != E_OK)
55696 + RETURN_ERROR(MAJOR, err, NO_MSG);
55697 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55698 + XX_UDelay(1000000);
55699 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55700 +
55701 + if (!savedParams.taskCompVal
55702 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55703 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55704 + if (!savedParams.dmaCompVal
55705 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55706 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55707 + if (!savedParams.fifoCompVal
55708 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55709 + savedParams.fifoCompVal = currParams.fifoCompVal
55710 + + (2 * BMI_FIFO_UNITS);
55711 + }
55712 +
55713 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55714 + savedParams.taskCompVal, savedParams.dmaCompVal,
55715 + savedParams.fifoCompVal);
55716 + return E_OK;
55717 +}
55718 +
55719 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55720 +{
55721 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55722 + int err;
55723 +
55724 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55725 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55726 +
55727 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55728 + if (err != 0)
55729 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55730 + return E_OK;
55731 +}
55732 +
55733 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55734 +{
55735 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55736 + volatile uint32_t *p_ErrDiscard = NULL;
55737 + int err;
55738 +
55739 + UNUSED(p_ErrDiscard);
55740 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55741 + if (err != 0)
55742 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55743 +
55744 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55745 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55746 + {
55747 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55748 +
55749 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55750 + (void**)&p_ParamsPage);
55751 + ASSERT_COND(p_ParamsPage);
55752 + switch (p_FmPort->portType)
55753 + {
55754 + case (e_FM_PORT_TYPE_RX_10G):
55755 + case (e_FM_PORT_TYPE_RX):
55756 + p_ErrDiscard =
55757 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55758 + break;
55759 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55760 + p_ErrDiscard =
55761 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55762 + break;
55763 + default:
55764 + RETURN_ERROR(
55765 + MAJOR, E_INVALID_OPERATION,
55766 + ("available for Rx and offline parsing ports only"));
55767 + }
55768 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55769 + GET_UINT32(*p_ErrDiscard) | errs);
55770 + }
55771 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55772 +
55773 + return E_OK;
55774 +}
55775 +
55776 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55777 + bool enable)
55778 +{
55779 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55780 + int err;
55781 +
55782 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55783 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55784 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55785 +
55786 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55787 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55788 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55789 + ("available for Rx ports only"));
55790 +
55791 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55792 + if (err != 0)
55793 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55794 + return E_OK;
55795 +}
55796 +
55797 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55798 +{
55799 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55800 +
55801 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55802 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55803 + p_BmiStats->cntCycle =
55804 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55805 + /* fmbm_rccn */
55806 + p_BmiStats->cntTaskUtil =
55807 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55808 + /* fmbm_rtuc */
55809 + p_BmiStats->cntQueueUtil =
55810 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55811 + /* fmbm_rrquc */
55812 + p_BmiStats->cntDmaUtil =
55813 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55814 + /* fmbm_rduc */
55815 + p_BmiStats->cntFifoUtil =
55816 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55817 + /* fmbm_rfuc */
55818 + p_BmiStats->cntRxPauseActivation =
55819 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55820 + /* fmbm_rpac */
55821 + p_BmiStats->cntFrame =
55822 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55823 + /* fmbm_rfrc */
55824 + p_BmiStats->cntDiscardFrame =
55825 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55826 + /* fmbm_rfdc */
55827 + p_BmiStats->cntDeallocBuf =
55828 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55829 + /* fmbm_rbdc */
55830 + p_BmiStats->cntRxBadFrame =
55831 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55832 + /* fmbm_rfbc */
55833 + p_BmiStats->cntRxLargeFrame =
55834 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55835 + /* fmbm_rlfc */
55836 + p_BmiStats->cntRxFilterFrame =
55837 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55838 + /* fmbm_rffc */
55839 + p_BmiStats->cntRxListDmaErr =
55840 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55841 + /* fmbm_rfldec */
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 = 0;
55846 + p_BmiStats->cntLengthErr = 0;
55847 + p_BmiStats->cntUnsupportedFormat = 0;
55848 + }
55849 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55850 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55851 + p_BmiStats->cntCycle =
55852 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55853 + /* fmbm_tccn */
55854 + p_BmiStats->cntTaskUtil =
55855 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55856 + /* fmbm_ttuc */
55857 + p_BmiStats->cntQueueUtil =
55858 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55859 + /* fmbm_ttcquc */
55860 + p_BmiStats->cntDmaUtil =
55861 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55862 + /* fmbm_tduc */
55863 + p_BmiStats->cntFifoUtil =
55864 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55865 + /* fmbm_tfuc */
55866 + p_BmiStats->cntRxPauseActivation = 0;
55867 + p_BmiStats->cntFrame =
55868 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55869 + /* fmbm_tfrc */
55870 + p_BmiStats->cntDiscardFrame =
55871 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55872 + /* fmbm_tfdc */
55873 + p_BmiStats->cntDeallocBuf =
55874 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55875 + /* fmbm_tbdc */
55876 + p_BmiStats->cntRxBadFrame = 0;
55877 + p_BmiStats->cntRxLargeFrame = 0;
55878 + p_BmiStats->cntRxFilterFrame = 0;
55879 + p_BmiStats->cntRxListDmaErr = 0;
55880 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
55881 + p_BmiStats->cntWredDiscard = 0;
55882 + p_BmiStats->cntLengthErr =
55883 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55884 + /* fmbm_tfledc */
55885 + p_BmiStats->cntUnsupportedFormat =
55886 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55887 + /* fmbm_tfufdc */
55888 + }
55889 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
55890 + p_BmiStats->cntCycle =
55891 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55892 + /* fmbm_occn */
55893 + p_BmiStats->cntTaskUtil =
55894 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55895 + /* fmbm_otuc */
55896 + p_BmiStats->cntQueueUtil = 0;
55897 + p_BmiStats->cntDmaUtil =
55898 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55899 + /* fmbm_oduc */
55900 + p_BmiStats->cntFifoUtil =
55901 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55902 + /* fmbm_ofuc*/
55903 + p_BmiStats->cntRxPauseActivation = 0;
55904 + p_BmiStats->cntFrame =
55905 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55906 + /* fmbm_ofrc */
55907 + p_BmiStats->cntDiscardFrame =
55908 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55909 + /* fmbm_ofdc */
55910 + p_BmiStats->cntDeallocBuf =
55911 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55912 + /* fmbm_obdc*/
55913 + p_BmiStats->cntRxBadFrame = 0;
55914 + p_BmiStats->cntRxLargeFrame = 0;
55915 + p_BmiStats->cntRxFilterFrame =
55916 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55917 + /* fmbm_offc */
55918 + p_BmiStats->cntRxListDmaErr =
55919 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55920 + /* fmbm_ofldec */
55921 + p_BmiStats->cntRxOutOfBuffersDiscard =
55922 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55923 + /* fmbm_rodc */
55924 + p_BmiStats->cntWredDiscard =
55925 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
55926 + /* fmbm_ofwdc */
55927 + p_BmiStats->cntLengthErr =
55928 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55929 + /* fmbm_ofledc */
55930 + p_BmiStats->cntUnsupportedFormat =
55931 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55932 + /* fmbm_ofufdc */
55933 + }
55934 + return E_OK;
55935 +}
55936 +
55937 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
55938 +{
55939 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55940 + bool bmiCounter = FALSE;
55941 + enum fman_port_stats_counters statsType;
55942 + enum fman_port_perf_counters perfType;
55943 + enum fman_port_qmi_counters queueType;
55944 + bool isStats;
55945 + t_Error errCode;
55946 +
55947 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55948 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55949 +
55950 + switch (counter)
55951 + {
55952 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55953 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55954 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55955 + /* check that counter is available for the port type */
55956 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55957 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55958 + {
55959 + REPORT_ERROR(MINOR, E_INVALID_STATE,
55960 + ("Requested counter is not available for Rx ports"));
55961 + return 0;
55962 + }
55963 + bmiCounter = FALSE;
55964 + break;
55965 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55966 + bmiCounter = FALSE;
55967 + break;
55968 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55969 + bmiCounter = TRUE;
55970 + break;
55971 + }
55972 +
55973 + if (bmiCounter)
55974 + {
55975 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55976 + &perfType, &isStats);
55977 + if (errCode != E_OK)
55978 + {
55979 + REPORT_ERROR(MINOR, errCode, NO_MSG);
55980 + return 0;
55981 + }
55982 + if (isStats)
55983 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
55984 + else
55985 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
55986 + }
55987 + else /* QMI counter */
55988 + {
55989 + /* check that counters are enabled */
55990 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55991 + & QMI_PORT_CFG_EN_COUNTERS))
55992 +
55993 + {
55994 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
55995 + return 0;
55996 + }
55997 +
55998 + /* Set counter */
55999 + switch (counter)
56000 + {
56001 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56002 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56003 + break;
56004 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56005 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56006 + break;
56007 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56008 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56009 + break;
56010 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56011 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56012 + break;
56013 + default:
56014 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
56015 + return 0;
56016 + }
56017 +
56018 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
56019 + }
56020 +
56021 + return 0;
56022 +}
56023 +
56024 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
56025 + uint32_t value)
56026 +{
56027 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56028 + bool bmiCounter = FALSE;
56029 + enum fman_port_stats_counters statsType;
56030 + enum fman_port_perf_counters perfType;
56031 + enum fman_port_qmi_counters queueType;
56032 + bool isStats;
56033 + t_Error errCode;
56034 +
56035 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56036 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56037 +
56038 + switch (counter)
56039 + {
56040 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56041 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56042 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56043 + /* check that counter is available for the port type */
56044 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56045 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56046 + RETURN_ERROR(
56047 + MINOR, E_INVALID_STATE,
56048 + ("Requested counter is not available for Rx ports"));
56049 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56050 + bmiCounter = FALSE;
56051 + break;
56052 + default: /* BMI counters (or error - will be checked in BMI routine )*/
56053 + bmiCounter = TRUE;
56054 + break;
56055 + }
56056 +
56057 + if (bmiCounter)
56058 + {
56059 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
56060 + &perfType, &isStats);
56061 + if (errCode != E_OK)
56062 + {
56063 + RETURN_ERROR(MINOR, errCode, NO_MSG);
56064 + }
56065 + if (isStats)
56066 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
56067 + else
56068 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
56069 + }
56070 + else /* QMI counter */
56071 + {
56072 + /* check that counters are enabled */
56073 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
56074 + & QMI_PORT_CFG_EN_COUNTERS))
56075 + {
56076 + RETURN_ERROR(MINOR, E_INVALID_STATE,
56077 + ("Requested counter was not enabled"));
56078 + }
56079 +
56080 + /* Set counter */
56081 + switch (counter)
56082 + {
56083 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56084 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56085 + break;
56086 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56087 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56088 + break;
56089 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56090 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56091 + break;
56092 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56093 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56094 + break;
56095 + default:
56096 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56097 + ("Requested counter is not available"));
56098 + }
56099 +
56100 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
56101 + }
56102 +
56103 + return E_OK;
56104 +}
56105 +
56106 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
56107 +{
56108 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56109 +
56110 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56111 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56112 +
56113 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56114 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56115 + {
56116 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
56117 + return 0;
56118 + }
56119 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
56120 +}
56121 +
56122 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
56123 + uint32_t value)
56124 +{
56125 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
56126 +
56127 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56128 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56129 +
56130 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56131 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56132 + RETURN_ERROR( MINOR, E_INVALID_STATE,
56133 + ("Requested counter is not available for non-Rx ports"));
56134 +
56135 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
56136 + return E_OK;
56137 +}
56138 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
56139 +{
56140 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56141 + t_Error err;
56142 + bool isStalled;
56143 +
56144 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
56145 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56146 + FALSE);
56147 +
56148 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
56149 + if (err != E_OK)
56150 + {
56151 + REPORT_ERROR(MAJOR, err, NO_MSG);
56152 + return TRUE;
56153 + }
56154 + return isStalled;
56155 +}
56156 +
56157 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
56158 +{
56159 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56160 +
56161 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56162 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56163 +
56164 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
56165 +}
56166 +
56167 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
56168 +{
56169 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56170 + int err;
56171 +
56172 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56173 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56174 +
56175 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56176 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56177 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56178 + ("available for Rx ports only"));
56179 +
56180 + if (l4Checksum)
56181 + err = fman_port_modify_rx_fd_bits(
56182 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56183 + TRUE);
56184 + else
56185 + err = fman_port_modify_rx_fd_bits(
56186 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56187 + FALSE);
56188 + if (err != 0)
56189 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
56190 +
56191 + return E_OK;
56192 +}
56193 +
56194 +/*****************************************************************************/
56195 +/* API Run-time PCD Control unit functions */
56196 +/*****************************************************************************/
56197 +
56198 +#if (DPAA_VERSION >= 11)
56199 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
56200 +{
56201 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56202 + t_Error err = E_OK;
56203 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
56204 + uint32_t tmpReg = 0, tmp = 0;
56205 + uint16_t hwStoragePrflId;
56206 +
56207 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56208 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
56209 + /*for numOfProfiles = 0 don't call this function*/
56210 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
56211 + /*dfltRelativeId should be in the range of numOfProfiles*/
56212 + SANITY_CHECK_RETURN_ERROR(
56213 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
56214 + E_INVALID_VALUE);
56215 + /*p_FmPort should be from Rx type or OP*/
56216 + SANITY_CHECK_RETURN_ERROR(
56217 + ((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)),
56218 + E_INVALID_VALUE);
56219 + /*port should be disabled*/
56220 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
56221 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
56222 + SANITY_CHECK_RETURN_ERROR(
56223 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56224 + E_INVALID_VALUE);
56225 + /*should be called before SetPCD - this port should be without PCD*/
56226 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
56227 +
56228 + /*alloc window of VSPs for this port*/
56229 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
56230 + p_FmPort->portId, p_VSPParams->numOfProfiles);
56231 + if (err != E_OK)
56232 + RETURN_ERROR(MAJOR, err, NO_MSG);
56233 +
56234 + /*get absolute VSP ID for dfltRelative*/
56235 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
56236 + p_FmPort->portId,
56237 + p_VSPParams->dfltRelativeId,
56238 + &hwStoragePrflId);
56239 + if (err != E_OK)
56240 + RETURN_ERROR(MAJOR, err, NO_MSG);
56241 +
56242 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56243 + switch (p_FmPort->portType)
56244 + {
56245 + case (e_FM_PORT_TYPE_RX_10G):
56246 + case (e_FM_PORT_TYPE_RX):
56247 + p_BmiStorageProfileId =
56248 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56249 + p_BmiVspe =
56250 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56251 +
56252 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56253 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56254 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56255 +
56256 + tmpReg = GET_UINT32(*p_BmiVspe);
56257 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56258 +
56259 + p_BmiStorageProfileId =
56260 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56261 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56262 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56263 + break;
56264 +
56265 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56266 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56267 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56268 + tmpReg);
56269 +
56270 + p_BmiStorageProfileId =
56271 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56272 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56273 + tmp |= BMI_EBD_EN;
56274 + break;
56275 +
56276 + default:
56277 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56278 + ("available for Rx and offline parsing ports only"));
56279 + }
56280 +
56281 + p_FmPort->vspe = TRUE;
56282 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56283 +
56284 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56285 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56286 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56287 +
56288 + tmpReg = GET_UINT32(*p_BmiVspe);
56289 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56290 + return E_OK;
56291 +}
56292 +#endif /* (DPAA_VERSION >= 11) */
56293 +
56294 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56295 +{
56296 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56297 + t_Error err = E_OK;
56298 +
56299 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56300 + ASSERT_COND(p_FmPort->h_FmPcd);
56301 +
56302 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56303 + {
56304 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56305 + return ERROR_CODE(E_BUSY);
56306 + }
56307 +
56308 + if (numOfProfiles)
56309 + {
56310 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56311 + p_FmPort->hardwarePortId, numOfProfiles);
56312 + if (err)
56313 + RETURN_ERROR(MAJOR, err, NO_MSG);
56314 + }
56315 + /* set the port handle within the PCD policer, even if no profiles defined */
56316 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56317 +
56318 + RELEASE_LOCK(p_FmPort->lock);
56319 +
56320 + return E_OK;
56321 +}
56322 +
56323 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56324 +{
56325 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56326 + t_Error err = E_OK;
56327 +
56328 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56329 + {
56330 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56331 + return ERROR_CODE(E_BUSY);
56332 + }
56333 +
56334 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56335 +
56336 + RELEASE_LOCK(p_FmPort->lock);
56337 +
56338 + if (err)
56339 + RETURN_ERROR(MAJOR, err, NO_MSG);
56340 +
56341 + return E_OK;
56342 +}
56343 +
56344 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56345 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56346 +{
56347 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56348 + volatile uint32_t *p_BmiHpnia = NULL;
56349 + uint32_t tmpReg;
56350 + uint8_t relativeSchemeId;
56351 + uint8_t physicalSchemeId;
56352 +
56353 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56354 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56355 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56356 + E_INVALID_STATE);
56357 +
56358 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56359 + switch (p_FmPort->portType)
56360 + {
56361 + case (e_FM_PORT_TYPE_RX_10G):
56362 + case (e_FM_PORT_TYPE_RX):
56363 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56364 + break;
56365 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56366 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56367 + break;
56368 + default:
56369 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56370 + ("available for Rx and offline parsing ports only"));
56371 + }
56372 +
56373 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56374 + {
56375 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56376 + return ERROR_CODE(E_BUSY);
56377 + }
56378 +
56379 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56380 + if (p_FmPcdKgScheme->direct)
56381 + {
56382 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56383 + /* check that this scheme is bound to this port */
56384 + if (!(p_FmPort->schemesPerPortVector
56385 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56386 + {
56387 + RELEASE_LOCK(p_FmPort->lock);
56388 + RETURN_ERROR(
56389 + MAJOR, E_INVALID_STATE,
56390 + ("called with a scheme that is not bound to this port"));
56391 + }
56392 +
56393 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56394 + physicalSchemeId);
56395 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56396 + {
56397 + RELEASE_LOCK(p_FmPort->lock);
56398 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56399 + ("called with invalid Scheme "));
56400 + }
56401 +
56402 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56403 + {
56404 + RELEASE_LOCK(p_FmPort->lock);
56405 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56406 + ("called with uninitialized Scheme "));
56407 + }
56408 +
56409 + WRITE_UINT32(
56410 + *p_BmiHpnia,
56411 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56412 + }
56413 + else
56414 + /* change to indirect scheme */
56415 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56416 + RELEASE_LOCK(p_FmPort->lock);
56417 +
56418 + return E_OK;
56419 +}
56420 +
56421 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56422 + t_Handle h_Profile)
56423 +{
56424 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56425 + volatile uint32_t *p_BmiNia;
56426 + volatile uint32_t *p_BmiHpnia;
56427 + uint32_t tmpReg;
56428 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56429 +
56430 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56431 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56432 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56433 + E_INVALID_STATE);
56434 +
56435 + /* check relevance of this routine - only when policer is used
56436 + directly after BMI or Parser */
56437 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56438 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56439 + RETURN_ERROR(
56440 + MAJOR,
56441 + E_INVALID_STATE,
56442 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56443 +
56444 + switch (p_FmPort->portType)
56445 + {
56446 + case (e_FM_PORT_TYPE_RX_10G):
56447 + case (e_FM_PORT_TYPE_RX):
56448 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56449 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56450 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56451 + break;
56452 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56453 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56454 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56455 + tmpReg = 0;
56456 + break;
56457 + default:
56458 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56459 + ("available for Rx and offline parsing ports only"));
56460 + }
56461 +
56462 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56463 + {
56464 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56465 + return ERROR_CODE(E_BUSY);
56466 + }
56467 +
56468 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56469 + {
56470 + RELEASE_LOCK(p_FmPort->lock);
56471 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56472 + }
56473 +
56474 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56475 +
56476 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56477 + {
56478 + /* update BMI HPNIA */
56479 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56480 + }
56481 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56482 + {
56483 + /* rfne may contain FDCS bits, so first we read them. */
56484 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56485 + /* update BMI NIA */
56486 + WRITE_UINT32(*p_BmiNia, tmpReg);
56487 + }RELEASE_LOCK(p_FmPort->lock);
56488 +
56489 + return E_OK;
56490 +}
56491 +
56492 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56493 +{
56494 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56495 + t_Error err = E_OK;
56496 + volatile uint32_t *p_BmiCcBase = NULL;
56497 + volatile uint32_t *p_BmiNia = NULL;
56498 + uint32_t ccTreePhysOffset;
56499 +
56500 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56501 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56502 +
56503 + if (p_FmPort->imEn)
56504 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56505 + ("available for non-independent mode ports only"));
56506 +
56507 + /* get PCD registers pointers */
56508 + switch (p_FmPort->portType)
56509 + {
56510 + case (e_FM_PORT_TYPE_RX_10G):
56511 + case (e_FM_PORT_TYPE_RX):
56512 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56513 + break;
56514 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56515 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56516 + break;
56517 + default:
56518 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56519 + ("available for Rx and offline parsing ports only"));
56520 + }
56521 +
56522 + /* check that current NIA is BMI to BMI */
56523 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56524 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56525 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56526 + ("may be called only for ports in BMI-to-BMI state."));
56527 +
56528 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56529 + {
56530 + if (p_FmPort->h_IpReassemblyManip)
56531 + {
56532 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56533 + p_FmPort->h_IpReassemblyManip, FALSE);
56534 + if (err != E_OK)
56535 + {
56536 + RETURN_ERROR(MAJOR, err, NO_MSG);
56537 + }
56538 + }
56539 + else
56540 + if (p_FmPort->h_CapwapReassemblyManip)
56541 + {
56542 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56543 + p_FmPort->h_CapwapReassemblyManip,
56544 + FALSE);
56545 + if (err != E_OK)
56546 + {
56547 + RETURN_ERROR(MAJOR, err, NO_MSG);
56548 + }
56549 + }
56550 + switch (p_FmPort->portType)
56551 + {
56552 + case (e_FM_PORT_TYPE_RX_10G):
56553 + case (e_FM_PORT_TYPE_RX):
56554 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56555 + break;
56556 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56557 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56558 + break;
56559 + default:
56560 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56561 + }
56562 +
56563 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56564 + {
56565 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56566 + return ERROR_CODE(E_BUSY);
56567 + }
56568 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56569 + &ccTreePhysOffset, h_FmPort);
56570 + if (err)
56571 + {
56572 + RELEASE_LOCK(p_FmPort->lock);
56573 + RETURN_ERROR(MAJOR, err, NO_MSG);
56574 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56575 +
56576 + p_FmPort->ccTreeId = h_CcTree;
56577 + RELEASE_LOCK(p_FmPort->lock);
56578 + }
56579 + else
56580 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56581 + ("Coarse Classification not defined for this port."));
56582 +
56583 + return E_OK;
56584 +}
56585 +
56586 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56587 +{
56588 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56589 + t_Error err = E_OK;
56590 +
56591 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56592 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56593 +
56594 + if (p_FmPort->imEn)
56595 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56596 + ("available for non-independent mode ports only"));
56597 +
56598 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56599 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56600 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56601 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56602 + ("available for Rx and offline parsing ports only"));
56603 +
56604 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56605 + {
56606 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56607 + return ERROR_CODE(E_BUSY);
56608 + }
56609 +
56610 + if (p_FmPort->h_ReassemblyTree)
56611 + p_FmPort->pcdEngines |= FM_PCD_CC;
56612 +
56613 + err = AttachPCD(h_FmPort);
56614 + RELEASE_LOCK(p_FmPort->lock);
56615 +
56616 + return err;
56617 +}
56618 +
56619 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56620 +{
56621 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56622 + t_Error err = E_OK;
56623 +
56624 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56625 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56626 +
56627 + if (p_FmPort->imEn)
56628 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56629 + ("available for non-independent mode ports only"));
56630 +
56631 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56632 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56633 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56634 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56635 + ("available for Rx and offline parsing ports only"));
56636 +
56637 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56638 + {
56639 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56640 + return ERROR_CODE(E_BUSY);
56641 + }
56642 +
56643 + err = DetachPCD(h_FmPort);
56644 + if (err != E_OK)
56645 + {
56646 + RELEASE_LOCK(p_FmPort->lock);
56647 + RETURN_ERROR(MAJOR, err, NO_MSG);
56648 + }
56649 +
56650 + if (p_FmPort->h_ReassemblyTree)
56651 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56652 + RELEASE_LOCK(p_FmPort->lock);
56653 +
56654 + return E_OK;
56655 +}
56656 +
56657 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56658 +{
56659 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56660 + t_Error err = E_OK;
56661 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56662 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56663 + t_FmPortPcdCcParams fmPortPcdCcParams;
56664 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56665 +
56666 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56667 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56668 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56669 +
56670 + if (p_FmPort->imEn)
56671 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56672 + ("available for non-independent mode ports only"));
56673 +
56674 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56675 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56676 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56677 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56678 + ("available for Rx and offline parsing ports only"));
56679 +
56680 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56681 + {
56682 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56683 + return ERROR_CODE(E_BUSY);
56684 + }
56685 +
56686 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56687 + ASSERT_COND(p_FmPort->h_FmPcd);
56688 +
56689 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56690 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56691 + ("Tree handle must be given if CC is required"));
56692 +
56693 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56694 + p_PcdParams = &modifiedPcdParams;
56695 + if ((p_PcdParams->h_IpReassemblyManip)
56696 +#if (DPAA_VERSION >= 11)
56697 + || (p_PcdParams->h_CapwapReassemblyManip)
56698 +#endif /* (DPAA_VERSION >= 11) */
56699 + )
56700 + {
56701 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56702 + && (p_PcdParams->pcdSupport
56703 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56704 + && (p_PcdParams->pcdSupport
56705 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56706 + && (p_PcdParams->pcdSupport
56707 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56708 + {
56709 + RELEASE_LOCK(p_FmPort->lock);
56710 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56711 + ("pcdSupport must have KG for supporting Reassembly"));
56712 + }
56713 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56714 +#if (DPAA_VERSION >= 11)
56715 + if ((p_PcdParams->h_IpReassemblyManip)
56716 + && (p_PcdParams->h_CapwapReassemblyManip))
56717 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56718 + ("Either IP-R or CAPWAP-R is allowed"));
56719 + if ((p_PcdParams->h_CapwapReassemblyManip)
56720 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56721 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56722 + ("CAPWAP-R is allowed only on offline-port"));
56723 + if (p_PcdParams->h_CapwapReassemblyManip)
56724 + p_FmPort->h_CapwapReassemblyManip =
56725 + p_PcdParams->h_CapwapReassemblyManip;
56726 +#endif /* (DPAA_VERSION >= 11) */
56727 +
56728 + if (!p_PcdParams->p_CcParams)
56729 + {
56730 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56731 + || (p_PcdParams->pcdSupport
56732 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56733 + {
56734 + RELEASE_LOCK(p_FmPort->lock);
56735 + RETURN_ERROR(
56736 + MAJOR,
56737 + E_INVALID_STATE,
56738 + ("PCD initialization structure is not consistent with pcdSupport"));
56739 + }
56740 +
56741 + /* No user-tree, need to build internal tree */
56742 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56743 + sizeof(t_FmPcdCcTreeParams));
56744 + if (!p_FmPcdCcTreeParams)
56745 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56746 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56747 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56748 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56749 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56750 +
56751 + if (!p_FmPort->h_ReassemblyTree)
56752 + {
56753 + RELEASE_LOCK(p_FmPort->lock);
56754 + XX_Free(p_FmPcdCcTreeParams);
56755 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56756 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56757 + }
56758 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56759 + p_PcdParams->pcdSupport =
56760 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56761 + else
56762 + p_PcdParams->pcdSupport =
56763 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56764 +
56765 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56766 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56767 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56768 + XX_Free(p_FmPcdCcTreeParams);
56769 + }
56770 +
56771 + if (p_FmPort->h_IpReassemblyManip)
56772 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56773 + p_PcdParams->p_CcParams->h_CcTree,
56774 + p_PcdParams->h_NetEnv,
56775 + p_FmPort->h_IpReassemblyManip, TRUE);
56776 +#if (DPAA_VERSION >= 11)
56777 + else
56778 + if (p_FmPort->h_CapwapReassemblyManip)
56779 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56780 + p_PcdParams->p_CcParams->h_CcTree,
56781 + p_PcdParams->h_NetEnv,
56782 + p_FmPort->h_CapwapReassemblyManip,
56783 + TRUE);
56784 +#endif /* (DPAA_VERSION >= 11) */
56785 +
56786 + if (err != E_OK)
56787 + {
56788 + if (p_FmPort->h_ReassemblyTree)
56789 + {
56790 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56791 + p_FmPort->h_ReassemblyTree = NULL;
56792 + }RELEASE_LOCK(p_FmPort->lock);
56793 + RETURN_ERROR(MAJOR, err, NO_MSG);
56794 + }
56795 + }
56796 +
56797 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56798 + {
56799 + if (p_FmPort->h_ReassemblyTree)
56800 + {
56801 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56802 + p_FmPort->h_ReassemblyTree = NULL;
56803 + }RELEASE_LOCK(p_FmPort->lock);
56804 + DBG(TRACE, ("Try LockAll - BUSY"));
56805 + return ERROR_CODE(E_BUSY);
56806 + }
56807 +
56808 + err = SetPcd(h_FmPort, p_PcdParams);
56809 + if (err)
56810 + {
56811 + if (p_FmPort->h_ReassemblyTree)
56812 + {
56813 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56814 + p_FmPort->h_ReassemblyTree = NULL;
56815 + }
56816 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56817 + RELEASE_LOCK(p_FmPort->lock);
56818 + RETURN_ERROR(MAJOR, err, NO_MSG);
56819 + }
56820 +
56821 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56822 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56823 + {
56824 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56825 + p_FmPort->hardwarePortId, TRUE);
56826 + if (err)
56827 + {
56828 + DeletePcd(p_FmPort);
56829 + if (p_FmPort->h_ReassemblyTree)
56830 + {
56831 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56832 + p_FmPort->h_ReassemblyTree = NULL;
56833 + }
56834 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56835 + RELEASE_LOCK(p_FmPort->lock);
56836 + RETURN_ERROR(MAJOR, err, NO_MSG);
56837 + }
56838 + p_FmPort->includeInPrsStatistics = TRUE;
56839 + }
56840 +
56841 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56842 +
56843 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56844 + {
56845 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56846 +
56847 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56848 + {
56849 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56850 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56851 + (p_FmPort->pcdEngines & FM_PCD_KG))
56852 + {
56853 + int i;
56854 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56855 + /* The following function must be locked */
56856 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56857 + p_PcdParams->p_KgParams->h_Schemes[i],
56858 + UPDATE_KG_NIA_CC_WA,
56859 + 0);
56860 + }
56861 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56862 +
56863 +#if (DPAA_VERSION >= 11)
56864 + {
56865 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56866 +
56867 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56868 + (void**)&p_ParamsPage);
56869 + ASSERT_COND(p_ParamsPage);
56870 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56871 + p_FmPort->savedBmiNia);
56872 + }
56873 +#endif /* (DPAA_VERSION >= 11) */
56874 +
56875 + /* Set post-bmi-fetch nia */
56876 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
56877 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
56878 + | NIA_ENG_FM_CTL);
56879 +
56880 + /* Set pre-bmi-fetch nia */
56881 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
56882 +#if (DPAA_VERSION >= 11)
56883 + fmPortGetSetCcParams.setCcParams.nia =
56884 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
56885 +#else
56886 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
56887 +#endif /* (DPAA_VERSION >= 11) */
56888 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
56889 + != E_OK)
56890 + {
56891 + DeletePcd(p_FmPort);
56892 + if (p_FmPort->h_ReassemblyTree)
56893 + {
56894 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56895 + p_FmPort->h_ReassemblyTree = NULL;
56896 + }
56897 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56898 + RELEASE_LOCK(p_FmPort->lock);
56899 + RETURN_ERROR(MAJOR, err, NO_MSG);
56900 + }
56901 + }
56902 +
56903 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56904 +
56905 + /* Set pop-to-next-step nia */
56906 +#if (DPAA_VERSION == 10)
56907 + if (p_FmPort->fmRevInfo.majorRev < 6)
56908 + {
56909 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
56910 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56911 + }
56912 + else
56913 + {
56914 +#endif /* (DPAA_VERSION == 10) */
56915 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
56916 +#if (DPAA_VERSION == 10)
56917 + }
56918 +#endif /* (DPAA_VERSION == 10) */
56919 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56920 + != E_OK)
56921 + {
56922 + DeletePcd(p_FmPort);
56923 + if (p_FmPort->h_ReassemblyTree)
56924 + {
56925 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56926 + p_FmPort->h_ReassemblyTree = NULL;
56927 + }RELEASE_LOCK(p_FmPort->lock);
56928 + RETURN_ERROR(MAJOR, err, NO_MSG);
56929 + }
56930 +
56931 + /* Set post-bmi-prepare-to-enq nia */
56932 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56933 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
56934 + | NIA_ENG_FM_CTL);
56935 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56936 + != E_OK)
56937 + {
56938 + DeletePcd(p_FmPort);
56939 + if (p_FmPort->h_ReassemblyTree)
56940 + {
56941 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56942 + p_FmPort->h_ReassemblyTree = NULL;
56943 + }RELEASE_LOCK(p_FmPort->lock);
56944 + RETURN_ERROR(MAJOR, err, NO_MSG);
56945 + }
56946 +
56947 + if ((p_FmPort->h_IpReassemblyManip)
56948 + || (p_FmPort->h_CapwapReassemblyManip))
56949 + {
56950 +#if (DPAA_VERSION == 10)
56951 + if (p_FmPort->fmRevInfo.majorRev < 6)
56952 + {
56953 + /* Overwrite post-bmi-prepare-to-enq nia */
56954 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56955 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
56956 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
56957 + }
56958 + else
56959 + {
56960 +#endif /* (DPAA_VERSION == 10) */
56961 + /* Set the ORR bit (for order-restoration) */
56962 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
56963 + fmPortGetSetCcParams.setCcParams.nia =
56964 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
56965 +#if (DPAA_VERSION == 10)
56966 + }
56967 +#endif /* (DPAA_VERSION == 10) */
56968 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56969 + != E_OK)
56970 + {
56971 + DeletePcd(p_FmPort);
56972 + if (p_FmPort->h_ReassemblyTree)
56973 + {
56974 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56975 + p_FmPort->h_ReassemblyTree = NULL;
56976 + }RELEASE_LOCK(p_FmPort->lock);
56977 + RETURN_ERROR(MAJOR, err, NO_MSG);
56978 + }
56979 + }
56980 + }
56981 + else
56982 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56983 +
56984 +#if (DPAA_VERSION >= 11)
56985 + {
56986 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56987 +
56988 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56989 +
56990 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
56991 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56992 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
56993 + | NIA_ENG_FM_CTL;
56994 + else
56995 + fmPortGetSetCcParams.setCcParams.nia =
56996 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56997 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56998 + != E_OK)
56999 + {
57000 + DeletePcd(p_FmPort);
57001 + if (p_FmPort->h_ReassemblyTree)
57002 + {
57003 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57004 + p_FmPort->h_ReassemblyTree = NULL;
57005 + }RELEASE_LOCK(p_FmPort->lock);
57006 + RETURN_ERROR(MAJOR, err, NO_MSG);
57007 + }
57008 +
57009 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
57010 + (void**)&p_ParamsPage);
57011 + ASSERT_COND(p_ParamsPage);
57012 +
57013 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
57014 + WRITE_UINT32(
57015 + p_ParamsPage->misc,
57016 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
57017 +
57018 + if ((p_FmPort->h_IpReassemblyManip)
57019 + || (p_FmPort->h_CapwapReassemblyManip))
57020 + {
57021 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57022 + WRITE_UINT32(
57023 + p_ParamsPage->discardMask,
57024 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
57025 + else
57026 + WRITE_UINT32(
57027 + p_ParamsPage->discardMask,
57028 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
57029 + }
57030 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
57031 + if (p_FmPort->vspe)
57032 + WRITE_UINT32(
57033 + p_ParamsPage->misc,
57034 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
57035 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
57036 + }
57037 +#endif /* (DPAA_VERSION >= 11) */
57038 +
57039 + err = AttachPCD(h_FmPort);
57040 + if (err)
57041 + {
57042 + DeletePcd(p_FmPort);
57043 + if (p_FmPort->h_ReassemblyTree)
57044 + {
57045 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57046 + p_FmPort->h_ReassemblyTree = NULL;
57047 + }RELEASE_LOCK(p_FmPort->lock);
57048 + RETURN_ERROR(MAJOR, err, NO_MSG);
57049 + }
57050 +
57051 + RELEASE_LOCK(p_FmPort->lock);
57052 +
57053 + return err;
57054 +}
57055 +
57056 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
57057 +{
57058 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57059 + t_Error err = E_OK;
57060 +
57061 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
57062 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57063 +
57064 + if (p_FmPort->imEn)
57065 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57066 + ("available for non-independant mode ports only"));
57067 +
57068 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57069 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57070 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57071 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57072 + ("available for Rx and offline parsing ports only"));
57073 +
57074 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57075 + {
57076 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57077 + return ERROR_CODE(E_BUSY);
57078 + }
57079 +
57080 + err = DetachPCD(h_FmPort);
57081 + if (err)
57082 + {
57083 + RELEASE_LOCK(p_FmPort->lock);
57084 + RETURN_ERROR(MAJOR, err, NO_MSG);
57085 + }
57086 +
57087 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
57088 +
57089 + /* we do it anyway, instead of checking if included */
57090 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
57091 + {
57092 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
57093 + p_FmPort->hardwarePortId, FALSE);
57094 + p_FmPort->includeInPrsStatistics = FALSE;
57095 + }
57096 +
57097 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
57098 + {
57099 + RELEASE_LOCK(p_FmPort->lock);
57100 + DBG(TRACE, ("Try LockAll - BUSY"));
57101 + return ERROR_CODE(E_BUSY);
57102 + }
57103 +
57104 + err = DeletePcd(h_FmPort);
57105 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57106 + if (err)
57107 + {
57108 + RELEASE_LOCK(p_FmPort->lock);
57109 + RETURN_ERROR(MAJOR, err, NO_MSG);
57110 + }
57111 +
57112 + if (p_FmPort->h_ReassemblyTree)
57113 + {
57114 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57115 + if (err)
57116 + {
57117 + RELEASE_LOCK(p_FmPort->lock);
57118 + RETURN_ERROR(MAJOR, err, NO_MSG);
57119 + }
57120 + p_FmPort->h_ReassemblyTree = NULL;
57121 + }RELEASE_LOCK(p_FmPort->lock);
57122 +
57123 + return err;
57124 +}
57125 +
57126 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
57127 + t_FmPcdPortSchemesParams *p_PortScheme)
57128 +{
57129 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57130 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57131 + t_Error err = E_OK;
57132 + uint32_t tmpScmVec = 0;
57133 + int i;
57134 +
57135 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57136 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57137 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57138 + E_INVALID_STATE);
57139 +
57140 + schemeBind.netEnvId = p_FmPort->netEnvId;
57141 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57142 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57143 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
57144 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57145 + {
57146 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57147 + p_PortScheme->h_Schemes[i]);
57148 + /* build vector */
57149 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57150 + }
57151 +
57152 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57153 + {
57154 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57155 + return ERROR_CODE(E_BUSY);
57156 + }
57157 +
57158 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57159 + if (err == E_OK)
57160 + p_FmPort->schemesPerPortVector |= tmpScmVec;
57161 +
57162 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
57163 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
57164 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
57165 + (p_FmPort->fmRevInfo.majorRev < 6))
57166 + {
57167 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
57168 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
57169 + }
57170 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
57171 +
57172 + RELEASE_LOCK(p_FmPort->lock);
57173 +
57174 + return err;
57175 +}
57176 +
57177 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
57178 + t_FmPcdPortSchemesParams *p_PortScheme)
57179 +{
57180 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57181 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57182 + t_Error err = E_OK;
57183 + uint32_t tmpScmVec = 0;
57184 + int i;
57185 +
57186 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57187 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57188 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57189 + E_INVALID_STATE);
57190 +
57191 + schemeBind.netEnvId = p_FmPort->netEnvId;
57192 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57193 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57194 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57195 + {
57196 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57197 + p_PortScheme->h_Schemes[i]);
57198 + /* build vector */
57199 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57200 + }
57201 +
57202 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57203 + {
57204 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57205 + return ERROR_CODE(E_BUSY);
57206 + }
57207 +
57208 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57209 + if (err == E_OK)
57210 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
57211 + RELEASE_LOCK(p_FmPort->lock);
57212 +
57213 + return err;
57214 +}
57215 +
57216 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
57217 + t_FmPortCongestionGrps *p_CongestionGrps)
57218 +{
57219 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57220 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
57221 + uint8_t mod, index;
57222 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57223 + int err;
57224 +#if (DPAA_VERSION >= 11)
57225 + int j;
57226 +#endif /* (DPAA_VERSION >= 11) */
57227 +
57228 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57229 +
57230 + /* un-necessary check of the indexes; probably will be needed in the future when there
57231 + will be more CGs available ....
57232 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57233 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
57234 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
57235 + */
57236 +
57237 +#ifdef FM_NO_OP_OBSERVED_CGS
57238 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
57239 + (p_FmPort->fmRevInfo.majorRev < 6))
57240 + {
57241 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57242 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57243 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57244 + }
57245 + else
57246 +#endif /* FM_NO_OP_OBSERVED_CGS */
57247 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57248 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57249 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57250 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57251 + ("Available for Rx & OP ports only"));
57252 +
57253 + /* Prepare groups map array */
57254 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57255 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57256 + {
57257 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57258 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57259 + if (p_FmPort->fmRevInfo.majorRev != 4)
57260 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57261 + else
57262 + grpsMap[0] |= (uint32_t)(1 << mod);
57263 + }
57264 +
57265 + memset(&priorityTmpArray, 0,
57266 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57267 +
57268 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57269 + {
57270 +#if (DPAA_VERSION >= 11)
57271 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57272 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57273 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57274 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57275 +#endif /* (DPAA_VERSION >= 11) */
57276 + }
57277 +
57278 +#if (DPAA_VERSION >= 11)
57279 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57280 + {
57281 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57282 + priorityTmpArray[i]);
57283 + if (err)
57284 + return err;
57285 + }
57286 +#endif /* (DPAA_VERSION >= 11) */
57287 +
57288 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57289 + if (err != 0)
57290 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57291 +
57292 + return E_OK;
57293 +}
57294 +
57295 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57296 + t_FmPortCongestionGrps *p_CongestionGrps)
57297 +{
57298 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57299 + uint8_t mod, index;
57300 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57301 + int err;
57302 +
57303 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57304 +
57305 + {
57306 +#ifdef FM_NO_OP_OBSERVED_CGS
57307 + t_FmRevisionInfo revInfo;
57308 +
57309 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57310 + if (revInfo.majorRev != 4)
57311 + {
57312 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57313 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57314 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57315 + }
57316 + else
57317 +#endif /* FM_NO_OP_OBSERVED_CGS */
57318 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57319 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57320 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57321 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57322 + ("Available for Rx & OP ports only"));
57323 + }
57324 +
57325 + /* Prepare groups map array */
57326 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57327 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57328 + {
57329 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57330 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57331 + if (p_FmPort->fmRevInfo.majorRev != 4)
57332 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57333 + else
57334 + grpsMap[0] |= (uint32_t)(1 << mod);
57335 + }
57336 +
57337 +#if (DPAA_VERSION >= 11)
57338 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57339 + {
57340 + t_Error err = FmSetCongestionGroupPFCpriority(
57341 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57342 + 0);
57343 + if (err)
57344 + return err;
57345 + }
57346 +#endif /* (DPAA_VERSION >= 11) */
57347 +
57348 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57349 + if (err != 0)
57350 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57351 + ("fman_port_remove_congestion_grps"));
57352 + return E_OK;
57353 +}
57354 +
57355 +#if (DPAA_VERSION >= 11)
57356 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57357 + uint32_t *p_Ipv4OptionsCount)
57358 +{
57359 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57360 +
57361 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57362 + SANITY_CHECK_RETURN_ERROR(
57363 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57364 + E_INVALID_VALUE);
57365 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57366 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57367 +
57368 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57369 +
57370 + return E_OK;
57371 +}
57372 +#endif /* (DPAA_VERSION >= 11) */
57373 +
57374 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57375 + t_FmPortDsarTablesSizes *params)
57376 +{
57377 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57378 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57379 + sizeof(struct t_FmPortDsarTablesSizes));
57380 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57381 + sizeof(struct t_FmPortDsarTablesSizes));
57382 + return E_OK;
57383 +}
57384 +
57385 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57386 +{
57387 + uint32_t *param_page;
57388 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57389 + t_ArCommonDesc *ArCommonDescPtr;
57390 + uint32_t size = sizeof(t_ArCommonDesc);
57391 + // ARP
57392 + // should put here if (params->max_num_of_arp_entries)?
57393 + size = ROUND_UP(size,4);
57394 + size += sizeof(t_DsarArpDescriptor);
57395 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57396 + size += sizeof(t_DsarArpStatistics);
57397 + //ICMPV4
57398 + size = ROUND_UP(size,4);
57399 + size += sizeof(t_DsarIcmpV4Descriptor);
57400 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57401 + size += sizeof(t_DsarIcmpV4Statistics);
57402 + //ICMPV6
57403 + size = ROUND_UP(size,4);
57404 + size += sizeof(t_DsarIcmpV6Descriptor);
57405 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57406 + size += sizeof(t_DsarIcmpV6Statistics);
57407 + //ND
57408 + size = ROUND_UP(size,4);
57409 + size += sizeof(t_DsarNdDescriptor);
57410 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57411 + size += sizeof(t_DsarIcmpV6Statistics);
57412 + //SNMP
57413 + size = ROUND_UP(size,4);
57414 + size += sizeof(t_DsarSnmpDescriptor);
57415 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57416 + * params->maxNumOfSnmpIPV4Entries;
57417 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57418 + * params->maxNumOfSnmpIPV6Entries;
57419 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57420 + size += params->maxNumOfSnmpOidChar;
57421 + size += sizeof(t_DsarIcmpV6Statistics);
57422 + //filters
57423 + size = ROUND_UP(size,4);
57424 + size += params->maxNumOfIpProtFiltering;
57425 + size = ROUND_UP(size,4);
57426 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57427 + size = ROUND_UP(size,4);
57428 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57429 +
57430 + // add here for more protocols
57431 +
57432 + // statistics
57433 + size = ROUND_UP(size,4);
57434 + size += sizeof(t_ArStatistics);
57435 +
57436 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57437 +
57438 + param_page =
57439 + XX_PhysToVirt(
57440 + p_FmPort->fmMuramPhysBaseAddr
57441 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57442 + WRITE_UINT32(
57443 + *param_page,
57444 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57445 + return E_OK;
57446 +}
57447 +
57448 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57449 +{
57450 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57451 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57452 +}
57453 +
57454 +struct arOffsets
57455 +{
57456 + uint32_t arp;
57457 + uint32_t nd;
57458 + uint32_t icmpv4;
57459 + uint32_t icmpv6;
57460 + uint32_t snmp;
57461 + uint32_t stats;
57462 + uint32_t filtIp;
57463 + uint32_t filtUdp;
57464 + uint32_t filtTcp;
57465 +};
57466 +
57467 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57468 + struct t_FmPortDsarParams *params,
57469 + t_FmPort *p_FmPort)
57470 +{
57471 + uint32_t size = sizeof(t_ArCommonDesc);
57472 + // ARP
57473 + if (params->p_AutoResArpInfo)
57474 + {
57475 + size = ROUND_UP(size,4);
57476 + of->arp = size;
57477 + size += sizeof(t_DsarArpDescriptor);
57478 + size += sizeof(t_DsarArpBindingEntry)
57479 + * params->p_AutoResArpInfo->tableSize;
57480 + size += sizeof(t_DsarArpStatistics);
57481 + }
57482 + // ICMPV4
57483 + if (params->p_AutoResEchoIpv4Info)
57484 + {
57485 + size = ROUND_UP(size,4);
57486 + of->icmpv4 = size;
57487 + size += sizeof(t_DsarIcmpV4Descriptor);
57488 + size += sizeof(t_DsarIcmpV4BindingEntry)
57489 + * params->p_AutoResEchoIpv4Info->tableSize;
57490 + size += sizeof(t_DsarIcmpV4Statistics);
57491 + }
57492 + // ICMPV6
57493 + if (params->p_AutoResEchoIpv6Info)
57494 + {
57495 + size = ROUND_UP(size,4);
57496 + of->icmpv6 = size;
57497 + size += sizeof(t_DsarIcmpV6Descriptor);
57498 + size += sizeof(t_DsarIcmpV6BindingEntry)
57499 + * params->p_AutoResEchoIpv6Info->tableSize;
57500 + size += sizeof(t_DsarIcmpV6Statistics);
57501 + }
57502 + // ND
57503 + if (params->p_AutoResNdpInfo)
57504 + {
57505 + size = ROUND_UP(size,4);
57506 + of->nd = size;
57507 + size += sizeof(t_DsarNdDescriptor);
57508 + size += sizeof(t_DsarIcmpV6BindingEntry)
57509 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57510 + + params->p_AutoResNdpInfo->tableSizeTmp);
57511 + size += sizeof(t_DsarIcmpV6Statistics);
57512 + }
57513 + // SNMP
57514 + if (params->p_AutoResSnmpInfo)
57515 + {
57516 + size = ROUND_UP(size,4);
57517 + of->snmp = size;
57518 + size += sizeof(t_DsarSnmpDescriptor);
57519 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57520 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57521 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57522 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57523 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57524 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57525 + size += sizeof(t_DsarIcmpV6Statistics);
57526 + }
57527 + //filters
57528 + size = ROUND_UP(size,4);
57529 + if (params->p_AutoResFilteringInfo)
57530 + {
57531 + of->filtIp = size;
57532 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57533 + size = ROUND_UP(size,4);
57534 + of->filtUdp = size;
57535 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57536 + * sizeof(t_PortTblEntry);
57537 + size = ROUND_UP(size,4);
57538 + of->filtTcp = size;
57539 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57540 + * sizeof(t_PortTblEntry);
57541 + }
57542 + // add here for more protocols
57543 + // statistics
57544 + size = ROUND_UP(size,4);
57545 + of->stats = size;
57546 + size += sizeof(t_ArStatistics);
57547 + return size;
57548 +}
57549 +
57550 +uint32_t* ARDesc;
57551 +void PrsEnable(t_Handle p_FmPcd);
57552 +void PrsDisable(t_Handle p_FmPcd);
57553 +int PrsIsEnabled(t_Handle p_FmPcd);
57554 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57555 +
57556 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57557 + t_FmPortDsarTablesSizes *sizes)
57558 +{
57559 + bool macInit = FALSE;
57560 + uint8_t mac[6];
57561 + int i = 0;
57562 +
57563 + // check table sizes
57564 + if (params->p_AutoResArpInfo
57565 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57566 + RETURN_ERROR(
57567 + MAJOR, E_INVALID_VALUE,
57568 + ("DSAR: Arp table size exceeds the configured maximum size."));
57569 + if (params->p_AutoResEchoIpv4Info
57570 + && sizes->maxNumOfEchoIpv4Entries
57571 + < params->p_AutoResEchoIpv4Info->tableSize)
57572 + RETURN_ERROR(
57573 + MAJOR,
57574 + E_INVALID_VALUE,
57575 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57576 + if (params->p_AutoResNdpInfo
57577 + && sizes->maxNumOfNdpEntries
57578 + < params->p_AutoResNdpInfo->tableSizeAssigned
57579 + + params->p_AutoResNdpInfo->tableSizeTmp)
57580 + RETURN_ERROR(
57581 + MAJOR, E_INVALID_VALUE,
57582 + ("DSAR: NDP table size exceeds the configured maximum size."));
57583 + if (params->p_AutoResEchoIpv6Info
57584 + && sizes->maxNumOfEchoIpv6Entries
57585 + < params->p_AutoResEchoIpv6Info->tableSize)
57586 + RETURN_ERROR(
57587 + MAJOR,
57588 + E_INVALID_VALUE,
57589 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57590 + if (params->p_AutoResSnmpInfo
57591 + && sizes->maxNumOfSnmpOidEntries
57592 + < params->p_AutoResSnmpInfo->oidsTblSize)
57593 + RETURN_ERROR(
57594 + MAJOR,
57595 + E_INVALID_VALUE,
57596 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57597 + if (params->p_AutoResSnmpInfo
57598 + && sizes->maxNumOfSnmpIPV4Entries
57599 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57600 + RETURN_ERROR(
57601 + MAJOR,
57602 + E_INVALID_VALUE,
57603 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57604 + if (params->p_AutoResSnmpInfo
57605 + && sizes->maxNumOfSnmpIPV6Entries
57606 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57607 + RETURN_ERROR(
57608 + MAJOR,
57609 + E_INVALID_VALUE,
57610 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57611 + if (params->p_AutoResFilteringInfo)
57612 + {
57613 + if (sizes->maxNumOfIpProtFiltering
57614 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57615 + RETURN_ERROR(
57616 + MAJOR,
57617 + E_INVALID_VALUE,
57618 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57619 + if (sizes->maxNumOfTcpPortFiltering
57620 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57621 + RETURN_ERROR(
57622 + MAJOR,
57623 + E_INVALID_VALUE,
57624 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57625 + if (sizes->maxNumOfUdpPortFiltering
57626 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57627 + RETURN_ERROR(
57628 + MAJOR,
57629 + E_INVALID_VALUE,
57630 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57631 + }
57632 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57633 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57634 + {
57635 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57636 + i = 1;
57637 + macInit = TRUE;
57638 +
57639 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57640 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57641 + RETURN_ERROR(
57642 + MAJOR, E_INVALID_VALUE,
57643 + ("DSAR: Only 1 mac address is currently supported."));
57644 + }
57645 + if (params->p_AutoResEchoIpv4Info
57646 + && params->p_AutoResEchoIpv4Info->tableSize)
57647 + {
57648 + i = 0;
57649 + if (!macInit)
57650 + {
57651 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57652 + 6);
57653 + i = 1;
57654 + macInit = TRUE;
57655 + }
57656 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57657 + if (memcmp(mac,
57658 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57659 + RETURN_ERROR(
57660 + MAJOR, E_INVALID_VALUE,
57661 + ("DSAR: Only 1 mac address is currently supported."));
57662 + }
57663 + if (params->p_AutoResEchoIpv6Info
57664 + && params->p_AutoResEchoIpv6Info->tableSize)
57665 + {
57666 + i = 0;
57667 + if (!macInit)
57668 + {
57669 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57670 + 6);
57671 + i = 1;
57672 + macInit = TRUE;
57673 + }
57674 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57675 + if (memcmp(mac,
57676 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57677 + RETURN_ERROR(
57678 + MAJOR, E_INVALID_VALUE,
57679 + ("DSAR: Only 1 mac address is currently supported."));
57680 + }
57681 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57682 + {
57683 + i = 0;
57684 + if (!macInit)
57685 + {
57686 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57687 + 6);
57688 + i = 1;
57689 + macInit = TRUE;
57690 + }
57691 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57692 + if (memcmp(mac,
57693 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57694 + 6))
57695 + RETURN_ERROR(
57696 + MAJOR, E_INVALID_VALUE,
57697 + ("DSAR: Only 1 mac address is currently supported."));
57698 + }
57699 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57700 + {
57701 + i = 0;
57702 + if (!macInit)
57703 + {
57704 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57705 + i = 1;
57706 + }
57707 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57708 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57709 + 6))
57710 + RETURN_ERROR(
57711 + MAJOR, E_INVALID_VALUE,
57712 + ("DSAR: Only 1 mac address is currently supported."));
57713 + }
57714 + return E_OK;
57715 +}
57716 +
57717 +static int GetBERLen(uint8_t* buf)
57718 +{
57719 + if (*buf & 0x80)
57720 + {
57721 + if ((*buf & 0x7F) == 1)
57722 + return buf[1];
57723 + else
57724 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57725 + }
57726 + else
57727 + return buf[0];
57728 +}
57729 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57730 +
57731 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57732 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57733 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57734 +static int fm_soc_suspend(void)
57735 +{
57736 + uint32_t *fmclk, tmp32;
57737 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57738 + tmp32 = GET_UINT32(*fmclk);
57739 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57740 + tmp32 = GET_UINT32(*fmclk);
57741 + iounmap(fmclk);
57742 + return 0;
57743 +}
57744 +
57745 +void fm_clk_down(void)
57746 +{
57747 + uint32_t *fmclk, tmp32;
57748 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57749 + tmp32 = GET_UINT32(*fmclk);
57750 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57751 + tmp32 = GET_UINT32(*fmclk);
57752 + iounmap(fmclk);
57753 +}
57754 +
57755 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57756 +{
57757 + int i, j;
57758 + t_Error err;
57759 + uint32_t nia;
57760 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57761 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57762 + t_DsarArpDescriptor *ArpDescriptor;
57763 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57764 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57765 + t_DsarNdDescriptor* NDDescriptor;
57766 +
57767 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57768 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57769 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57770 + struct arOffsets* of;
57771 + uint8_t tmp = 0;
57772 + t_FmGetSetParams fmGetSetParams;
57773 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57774 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57775 + fmGetSetParams.setParams.sleep = 1;
57776 +
57777 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57778 + if (err != E_OK)
57779 + return err;
57780 +
57781 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57782 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57783 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57784 +
57785 + // common
57786 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57787 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57788 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57789 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57790 + else
57791 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57792 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57793 +
57794 + // ARP
57795 + if (params->p_AutoResArpInfo)
57796 + {
57797 + t_DsarArpBindingEntry* arp_bindings;
57798 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57799 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57800 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57801 + if (params->p_AutoResArpInfo->enableConflictDetection)
57802 + WRITE_UINT16(ArpDescriptor->control, 1);
57803 + else
57804 + WRITE_UINT16(ArpDescriptor->control, 0);
57805 + if (params->p_AutoResArpInfo->tableSize)
57806 + {
57807 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57808 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57809 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57810 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57811 +
57812 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57813 + {
57814 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57815 + if (arp_entry[i].isVlan)
57816 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57817 + }
57818 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57819 + }
57820 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57821 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57822 + }
57823 +
57824 + // ICMPV4
57825 + if (params->p_AutoResEchoIpv4Info)
57826 + {
57827 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57828 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57829 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57830 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57831 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57832 + if (params->p_AutoResEchoIpv4Info->tableSize)
57833 + {
57834 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57835 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57836 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57837 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57838 +
57839 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57840 + {
57841 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57842 + if (arp_entry[i].isVlan)
57843 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57844 + }
57845 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57846 + }
57847 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57848 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57849 + }
57850 +
57851 + // ICMPV6
57852 + if (params->p_AutoResEchoIpv6Info)
57853 + {
57854 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57855 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57856 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57857 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57858 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57859 + if (params->p_AutoResEchoIpv6Info->tableSize)
57860 + {
57861 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57862 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57863 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57864 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57865 +
57866 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57867 + {
57868 + for (j = 0; j < 4; j++)
57869 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57870 + if (ndp_entry[i].isVlan)
57871 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57872 + }
57873 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57874 + }
57875 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
57876 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
57877 + }
57878 +
57879 + // ND
57880 + if (params->p_AutoResNdpInfo)
57881 + {
57882 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57883 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57884 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
57885 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
57886 + if (params->p_AutoResNdpInfo->enableConflictDetection)
57887 + WRITE_UINT16(NDDescriptor->control, 1);
57888 + else
57889 + WRITE_UINT16(NDDescriptor->control, 0);
57890 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57891 + {
57892 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
57893 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57894 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57895 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
57896 + + params->p_AutoResNdpInfo->tableSizeTmp);
57897 +
57898 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57899 + {
57900 + for (j = 0; j < 4; j++)
57901 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57902 + if (ndp_entry[i].isVlan)
57903 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57904 + }
57905 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
57906 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57907 + {
57908 + for (j = 0; j < 4; j++)
57909 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57910 + if (ndp_entry[i].isVlan)
57911 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57912 + }
57913 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57914 + }
57915 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
57916 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57917 + - fmMuramVirtBaseAddr);
57918 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
57919 + }
57920 +
57921 + // SNMP
57922 + if (params->p_AutoResSnmpInfo)
57923 + {
57924 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
57925 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
57926 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
57927 + t_OidsTblEntry* snmpOid;
57928 + uint8_t *charPointer;
57929 + int len;
57930 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
57931 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
57932 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
57933 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
57934 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
57935 + if (snmpSrc->numOfIpv4Addresses)
57936 + {
57937 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
57938 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
57939 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
57940 + {
57941 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
57942 + if (snmpIpv4AddrSrc[i].isVlan)
57943 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
57944 + }
57945 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
57946 + }
57947 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
57948 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
57949 + if (snmpSrc->numOfIpv6Addresses)
57950 + {
57951 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
57952 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
57953 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
57954 + {
57955 + for (j = 0; j < 4; j++)
57956 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
57957 + if (snmpIpv6AddrSrc[i].isVlan)
57958 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
57959 + }
57960 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
57961 + }
57962 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
57963 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
57964 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
57965 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
57966 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
57967 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
57968 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57969 + charPointer += len;
57970 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
57971 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
57972 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57973 + charPointer += len;
57974 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
57975 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
57976 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
57977 + {
57978 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
57979 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
57980 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
57981 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57982 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
57983 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
57984 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
57985 + else
57986 + {
57987 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
57988 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57989 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
57990 + }
57991 + snmpOid++;
57992 + }
57993 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
57994 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57995 + }
57996 +
57997 + // filtering
57998 + if (params->p_AutoResFilteringInfo)
57999 + {
58000 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
58001 + tmp |= IP_PROT_TBL_PASS_MASK;
58002 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
58003 + tmp |= UDP_PORT_TBL_PASS_MASK;
58004 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
58005 + tmp |= TCP_PORT_TBL_PASS_MASK;
58006 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
58007 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
58008 +
58009 + // ip filtering
58010 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
58011 + {
58012 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
58013 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
58014 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
58015 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
58016 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
58017 + }
58018 +
58019 + // udp filtering
58020 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
58021 + {
58022 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
58023 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
58024 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
58025 + {
58026 + WRITE_UINT32(udp_tbl[i].Ports,
58027 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
58028 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
58029 + WRITE_UINT32(udp_tbl[i].PortsMask,
58030 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
58031 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
58032 + }
58033 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
58034 + }
58035 +
58036 + // tcp filtering
58037 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
58038 + {
58039 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
58040 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
58041 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
58042 + {
58043 + WRITE_UINT32(tcp_tbl[i].Ports,
58044 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
58045 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
58046 + WRITE_UINT32(tcp_tbl[i].PortsMask,
58047 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
58048 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
58049 + }
58050 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
58051 + }
58052 + }
58053 + // common stats
58054 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
58055 +
58056 + // get into Deep Sleep sequence:
58057 +
58058 + // Ensures that FMan do not enter the idle state. This is done by programing
58059 + // FMDPSLPCR[FM_STOP] to one.
58060 + fm_soc_suspend();
58061 +
58062 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
58063 + return E_OK;
58064 +
58065 +}
58066 +
58067 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
58068 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
58069 +{
58070 + t_FmGetSetParams fmGetSetParams;
58071 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
58072 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
58073 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58074 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58075 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58076 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
58077 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58078 +
58079 + /* Issue graceful stop to HC port */
58080 + FM_PORT_Disable(p_FmPortHc);
58081 +
58082 + // config tx port
58083 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
58084 + 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);
58085 + // ????
58086 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
58087 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
58088 + // Stage 7:echo
58089 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
58090 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
58091 + if (!PrsIsEnabled(h_FmPcd))
58092 + {
58093 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
58094 + PrsEnable(h_FmPcd);
58095 + }
58096 + else
58097 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
58098 +
58099 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
58100 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
58101 +
58102 + // save rcfg for restoring: accumulate mode is changed by ucode
58103 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
58104 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
58105 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58106 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58107 + fmGetSetParams.setParams.sleep = 1;
58108 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58109 +
58110 +// ***** issue external request sync command
58111 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58112 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
58113 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58114 + // get
58115 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58116 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
58117 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58118 + if (fmGetSetParams.getParams.fmfp_extc != 0)
58119 + {
58120 + // clear
58121 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58122 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
58123 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58124 +}
58125 +
58126 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58127 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
58128 + do
58129 + {
58130 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58131 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
58132 + if (fmGetSetParams.getParams.fm_npi != 0)
58133 + XX_Print("FM: Sync did not finish\n");
58134 +
58135 + // check that all stoped
58136 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58137 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
58138 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58139 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
58140 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58141 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
58142 + XX_Print("FM: Sleeping\n");
58143 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
58144 +
58145 + return E_OK;
58146 +}
58147 +
58148 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
58149 +
58150 +void FM_PORT_Dsar_DumpRegs()
58151 +{
58152 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
58153 + DUMP_MEMORY(hh, 0x220);
58154 +}
58155 +
58156 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
58157 +{
58158 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58159 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
58160 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58161 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58162 + t_FmGetSetParams fmGetSetParams;
58163 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58164 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58165 + fmGetSetParams.setParams.sleep = 0;
58166 + if (p_FmPort->deepSleepVars.autoResOffsets)
58167 + {
58168 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
58169 + p_FmPort->deepSleepVars.autoResOffsets = 0;
58170 + }
58171 +
58172 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
58173 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
58174 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
58175 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
58176 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
58177 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58178 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
58179 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
58180 + FM_PORT_Enable(p_FmPortHc);
58181 +}
58182 +
58183 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
58184 +{
58185 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
58186 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
58187 +}
58188 +
58189 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
58190 +{
58191 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58192 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
58193 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
58194 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58195 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
58196 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
58197 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58198 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
58199 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58200 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58201 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58202 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
58203 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58204 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58205 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58206 + stats->arpArCnt = arp_stats->arCnt;
58207 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
58208 + stats->ndpArCnt = nd_stats->arCnt;
58209 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
58210 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
58211 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
58212 + return E_OK;
58213 +}
58214 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58215 new file mode 100644
58216 index 00000000..85986f55
58217 --- /dev/null
58218 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58219 @@ -0,0 +1,999 @@
58220 +/*
58221 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58222 + *
58223 + * Redistribution and use in source and binary forms, with or without
58224 + * modification, are permitted provided that the following conditions are met:
58225 + * * Redistributions of source code must retain the above copyright
58226 + * notice, this list of conditions and the following disclaimer.
58227 + * * Redistributions in binary form must reproduce the above copyright
58228 + * notice, this list of conditions and the following disclaimer in the
58229 + * documentation and/or other materials provided with the distribution.
58230 + * * Neither the name of Freescale Semiconductor nor the
58231 + * names of its contributors may be used to endorse or promote products
58232 + * derived from this software without specific prior written permission.
58233 + *
58234 + *
58235 + * ALTERNATIVELY, this software may be distributed under the terms of the
58236 + * GNU General Public License ("GPL") as published by the Free Software
58237 + * Foundation, either version 2 of that License or (at your option) any
58238 + * later version.
58239 + *
58240 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58241 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58242 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58243 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
58244 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58245 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58246 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58247 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58248 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58249 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58250 + */
58251 +
58252 +
58253 +/******************************************************************************
58254 + @File fm_port.h
58255 +
58256 + @Description FM Port internal structures and definitions.
58257 +*//***************************************************************************/
58258 +#ifndef __FM_PORT_H
58259 +#define __FM_PORT_H
58260 +
58261 +#include "error_ext.h"
58262 +#include "std_ext.h"
58263 +#include "fm_port_ext.h"
58264 +
58265 +#include "fm_common.h"
58266 +#include "fm_sp_common.h"
58267 +#include "fsl_fman_sp.h"
58268 +#include "fm_port_ext.h"
58269 +#include "fsl_fman_port.h"
58270 +
58271 +#define __ERR_MODULE__ MODULE_FM_PORT
58272 +
58273 +
58274 +#define MIN_EXT_BUF_SIZE 64
58275 +#define DATA_ALIGNMENT 64
58276 +#define MAX_LIODN_OFFSET 64
58277 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58278 +
58279 +/**************************************************************************//**
58280 + @Description Memory Map defines
58281 +*//***************************************************************************/
58282 +#define BMI_PORT_REGS_OFFSET 0
58283 +#define QMI_PORT_REGS_OFFSET 0x400
58284 +#define PRS_PORT_REGS_OFFSET 0x800
58285 +
58286 +/**************************************************************************//**
58287 + @Description defaults
58288 +*//***************************************************************************/
58289 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58290 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58291 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58292 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58293 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58294 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58295 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58296 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58297 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58298 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58299 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58300 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58301 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58302 +#define DEFAULT_PORT_cutBytesFromEnd 4
58303 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58304 +
58305 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58306 +
58307 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58308 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58309 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58310 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58311 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58312 +
58313 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58314 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58315 +#define DEFAULT_PORT_BufMargins_startMargins 32
58316 +#define DEFAULT_PORT_BufMargins_endMargins 0
58317 +#define DEFAULT_PORT_syncReq TRUE
58318 +#define DEFAULT_PORT_syncReqForHc FALSE
58319 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58320 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58321 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58322 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58323 +#define DEFAULT_PORT_exception IM_EV_BSY
58324 +#define DEFAULT_PORT_maxFrameLength 9600
58325 +
58326 +#define DEFAULT_notSupported 0xff
58327 +
58328 +#if (DPAA_VERSION < 11)
58329 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58330 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58331 +
58332 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58333 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58334 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58335 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58336 +
58337 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58338 +
58339 +/* Host command port MUST NOT be changed to more than 1 !!! */
58340 +#define DEFAULT_PORT_numOfTasks(type) \
58341 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58342 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58343 + ((((type) == e_FM_PORT_TYPE_RX) || \
58344 + ((type) == e_FM_PORT_TYPE_TX) || \
58345 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58346 +
58347 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58348 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58349 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58350 +
58351 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58352 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58353 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58354 +
58355 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58356 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58357 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58358 +
58359 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58360 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58361 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58362 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58363 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58364 +
58365 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58366 +
58367 +#else /* (DPAA_VERSION < 11) */
58368 +/* Defaults are registers' reset values */
58369 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58370 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58371 +
58372 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58373 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58374 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58375 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58376 +
58377 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58378 +
58379 +#define DEFAULT_PORT_numOfTasks(type) \
58380 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58381 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58382 + (((type) == e_FM_PORT_TYPE_RX) || \
58383 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58384 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58385 +
58386 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58387 +
58388 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58389 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58390 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58391 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58392 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58393 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58394 +
58395 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58396 +
58397 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58398 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58399 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58400 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58401 +
58402 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58403 +
58404 +#endif /* (DPAA_VERSION < 11) */
58405 +
58406 +#define DEFAULT_PORT_txBdRingLength 16
58407 +#define DEFAULT_PORT_rxBdRingLength 128
58408 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58409 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58410 +
58411 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58412 +
58413 +/**************************************************************************//**
58414 + @Collection PCD Engines
58415 +*//***************************************************************************/
58416 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58417 +
58418 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58419 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58420 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58421 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58422 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58423 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58424 +/* @} */
58425 +
58426 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58427 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58428 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58429 +
58430 +#define FM_OH_PORT_ID 0
58431 +
58432 +/***********************************************************************/
58433 +/* SW parser OFFLOAD labels (offsets) */
58434 +/***********************************************************************/
58435 +#if (DPAA_VERSION == 10)
58436 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58437 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58438 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58439 +#else
58440 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58441 +/* Will be used for:
58442 + * 1. identify fragments
58443 + * 2. udp-lite
58444 + */
58445 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58446 +/* Will be used for:
58447 + * 1. will identify the fragmentable area
58448 + * 2. udp-lite
58449 + */
58450 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58451 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58452 +#endif /* (DPAA_VERSION == 10) */
58453 +
58454 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58455 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58456 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58457 +
58458 +
58459 +/**************************************************************************//**
58460 + @Description Memory Mapped Registers
58461 +*//***************************************************************************/
58462 +
58463 +#if defined(__MWERKS__) && !defined(__GNUC__)
58464 +#pragma pack(push,1)
58465 +#endif /* defined(__MWERKS__) && ... */
58466 +
58467 +typedef struct
58468 +{
58469 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58470 + volatile uint32_t fmbm_rst; /**< Rx Status */
58471 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58472 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58473 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58474 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58475 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58476 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58477 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58478 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58479 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58480 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58481 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58482 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58483 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58484 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58485 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58486 + /**< Rx Parse Results Array Initialization*/
58487 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58488 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58489 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58490 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58491 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58492 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58493 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58494 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58495 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58496 + /**< Buffer Manager pool Information-*/
58497 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58498 + /**< Allocate Counter-*/
58499 + volatile uint32_t reserved4[0x08];
58500 + /**< 0x130/0x140 - 0x15F reserved -*/
58501 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58502 + /**< Congestion Group Map*/
58503 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58504 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58505 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58506 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58507 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58508 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58509 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58510 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58511 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58512 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58513 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58514 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58515 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58516 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58517 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58518 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58519 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58520 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58521 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58522 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58523 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58524 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58525 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58526 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58527 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58528 +} t_FmPortRxBmiRegs;
58529 +
58530 +typedef struct
58531 +{
58532 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58533 + volatile uint32_t fmbm_tst; /**< Tx Status */
58534 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58535 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58536 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58537 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58538 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58539 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58540 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58541 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58542 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58543 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58544 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58545 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58546 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58547 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58548 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58549 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58550 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58551 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58552 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58553 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58554 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58555 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58556 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58557 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58558 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58559 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58560 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58561 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58562 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58563 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58564 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58565 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58566 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58567 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58568 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58569 +} t_FmPortTxBmiRegs;
58570 +
58571 +typedef struct
58572 +{
58573 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58574 + volatile uint32_t fmbm_ost; /**< O/H Status */
58575 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58576 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58577 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58578 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58579 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58580 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58581 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58582 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58583 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58584 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58585 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58586 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58587 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58588 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58589 + /**< O/H Parse Results Array Initialization */
58590 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58591 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58592 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58593 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58594 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58595 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58596 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58597 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58598 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58599 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58600 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58601 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58602 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58603 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58604 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58605 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58606 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58607 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58608 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58609 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58610 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58611 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58612 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58613 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58614 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58615 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58616 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58617 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58618 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58619 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58620 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58621 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58622 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58623 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58624 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58625 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58626 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58627 +} t_FmPortOhBmiRegs;
58628 +
58629 +typedef union
58630 +{
58631 + t_FmPortRxBmiRegs rxPortBmiRegs;
58632 + t_FmPortTxBmiRegs txPortBmiRegs;
58633 + t_FmPortOhBmiRegs ohPortBmiRegs;
58634 +} u_FmPortBmiRegs;
58635 +
58636 +typedef struct
58637 +{
58638 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58639 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58640 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58641 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58642 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58643 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58644 +} t_FmPortNonRxQmiRegs;
58645 +
58646 +typedef struct
58647 +{
58648 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58649 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58650 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58651 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58652 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58653 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58654 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58655 +} t_FmPortQmiRegs;
58656 +
58657 +typedef struct
58658 +{
58659 + struct
58660 + {
58661 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58662 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58663 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58664 + volatile uint32_t reserved0[0xde];
58665 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58666 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58667 +} t_FmPortPrsRegs;
58668 +
58669 +/**************************************************************************//*
58670 + @Description Basic buffer descriptor (BD) structure
58671 +*//***************************************************************************/
58672 +typedef _Packed struct
58673 +{
58674 + volatile uint16_t status;
58675 + volatile uint16_t length;
58676 + volatile uint8_t reserved0[0x6];
58677 + volatile uint8_t reserved1[0x1];
58678 + volatile t_FmPhysAddr buff;
58679 +} _PackedType t_FmImBd;
58680 +
58681 +typedef _Packed struct
58682 +{
58683 + volatile uint16_t gen; /**< tbd */
58684 + volatile uint8_t reserved0[0x1];
58685 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58686 + volatile uint16_t bdRingSize; /**< tbd */
58687 + volatile uint16_t offsetIn; /**< tbd */
58688 + volatile uint16_t offsetOut; /**< tbd */
58689 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58690 +} _PackedType t_FmPortImQd;
58691 +
58692 +typedef _Packed struct
58693 +{
58694 + volatile uint32_t mode; /**< Mode register */
58695 + volatile uint32_t rxQdPtr; /**< tbd */
58696 + volatile uint32_t txQdPtr; /**< tbd */
58697 + volatile uint16_t mrblr; /**< tbd */
58698 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58699 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58700 + t_FmPortImQd rxQd;
58701 + t_FmPortImQd txQd;
58702 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58703 +} _PackedType t_FmPortImPram;
58704 +
58705 +#if defined(__MWERKS__) && !defined(__GNUC__)
58706 +#pragma pack(pop)
58707 +#endif /* defined(__MWERKS__) && ... */
58708 +
58709 +
58710 +/**************************************************************************//**
58711 + @Description Registers bit fields
58712 +*//***************************************************************************/
58713 +
58714 +/**************************************************************************//**
58715 + @Description BMI defines
58716 +*//***************************************************************************/
58717 +#if (DPAA_VERSION >= 11)
58718 +#define BMI_SP_ID_MASK 0xff000000
58719 +#define BMI_SP_ID_SHIFT 24
58720 +#define BMI_SP_EN 0x01000000
58721 +#endif /* (DPAA_VERSION >= 11) */
58722 +
58723 +#define BMI_PORT_CFG_EN 0x80000000
58724 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58725 +#define BMI_PORT_CFG_FDOVR 0x02000000
58726 +#define BMI_PORT_CFG_IM 0x01000000
58727 +#define BMI_PORT_CFG_AM 0x00000040
58728 +#define BMI_PORT_STATUS_BSY 0x80000000
58729 +#define BMI_COUNTERS_EN 0x80000000
58730 +
58731 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58732 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58733 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58734 +#define BMI_RFNE_HXS_MASK 0x000000FF
58735 +
58736 +#define BMI_CMD_MR_LEAC 0x00200000
58737 +#define BMI_CMD_MR_SLEAC 0x00100000
58738 +#define BMI_CMD_MR_MA 0x00080000
58739 +#define BMI_CMD_MR_DEAS 0x00040000
58740 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58741 + BMI_CMD_MR_SLEAC | \
58742 + BMI_CMD_MR_MA | \
58743 + BMI_CMD_MR_DEAS)
58744 +#define BMI_CMD_ATTR_ORDER 0x80000000
58745 +#define BMI_CMD_ATTR_SYNC 0x02000000
58746 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58747 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58748 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58749 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58750 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58751 +
58752 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58753 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58754 + FM_PORT_FRM_ERR_PHYSICAL | \
58755 + FM_PORT_FRM_ERR_SIZE | \
58756 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58757 + FM_PORT_FRM_ERR_EXTRACTION | \
58758 + FM_PORT_FRM_ERR_NO_SCHEME | \
58759 + FM_PORT_FRM_ERR_COLOR_RED | \
58760 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58761 + FM_PORT_FRM_ERR_ILL_PLCR | \
58762 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58763 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58764 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58765 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58766 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58767 + FM_PORT_FRM_ERR_IPRE | \
58768 + FM_PORT_FRM_ERR_IPR_NCSP | \
58769 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58770 +
58771 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58772 + ~(FM_PORT_FRM_ERR_LENGTH | \
58773 + FM_PORT_FRM_ERR_NON_FM | \
58774 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58775 +
58776 +#define BMI_RATE_LIMIT_EN 0x80000000
58777 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58778 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58779 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58780 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58781 +
58782 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58783 +
58784 +#define BMI_PRS_RESULT_HIGH 0x00000000
58785 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58786 +
58787 +
58788 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58789 + FM_PORT_FRM_ERR_PHYSICAL | \
58790 + FM_PORT_FRM_ERR_SIZE | \
58791 + FM_PORT_FRM_ERR_EXTRACTION | \
58792 + FM_PORT_FRM_ERR_NO_SCHEME | \
58793 + FM_PORT_FRM_ERR_ILL_PLCR | \
58794 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58795 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58796 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58797 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58798 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58799 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58800 + FM_PORT_FRM_ERR_IPRE)
58801 +
58802 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58803 + FM_PORT_FRM_ERR_LENGTH | \
58804 + FM_PORT_FRM_ERR_NON_FM | \
58805 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58806 +
58807 +
58808 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58809 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58810 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58811 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58812 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58813 +
58814 +/* shifts */
58815 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58816 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58817 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58818 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58819 +
58820 +#define BMI_IM_FOF_SHIFT 28
58821 +#define BMI_PR_PORTID_SHIFT 24
58822 +
58823 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58824 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58825 +
58826 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58827 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58828 +
58829 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58830 +
58831 +#define BMI_INT_BUF_MARG_SHIFT 28
58832 +
58833 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58834 +
58835 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58836 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58837 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58838 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58839 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58840 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58841 +
58842 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58843 +
58844 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58845 +#define BMI_TX_LOW_COMF_SHIFT 0
58846 +
58847 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58848 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58849 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58850 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58851 +
58852 +#define BMI_MAX_BURST_SHIFT 16
58853 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58854 +
58855 +/* sizes */
58856 +#define FRAME_END_DATA_SIZE 16
58857 +#define FRAME_OFFSET_UNITS 16
58858 +#define MIN_TX_INT_OFFSET 16
58859 +#define MAX_FRAME_OFFSET 64
58860 +#define MAX_FIFO_PIPELINE_DEPTH 8
58861 +#define MAX_PERFORMANCE_TASK_COMP 64
58862 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58863 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58864 +#define MAX_PERFORMANCE_DMA_COMP 16
58865 +#define MAX_NUM_OF_TASKS 64
58866 +#define MAX_NUM_OF_EXTRA_TASKS 8
58867 +#define MAX_NUM_OF_DMAS 16
58868 +#define MAX_NUM_OF_EXTRA_DMAS 8
58869 +#define MAX_BURST_SIZE 1024
58870 +#define MIN_NUM_OF_OP_DMAS 2
58871 +
58872 +
58873 +/**************************************************************************//**
58874 + @Description QMI defines
58875 +*//***************************************************************************/
58876 +/* masks */
58877 +#define QMI_PORT_CFG_EN 0x80000000
58878 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
58879 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
58880 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
58881 +
58882 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
58883 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
58884 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
58885 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
58886 +
58887 +#define QMI_DEQ_CFG_PRI 0x80000000
58888 +#define QMI_DEQ_CFG_TYPE1 0x10000000
58889 +#define QMI_DEQ_CFG_TYPE2 0x20000000
58890 +#define QMI_DEQ_CFG_TYPE3 0x30000000
58891 +
58892 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
58893 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
58894 +
58895 +/**************************************************************************//**
58896 + @Description PARSER defines
58897 +*//***************************************************************************/
58898 +/* masks */
58899 +#define PRS_HDR_ERROR_DIS 0x00000800
58900 +#define PRS_HDR_SW_PRS_EN 0x00000400
58901 +#define PRS_CP_OFFSET_MASK 0x0000000F
58902 +#define PRS_TPID1_MASK 0xFFFF0000
58903 +#define PRS_TPID2_MASK 0x0000FFFF
58904 +#define PRS_TPID_DFLT 0x91009100
58905 +
58906 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
58907 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
58908 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
58909 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
58910 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
58911 +#define PRS_CAC_STOP 0x00000001
58912 +#define PRS_CAC_ACTIVE 0x00000100
58913 +
58914 +/* shifts */
58915 +#define PRS_PCTPID_SHIFT 16
58916 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
58917 +#define PRS_HDR_ETH_BC_SHIFT 28
58918 +#define PRS_HDR_ETH_MC_SHIFT 24
58919 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
58920 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
58921 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
58922 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
58923 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
58924 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
58925 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
58926 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
58927 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
58928 +
58929 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
58930 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
58931 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
58932 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
58933 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
58934 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
58935 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
58936 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
58937 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
58938 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
58939 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
58940 +
58941 +/* others */
58942 +#define PRS_HDR_ENTRY_SIZE 8
58943 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
58944 +
58945 +#define IPSEC_SW_PATCH_START 0x20
58946 +#define SCTP_SW_PATCH_START 0x4D
58947 +#define DCCP_SW_PATCH_START 0x41
58948 +
58949 +/**************************************************************************//**
58950 + @Description IM defines
58951 +*//***************************************************************************/
58952 +#define BD_R_E 0x80000000
58953 +#define BD_L 0x08000000
58954 +
58955 +#define BD_RX_CRE 0x00080000
58956 +#define BD_RX_FTL 0x00040000
58957 +#define BD_RX_FTS 0x00020000
58958 +#define BD_RX_OV 0x00010000
58959 +
58960 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
58961 +
58962 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
58963 +
58964 +#define BD_STATUS_MASK 0xffff0000
58965 +#define BD_LENGTH_MASK 0x0000ffff
58966 +
58967 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
58968 +
58969 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
58970 +
58971 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
58972 +
58973 +#define IM_ILEGAL_BD_ID 0xffff
58974 +
58975 +/* others */
58976 +#define IM_PRAM_ALIGN 0x100
58977 +
58978 +/* masks */
58979 +#define IM_MODE_GBL 0x20000000
58980 +#define IM_MODE_BO_MASK 0x18000000
58981 +#define IM_MODE_BO_SHIFT 3
58982 +#define IM_MODE_GRC_STP 0x00800000
58983 +
58984 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
58985 +
58986 +#define IM_RXQD_BSYINTM 0x0008
58987 +#define IM_RXQD_RXFINTM 0x0010
58988 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
58989 +
58990 +#define IM_EV_BSY 0x40000000
58991 +#define IM_EV_RX 0x80000000
58992 +
58993 +
58994 +/**************************************************************************//**
58995 + @Description Additional defines
58996 +*//***************************************************************************/
58997 +
58998 +typedef struct {
58999 + t_Handle h_FmMuram;
59000 + t_FmPortImPram *p_FmPortImPram;
59001 + uint8_t fwExtStructsMemId;
59002 + uint32_t fwExtStructsMemAttr;
59003 + uint16_t bdRingSize;
59004 + t_FmImBd *p_BdRing;
59005 + t_Handle *p_BdShadow;
59006 + uint16_t currBdId;
59007 + uint16_t firstBdOfFrameId;
59008 +
59009 + /* Rx port parameters */
59010 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
59011 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
59012 + t_BufferPoolInfo rxPool;
59013 + uint16_t mrblr;
59014 + uint16_t rxFrameAccumLength;
59015 + t_FmPortImRxStoreCallback *f_RxStore;
59016 +
59017 + /* Tx port parameters */
59018 + uint32_t txFirstBdStatus;
59019 + t_FmPortImTxConfCallback *f_TxConf;
59020 +} t_FmMacIm;
59021 +
59022 +
59023 +typedef struct {
59024 + struct fman_port_cfg dfltCfg;
59025 + uint32_t dfltFqid;
59026 + uint32_t confFqid;
59027 + uint32_t errFqid;
59028 + uintptr_t baseAddr;
59029 + uint8_t deqSubPortal;
59030 + bool deqHighPriority;
59031 + e_FmPortDeqType deqType;
59032 + e_FmPortDeqPrefetchOption deqPrefetchOption;
59033 + uint16_t deqByteCnt;
59034 + uint8_t cheksumLastBytesIgnore;
59035 + uint8_t cutBytesFromEnd;
59036 + t_FmBufPoolDepletion bufPoolDepletion;
59037 + uint8_t pipelineDepth;
59038 + uint16_t fifoLowComfLevel;
59039 + bool frmDiscardOverride;
59040 + bool enRateLimit;
59041 + t_FmPortRateLimit rateLimit;
59042 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
59043 + bool enBufPoolDepletion;
59044 + uint16_t liodnOffset;
59045 + uint16_t liodnBase;
59046 + t_FmExtPools extBufPools;
59047 + e_FmDmaSwapOption dmaSwapData;
59048 + e_FmDmaCacheOption dmaIntContextCacheAttr;
59049 + e_FmDmaCacheOption dmaHeaderCacheAttr;
59050 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
59051 + bool dmaReadOptimize;
59052 + bool dmaWriteOptimize;
59053 + uint32_t txFifoMinFillLevel;
59054 + uint32_t txFifoLowComfLevel;
59055 + uint32_t rxFifoPriElevationLevel;
59056 + uint32_t rxFifoThreshold;
59057 + t_FmSpBufMargins bufMargins;
59058 + t_FmSpIntContextDataCopy intContext;
59059 + bool syncReq;
59060 + e_FmPortColor color;
59061 + fmPortFrameErrSelect_t errorsToDiscard;
59062 + fmPortFrameErrSelect_t errorsToEnq;
59063 + bool forwardReuseIntContext;
59064 + t_FmBufferPrefixContent bufferPrefixContent;
59065 + t_FmBackupBmPools *p_BackupBmPools;
59066 + bool dontReleaseBuf;
59067 + bool setNumOfTasks;
59068 + bool setNumOfOpenDmas;
59069 + bool setSizeOfFifo;
59070 +#if (DPAA_VERSION >= 11)
59071 + bool noScatherGather;
59072 +#endif /* (DPAA_VERSION >= 11) */
59073 +
59074 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
59075 + bool bcbWorkaround;
59076 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
59077 +} t_FmPortDriverParam;
59078 +
59079 +
59080 +typedef struct t_FmPortRxPoolsParams
59081 +{
59082 + uint8_t numOfPools;
59083 + uint16_t secondLargestBufSize;
59084 + uint16_t largestBufSize;
59085 +} t_FmPortRxPoolsParams;
59086 +
59087 +typedef struct t_FmPortDsarVars {
59088 + t_Handle *autoResOffsets;
59089 + t_FmPortDsarTablesSizes *autoResMaxSizes;
59090 + uint32_t fmbm_tcfg;
59091 + uint32_t fmbm_tcmne;
59092 + uint32_t fmbm_rfne;
59093 + uint32_t fmbm_rfpne;
59094 + uint32_t fmbm_rcfg;
59095 + bool dsarEnabledParser;
59096 +} t_FmPortDsarVars;
59097 +typedef struct {
59098 + struct fman_port port;
59099 + t_Handle h_Fm;
59100 + t_Handle h_FmPcd;
59101 + t_Handle h_FmMuram;
59102 + t_FmRevisionInfo fmRevInfo;
59103 + uint8_t portId;
59104 + e_FmPortType portType;
59105 + int enabled;
59106 + char name[MODULE_NAME_SIZE];
59107 + uint8_t hardwarePortId;
59108 + uint16_t fmClkFreq;
59109 + t_FmPortQmiRegs *p_FmPortQmiRegs;
59110 + u_FmPortBmiRegs *p_FmPortBmiRegs;
59111 + t_FmPortPrsRegs *p_FmPortPrsRegs;
59112 + fmPcdEngines_t pcdEngines;
59113 + uint32_t savedBmiNia;
59114 + uint8_t netEnvId;
59115 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
59116 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
59117 + uint8_t privateInfo;
59118 + uint32_t schemesPerPortVector;
59119 + bool useClsPlan;
59120 + uint8_t clsPlanGrpId;
59121 + t_Handle ccTreeId;
59122 + t_Handle completeArg;
59123 + void (*f_Complete)(t_Handle arg);
59124 + t_FmSpBufferOffsets bufferOffsets;
59125 + /* Independent-Mode parameters support */
59126 + bool imEn;
59127 + t_FmMacIm im;
59128 + volatile bool lock;
59129 + t_Handle h_Spinlock;
59130 + t_FmPortExceptionCallback *f_Exception;
59131 + t_Handle h_App;
59132 + uint8_t internalBufferOffset;
59133 + uint8_t fmanCtrlEventId;
59134 + uint32_t exceptions;
59135 + bool polling;
59136 + t_FmExtPools extBufPools;
59137 + uint32_t requiredAction;
59138 + uint32_t savedQmiPnen;
59139 + uint32_t savedBmiFene;
59140 + uint32_t savedBmiFpne;
59141 + uint32_t savedBmiCmne;
59142 + uint32_t savedBmiOfp;
59143 + uint32_t savedNonRxQmiRegsPndn;
59144 + uint32_t origNonRxQmiRegsPndn;
59145 + int savedPrsStartOffset;
59146 + bool includeInPrsStatistics;
59147 + uint16_t maxFrameLength;
59148 + t_FmFmanCtrl orFmanCtrl;
59149 + t_FmPortRsrc openDmas;
59150 + t_FmPortRsrc tasks;
59151 + t_FmPortRsrc fifoBufs;
59152 + t_FmPortRxPoolsParams rxPoolsParams;
59153 +// bool explicitUserSizeOfFifo;
59154 + t_Handle h_IpReassemblyManip;
59155 + t_Handle h_CapwapReassemblyManip;
59156 + t_Handle h_ReassemblyTree;
59157 + uint64_t fmMuramPhysBaseAddr;
59158 +#if (DPAA_VERSION >= 11)
59159 + bool vspe;
59160 + uint8_t dfltRelativeId;
59161 + e_FmPortGprFuncType gprFunc;
59162 + t_FmPcdCtrlParamsPage *p_ParamsPage;
59163 +#endif /* (DPAA_VERSION >= 11) */
59164 + t_FmPortDsarVars deepSleepVars;
59165 + t_FmPortDriverParam *p_FmPortDriverParam;
59166 +} t_FmPort;
59167 +
59168 +
59169 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
59170 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
59171 +
59172 +t_Error FmPortImInit(t_FmPort *p_FmPort);
59173 +void FmPortImFree(t_FmPort *p_FmPort);
59174 +
59175 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
59176 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
59177 +t_Error FmPortImRx (t_FmPort *p_FmPort);
59178 +
59179 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
59180 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
59181 +
59182 +
59183 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
59184 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
59185 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
59186 +
59187 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
59188 +{
59189 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
59190 + physAddr |= GET_UINT32(p_Bd->buff.low);
59191 +
59192 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
59193 +}
59194 +
59195 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
59196 +{
59197 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
59198 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
59199 +}
59200 +
59201 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
59202 +{
59203 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
59204 + SET_ADDR(&p_Bd->buff, physAddr);
59205 +}
59206 +
59207 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
59208 +{
59209 + if (id < p_FmPort->im.bdRingSize-1)
59210 + return (uint16_t)(id+1);
59211 + else
59212 + return 0;
59213 +}
59214 +
59215 +void FM_PORT_Dsar_DumpRegs(void);
59216 +
59217 +
59218 +#endif /* __FM_PORT_H */
59219 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59220 new file mode 100755
59221 index 00000000..95619eff
59222 --- /dev/null
59223 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59224 @@ -0,0 +1,494 @@
59225 +/*
59226 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59227 + *
59228 + * Redistribution and use in source and binary forms, with or without
59229 + * modification, are permitted provided that the following conditions are met:
59230 + * * Redistributions of source code must retain the above copyright
59231 + * notice, this list of conditions and the following disclaimer.
59232 + * * Redistributions in binary form must reproduce the above copyright
59233 + * notice, this list of conditions and the following disclaimer in the
59234 + * documentation and/or other materials provided with the distribution.
59235 + * * Neither the name of Freescale Semiconductor nor the
59236 + * names of its contributors may be used to endorse or promote products
59237 + * derived from this software without specific prior written permission.
59238 + *
59239 + *
59240 + * ALTERNATIVELY, this software may be distributed under the terms of the
59241 + * GNU General Public License ("GPL") as published by the Free Software
59242 + * Foundation, either version 2 of that License or (at your option) any
59243 + * later version.
59244 + *
59245 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59246 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59247 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59248 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59249 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59250 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59251 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59252 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59253 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59254 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59255 + */
59256 +
59257 +/**************************************************************************//**
59258 + @File fm_port_dsar.h
59259 +
59260 + @Description Deep Sleep Auto Response project - common module header file.
59261 +
59262 + Author - Eyal Harari
59263 +
59264 + @Cautions See the FMan Controller spec and design document for more information.
59265 +*//***************************************************************************/
59266 +
59267 +#ifndef __FM_PORT_DSAR_H_
59268 +#define __FM_PORT_DSAR_H_
59269 +
59270 +#define DSAR_GETSER_MASK 0xFF0000FF
59271 +
59272 +#if defined(__MWERKS__) && !defined(__GNUC__)
59273 +#pragma pack(push,1)
59274 +#endif /* defined(__MWERKS__) && ... */
59275 +
59276 +/**************************************************************************//**
59277 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59278 + Refer to the FMan Controller spec for more details.
59279 +*//***************************************************************************/
59280 +typedef _Packed struct
59281 +{
59282 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59283 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59284 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59285 + uint16_t reserved;
59286 +} _PackedType t_DsarArpBindingEntry;
59287 +
59288 +/**************************************************************************//**
59289 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59290 + Refer to the FMan Controller spec for more details.
59291 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59292 + 0x04 ECHO_CNT Echo counter
59293 + 0x08 CD_CNT Conflict Detection counter
59294 + 0x0C AR_CNT Auto-Response counter
59295 + 0x10 RATM_CNT Replies Addressed To Me counter
59296 + 0x14 UKOP_CNT Unknown Operation counter
59297 + 0x18 NMTP_CNT Not my TPA counter
59298 + 0x1C NMVLAN_CNT Not My VLAN counter
59299 +*//***************************************************************************/
59300 +typedef _Packed struct
59301 +{
59302 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59303 + uint32_t echoCnt; /**< Echo counter. */
59304 + uint32_t cdCnt; /**< Conflict Detection counter. */
59305 + uint32_t arCnt; /**< Auto-Response counter. */
59306 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59307 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59308 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59309 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59310 +} _PackedType t_DsarArpStatistics;
59311 +
59312 +
59313 +/**************************************************************************//**
59314 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59315 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59316 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59317 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59318 + 0x6 0-15
59319 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59320 + 0xA 0-15
59321 + 0xC 0-15 Reserved Reserved. Must be cleared.
59322 + 0xE 015
59323 +
59324 +*//***************************************************************************/
59325 +typedef _Packed struct
59326 +{
59327 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59328 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59329 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59330 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59331 + uint32_t reserved1; /**< Reserved. */
59332 +} _PackedType t_DsarArpDescriptor;
59333 +
59334 +
59335 +/**************************************************************************//**
59336 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59337 + Refer to the FMan Controller spec for more details.
59338 +*//***************************************************************************/
59339 +typedef _Packed struct
59340 +{
59341 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59342 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59343 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59344 + uint16_t reserved;
59345 +} _PackedType t_DsarIcmpV4BindingEntry;
59346 +
59347 +/**************************************************************************//**
59348 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59349 + Refer to the FMan Controller spec for more details.
59350 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59351 + 0x04 NMVLAN_CNT Not My VLAN counter
59352 + 0x08 NMIP_CNT Not My IP counter
59353 + 0x0C AR_CNT Auto-Response counter
59354 + 0x10 CSERR_CNT Checksum Error counter
59355 + 0x14 Reserved Reserved
59356 + 0x18 Reserved Reserved
59357 + 0x1C Reserved Reserved
59358 +
59359 +*//***************************************************************************/
59360 +typedef _Packed struct
59361 +{
59362 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59363 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59364 + uint32_t nmIpCnt; /**< Not My IP counter */
59365 + uint32_t arCnt; /**< Auto-Response counter */
59366 + uint32_t cserrCnt; /**< Checksum Error counter */
59367 + uint32_t reserved0; /**< Reserved */
59368 + uint32_t reserved1; /**< Reserved */
59369 + uint32_t reserved2; /**< Reserved */
59370 +} _PackedType t_DsarIcmpV4Statistics;
59371 +
59372 +
59373 +
59374 +/**************************************************************************//**
59375 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59376 + 0x0 0-15 Control bits [0-15]
59377 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59378 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59379 + 0x6 0-15
59380 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59381 + 0xA 0-15
59382 + 0xC 0-15 Reserved Reserved. Must be cleared.
59383 + 0xE 015
59384 +
59385 +*//***************************************************************************/
59386 +typedef _Packed struct
59387 +{
59388 + uint16_t control; /** Control bits [0-15]. */
59389 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59390 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59391 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59392 + uint32_t reserved1; /**< Reserved. */
59393 +} _PackedType t_DsarIcmpV4Descriptor;
59394 +
59395 +/**************************************************************************//**
59396 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59397 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59398 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59399 + Flags[0] (VlanId[12]): Temporary address.
59400 + \95 0 - Assigned IP address.
59401 + \95 1- Temporary (tentative) IP address.
59402 + Refer to the FMan Controller spec for more details.
59403 +*//***************************************************************************/
59404 +typedef _Packed struct
59405 +{
59406 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59407 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59408 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59409 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59410 + uint16_t reserved;
59411 +} _PackedType t_DsarIcmpV6BindingEntry;
59412 +
59413 +/**************************************************************************//**
59414 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59415 + Refer to the FMan Controller spec for more details.
59416 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59417 + 0x04 NMVLAN_CNT Not My VLAN counter
59418 + 0x08 NMIP_CNT Not My IP counter
59419 + 0x0C AR_CNT Auto-Response counter
59420 + 0x10 CSERR_CNT Checksum Error counter
59421 + 0x14 MCAST_CNT Multicast counter
59422 + 0x18 Reserved Reserved
59423 + 0x1C Reserved Reserved
59424 +
59425 +*//***************************************************************************/
59426 +typedef _Packed struct
59427 +{
59428 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59429 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59430 + uint32_t nmIpCnt; /**< Not My IP counter */
59431 + uint32_t arCnt; /**< Auto-Response counter */
59432 + uint32_t reserved1; /**< Reserved */
59433 + uint32_t reserved2; /**< Reserved */
59434 + uint32_t reserved3; /**< Reserved */
59435 + uint32_t reserved4; /**< Reserved */
59436 +} _PackedType t_DsarIcmpV6Statistics;
59437 +
59438 +/**************************************************************************//**
59439 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59440 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59441 + 0x04 NMVLAN_CNT Not My VLAN counter
59442 + 0x08 NMIP_CNT Not My IP counter
59443 + 0x0C AR_CNT Auto-Response counter
59444 + 0x10 CSERR_CNT Checksum Error counter
59445 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59446 + 0x18 NMMCAST_CNT Not My Multicast group counter
59447 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59448 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59449 + Source Link-layer Address option is omitted
59450 +*//***************************************************************************/
59451 +typedef _Packed struct
59452 +{
59453 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59454 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59455 + uint32_t nmIpCnt; /**< Not My IP counter */
59456 + uint32_t arCnt; /**< Auto-Response counter */
59457 + uint32_t reserved1; /**< Reserved */
59458 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59459 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59460 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59461 +} _PackedType t_NdStatistics;
59462 +
59463 +/**************************************************************************//**
59464 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59465 + 0x0 0-15 Control bits [0-15]
59466 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59467 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59468 + 0x6 0-15
59469 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59470 + 0xA 0-15
59471 + 0xC 0-15 Reserved Reserved. Must be cleared.
59472 + 0xE 015
59473 +
59474 +*//***************************************************************************/
59475 +typedef _Packed struct
59476 +{
59477 + uint16_t control; /** Control bits [0-15]. */
59478 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59479 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59480 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59481 + uint32_t reserved1; /**< Reserved. */
59482 +} _PackedType t_DsarIcmpV6Descriptor;
59483 +
59484 +
59485 +/**************************************************************************//**
59486 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59487 + The fields names are taken from RFC 4443.
59488 +*//***************************************************************************/
59489 +/* 0 1 2 3 */
59490 +/* 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 */
59491 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59492 +/* | Type | Code | Checksum | */
59493 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59494 +/* | Identifier | Sequence Number | */
59495 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59496 +/* | Data ... */
59497 +/* +-+-+-+-+- */
59498 +typedef _Packed struct
59499 +{
59500 + uint8_t type;
59501 + uint8_t code;
59502 + uint16_t checksum;
59503 + uint16_t identifier;
59504 + uint16_t sequenceNumber;
59505 +} _PackedType t_IcmpV6EchoHdr;
59506 +
59507 +/**************************************************************************//**
59508 + @Description Internet Control Message Protocol (ICMPv6)
59509 + Neighbor Solicitation/Advertisement header
59510 + The fields names are taken from RFC 4861.
59511 + The R/S/O fields are valid for Neighbor Advertisement only
59512 +*//***************************************************************************/
59513 +/* 0 1 2 3
59514 + * 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
59515 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59516 + * | Type | Code | Checksum |
59517 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59518 + * |R|S|O| Reserved |
59519 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59520 + * | |
59521 + * + +
59522 + * | |
59523 + * + Target Address +
59524 + * | |
59525 + * + +
59526 + * | |
59527 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59528 + * | Options ...
59529 + * +-+-+-+-+-+-+-+-+-+-+-+-
59530 + *
59531 + * Options Format:
59532 + * 0 1 2 3
59533 + * 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
59534 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59535 + * | Type | Length | Link-Layer Address ... |
59536 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59537 + * | Link-Layer Address |
59538 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59539 +*/
59540 +typedef _Packed struct
59541 +{
59542 + uint8_t type;
59543 + uint8_t code;
59544 + uint16_t checksum;
59545 + uint32_t router:1;
59546 + uint32_t solicited:1;
59547 + uint32_t override:1;
59548 + uint32_t reserved:29;
59549 + uint32_t targetAddr[4];
59550 + uint8_t optionType;
59551 + uint8_t optionLength;
59552 + uint8_t linkLayerAddr[6];
59553 +} _PackedType t_IcmpV6NdHdr;
59554 +
59555 +/**************************************************************************//**
59556 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59557 + 0x0 0-15 Control bits [0-15]
59558 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59559 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59560 + 0x6 0-15
59561 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59562 + 0xA 0-15
59563 + 0xC 0-15 Reserved Reserved. Must be cleared.
59564 + 0xE 015
59565 +
59566 +*//***************************************************************************/
59567 +typedef _Packed struct
59568 +{
59569 + uint16_t control; /** Control bits [0-15]. */
59570 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59571 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59572 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59573 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59574 +} _PackedType t_DsarNdDescriptor;
59575 +
59576 +/**************************************************************************//**
59577 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59578 +
59579 +*//***************************************************************************/
59580 +typedef struct {
59581 + uint16_t oidSize; /**< Size in octets of the OID. */
59582 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59583 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59584 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59585 + uint32_t reserved;
59586 +} t_OidsTblEntry;
59587 +
59588 +/**************************************************************************//**
59589 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59590 + Refer to the FMan Controller spec for more details.
59591 +*//***************************************************************************/
59592 +typedef struct
59593 +{
59594 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59595 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59596 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59597 + uint16_t reserved;
59598 +} t_DsarSnmpIpv4AddrTblEntry;
59599 +
59600 +/**************************************************************************//**
59601 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59602 + Refer to the FMan Controller spec for more details.
59603 +*//***************************************************************************/
59604 +#pragma pack(push,1)
59605 +typedef struct
59606 +{
59607 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59608 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59609 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59610 + uint16_t reserved;
59611 +} t_DsarSnmpIpv6AddrTblEntry;
59612 +#pragma pack(pop)
59613 +
59614 +/**************************************************************************//**
59615 +@Description Deep Sleep Auto Response SNMP statistics table
59616 +
59617 +*//***************************************************************************/
59618 +typedef struct {
59619 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59620 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59621 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59622 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59623 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59624 +} t_DsarSnmpStatistics;
59625 +
59626 +/**************************************************************************//**
59627 + @Description Deep Sleep Auto Response SNMP Descriptor
59628 +
59629 +*//***************************************************************************/
59630 +typedef struct
59631 +{
59632 + uint16_t control; /**< Control bits [0-15]. */
59633 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59634 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59635 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59636 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59637 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59638 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59639 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59640 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59641 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59642 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59643 +} t_DsarSnmpDescriptor;
59644 +
59645 +/**************************************************************************//**
59646 +@Description Deep Sleep Auto Response (Common) Statistics
59647 +
59648 +*//***************************************************************************/
59649 +typedef _Packed struct {
59650 + uint32_t dsarDiscarded;
59651 + uint32_t dsarErrDiscarded;
59652 + uint32_t dsarFragDiscarded;
59653 + uint32_t dsarTunnelDiscarded;
59654 + uint32_t dsarArpDiscarded;
59655 + uint32_t dsarIpDiscarded;
59656 + uint32_t dsarTcpDiscarded;
59657 + uint32_t dsarUdpDiscarded;
59658 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59659 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59660 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59661 +} _PackedType t_ArStatistics;
59662 +
59663 +
59664 +/**************************************************************************//**
59665 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59666 +
59667 +*//***************************************************************************/
59668 +typedef _Packed struct {
59669 + uint32_t Ports;
59670 + uint32_t PortsMask;
59671 +} _PackedType t_PortTblEntry;
59672 +
59673 +
59674 +
59675 +/**************************************************************************//**
59676 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59677 +
59678 +*//***************************************************************************/
59679 +typedef _Packed struct {
59680 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59681 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59682 + uint16_t res1; /* 0x00 16-31 Reserved */
59683 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59684 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59685 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59686 + uint8_t res2; /* 0x10 0-7 Reserved */
59687 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59688 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59689 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59690 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59691 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59692 + uint8_t res3; /* 0x14 24-31 Reserved */
59693 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59694 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59695 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59696 + uint32_t res4; /* 0x24 Reserved */
59697 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59698 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59699 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59700 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59701 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59702 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59703 +} _PackedType t_ArCommonDesc;
59704 +
59705 +#if defined(__MWERKS__) && !defined(__GNUC__)
59706 +#pragma pack(pop)
59707 +#endif /* defined(__MWERKS__) && ... */
59708 +
59709 +/* t_ArCommonDesc.filterControl bits */
59710 +#define IP_PROT_TBL_PASS_MASK 0x08
59711 +#define UDP_PORT_TBL_PASS_MASK 0x04
59712 +#define TCP_PORT_TBL_PASS_MASK 0x02
59713 +
59714 +/* Offset of TCF flags within TCP packet */
59715 +#define TCP_FLAGS_OFFSET 12
59716 +
59717 +
59718 +#endif /* __FM_PORT_DSAR_H_ */
59719 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59720 new file mode 100644
59721 index 00000000..8de8f5fd
59722 --- /dev/null
59723 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59724 @@ -0,0 +1,753 @@
59725 +/*
59726 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59727 + *
59728 + * Redistribution and use in source and binary forms, with or without
59729 + * modification, are permitted provided that the following conditions are met:
59730 + * * Redistributions of source code must retain the above copyright
59731 + * notice, this list of conditions and the following disclaimer.
59732 + * * Redistributions in binary form must reproduce the above copyright
59733 + * notice, this list of conditions and the following disclaimer in the
59734 + * documentation and/or other materials provided with the distribution.
59735 + * * Neither the name of Freescale Semiconductor nor the
59736 + * names of its contributors may be used to endorse or promote products
59737 + * derived from this software without specific prior written permission.
59738 + *
59739 + *
59740 + * ALTERNATIVELY, this software may be distributed under the terms of the
59741 + * GNU General Public License ("GPL") as published by the Free Software
59742 + * Foundation, either version 2 of that License or (at your option) any
59743 + * later version.
59744 + *
59745 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59746 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59747 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59748 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59749 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59750 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59751 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59752 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59753 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59754 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59755 + */
59756 +
59757 +
59758 +/******************************************************************************
59759 + @File fm_port_im.c
59760 +
59761 + @Description FM Port Independent-Mode ...
59762 +*//***************************************************************************/
59763 +#include "std_ext.h"
59764 +#include "string_ext.h"
59765 +#include "error_ext.h"
59766 +#include "memcpy_ext.h"
59767 +#include "fm_muram_ext.h"
59768 +
59769 +#include "fm_port.h"
59770 +
59771 +
59772 +#define TX_CONF_STATUS_UNSENT 0x1
59773 +
59774 +
59775 +typedef enum e_TxConfType
59776 +{
59777 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59778 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59779 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59780 +} e_TxConfType;
59781 +
59782 +
59783 +static void ImException(t_Handle h_FmPort, uint32_t event)
59784 +{
59785 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59786 +
59787 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59788 + !FmIsMaster(p_FmPort->h_Fm));
59789 +
59790 + if (event & IM_EV_RX)
59791 + FmPortImRx(p_FmPort);
59792 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59793 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59794 +}
59795 +
59796 +
59797 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59798 +{
59799 + t_Error retVal = E_BUSY;
59800 + uint32_t bdStatus;
59801 + uint16_t savedStartBdId, confBdId;
59802 +
59803 + ASSERT_COND(p_FmPort);
59804 +
59805 + /*
59806 + if (confType==e_TX_CONF_TYPE_CHECK)
59807 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59808 + */
59809 +
59810 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59811 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59812 +
59813 + /* If R bit is set, we don't enter, or we break.
59814 + we run till we get to R, or complete the loop */
59815 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59816 + {
59817 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59818 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59819 +
59820 + /* case 1: R bit is 0 and Length is set -> confirm! */
59821 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59822 + {
59823 + if (p_FmPort->im.f_TxConf)
59824 + {
59825 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59826 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59827 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59828 + TX_CONF_STATUS_UNSENT,
59829 + p_FmPort->im.p_BdShadow[confBdId]);
59830 + else
59831 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59832 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59833 + 0,
59834 + p_FmPort->im.p_BdShadow[confBdId]);
59835 + }
59836 + }
59837 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59838 +
59839 + confBdId = GetNextBdId(p_FmPort, confBdId);
59840 + if (confBdId == savedStartBdId)
59841 + retVal = E_OK;
59842 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59843 + }
59844 +
59845 + return retVal;
59846 +}
59847 +
59848 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59849 +{
59850 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59851 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59852 + return E_OK;
59853 +}
59854 +
59855 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59856 +{
59857 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59858 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59859 + return E_OK;
59860 +}
59861 +
59862 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59863 +{
59864 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59865 + uint32_t bdStatus;
59866 + volatile uint8_t buffPos;
59867 + uint16_t length;
59868 + uint16_t errors;
59869 + uint8_t *p_CurData, *p_Data;
59870 + uint32_t flags;
59871 +
59872 + ASSERT_COND(p_FmPort);
59873 +
59874 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
59875 + if (p_FmPort->lock)
59876 + {
59877 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59878 + return E_OK;
59879 + }
59880 + p_FmPort->lock = TRUE;
59881 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59882 +
59883 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59884 +
59885 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
59886 + {
59887 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
59888 + {
59889 + p_FmPort->lock = FALSE;
59890 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59891 + }
59892 +
59893 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
59894 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
59895 +
59896 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
59897 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
59898 + length = (uint16_t)((bdStatus & BD_L) ?
59899 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
59900 + (bdStatus & BD_LENGTH_MASK));
59901 + p_FmPort->im.rxFrameAccumLength += length;
59902 +
59903 + /* determine whether buffer is first, last, first and last (single */
59904 + /* buffer frame) or middle (not first and not last) */
59905 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
59906 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
59907 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
59908 +
59909 + if (bdStatus & BD_L)
59910 + {
59911 + p_FmPort->im.rxFrameAccumLength = 0;
59912 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
59913 + }
59914 +
59915 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
59916 +
59917 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
59918 +
59919 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
59920 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
59921 +
59922 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
59923 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
59924 + /* Pass the buffer if one of the conditions is true:
59925 + - There are no errors
59926 + - This is a part of a larger frame ( the application has already received some buffers ) */
59927 + if ((buffPos != SINGLE_BUF) || !errors)
59928 + {
59929 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
59930 + p_CurData,
59931 + length,
59932 + errors,
59933 + buffPos,
59934 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
59935 + break;
59936 + }
59937 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
59938 + p_CurData,
59939 + h_CurrUserPriv))
59940 + {
59941 + p_FmPort->lock = FALSE;
59942 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
59943 + }
59944 +
59945 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59946 + }
59947 + p_FmPort->lock = FALSE;
59948 + return E_OK;
59949 +}
59950 +
59951 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
59952 +{
59953 + ASSERT_COND(p_FmPort);
59954 +
59955 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59956 +
59957 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
59958 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
59959 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
59960 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
59961 +
59962 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
59963 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
59964 +
59965 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59966 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59967 + {
59968 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
59969 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
59970 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
59971 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
59972 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
59973 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
59974 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
59975 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
59976 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
59977 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
59978 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
59979 +
59980 + p_FmPort->im.mrblr = 0x8000;
59981 + while (p_FmPort->im.mrblr)
59982 + {
59983 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
59984 + break;
59985 + p_FmPort->im.mrblr >>= 1;
59986 + }
59987 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
59988 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
59989 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
59990 + p_FmPort->exceptions = DEFAULT_PORT_exception;
59991 + if (FmIsMaster(p_FmPort->h_Fm))
59992 + p_FmPort->polling = FALSE;
59993 + else
59994 + p_FmPort->polling = TRUE;
59995 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59996 + }
59997 + else
59998 + {
59999 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
60000 +
60001 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
60002 + }
60003 +}
60004 +
60005 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
60006 +{
60007 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
60008 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
60009 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
60010 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
60011 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
60012 +
60013 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60014 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60015 + {
60016 + if (!POWER_OF_2(p_FmPort->im.mrblr))
60017 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
60018 + if (p_FmPort->im.mrblr < 256)
60019 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
60020 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
60021 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
60022 + }
60023 +
60024 + return E_OK;
60025 +}
60026 +
60027 +t_Error FmPortImInit(t_FmPort *p_FmPort)
60028 +{
60029 + t_FmImBd *p_Bd=NULL;
60030 + t_Handle h_BufContext;
60031 + uint64_t tmpPhysBase;
60032 + uint16_t log2Num;
60033 + uint8_t *p_Data/*, *p_Tmp*/;
60034 + int i;
60035 + t_Error err;
60036 + uint16_t tmpReg16;
60037 + uint32_t tmpReg32;
60038 +
60039 + ASSERT_COND(p_FmPort);
60040 +
60041 + p_FmPort->im.p_FmPortImPram =
60042 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
60043 + if (!p_FmPort->im.p_FmPortImPram)
60044 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
60045 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
60046 +
60047 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60048 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60049 + {
60050 + p_FmPort->im.p_BdRing =
60051 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
60052 + p_FmPort->im.fwExtStructsMemId,
60053 + 4);
60054 + if (!p_FmPort->im.p_BdRing)
60055 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
60056 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60057 +
60058 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60059 + if (!p_FmPort->im.p_BdShadow)
60060 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60061 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60062 +
60063 + /* Initialize the Rx-BD ring */
60064 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
60065 + {
60066 + p_Bd = BD_GET(i);
60067 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
60068 +
60069 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
60070 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
60071 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
60072 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
60073 + }
60074 +
60075 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60076 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60077 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60078 + else
60079 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60080 +
60081 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
60082 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60083 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
60084 +
60085 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
60086 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
60087 +
60088 + /* Initialize Rx QD */
60089 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60090 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
60091 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60092 +
60093 + /* Update the IM PRAM address in the BMI */
60094 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
60095 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60096 + p_FmPort->fmMuramPhysBaseAddr));
60097 + if (!p_FmPort->polling || p_FmPort->exceptions)
60098 + {
60099 + /* Allocate, configure and register interrupts */
60100 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60101 + if (err)
60102 + RETURN_ERROR(MAJOR, err, NO_MSG);
60103 +
60104 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60105 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
60106 + tmpReg32 = 0;
60107 +
60108 + if (p_FmPort->exceptions & IM_EV_BSY)
60109 + {
60110 + tmpReg16 |= IM_RXQD_BSYINTM;
60111 + tmpReg32 |= IM_EV_BSY;
60112 + }
60113 + if (!p_FmPort->polling)
60114 + {
60115 + tmpReg16 |= IM_RXQD_RXFINTM;
60116 + tmpReg32 |= IM_EV_RX;
60117 + }
60118 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60119 +
60120 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
60121 +
60122 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60123 + }
60124 + else
60125 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60126 + }
60127 + else
60128 + {
60129 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
60130 + if (!p_FmPort->im.p_BdRing)
60131 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
60132 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60133 +
60134 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60135 + if (!p_FmPort->im.p_BdShadow)
60136 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60137 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60138 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60139 +
60140 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60141 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60142 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60143 + else
60144 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60145 +
60146 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
60147 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60148 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
60149 +
60150 + /* Initialize Tx QD */
60151 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60152 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
60153 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60154 +
60155 + /* Update the IM PRAM address in the BMI */
60156 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
60157 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60158 + p_FmPort->fmMuramPhysBaseAddr));
60159 + }
60160 +
60161 +
60162 + return E_OK;
60163 +}
60164 +
60165 +void FmPortImFree(t_FmPort *p_FmPort)
60166 +{
60167 + uint32_t bdStatus;
60168 + uint8_t *p_CurData;
60169 +
60170 + ASSERT_COND(p_FmPort);
60171 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
60172 +
60173 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60174 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60175 + {
60176 + if (!p_FmPort->polling || p_FmPort->exceptions)
60177 + {
60178 + /* Deallocate and unregister interrupts */
60179 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60180 +
60181 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60182 +
60183 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60184 +
60185 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60186 + }
60187 + /* Try first clean what has received */
60188 + FmPortImRx(p_FmPort);
60189 +
60190 + /* Now, get rid of the the empty buffer! */
60191 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60192 +
60193 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
60194 + {
60195 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60196 +
60197 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
60198 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
60199 +
60200 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60201 + p_CurData,
60202 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60203 +
60204 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60205 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60206 + }
60207 + }
60208 + else
60209 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
60210 +
60211 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
60212 +
60213 + if (p_FmPort->im.p_BdShadow)
60214 + XX_Free(p_FmPort->im.p_BdShadow);
60215 +
60216 + if (p_FmPort->im.p_BdRing)
60217 + XX_FreeSmart(p_FmPort->im.p_BdRing);
60218 +}
60219 +
60220 +
60221 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
60222 +{
60223 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60224 +
60225 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60226 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60227 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60228 +
60229 + p_FmPort->im.mrblr = newVal;
60230 +
60231 + return E_OK;
60232 +}
60233 +
60234 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60235 +{
60236 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60237 +
60238 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60239 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60240 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60241 +
60242 + p_FmPort->im.bdRingSize = newVal;
60243 +
60244 + return E_OK;
60245 +}
60246 +
60247 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60248 +{
60249 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60250 +
60251 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60252 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60253 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60254 +
60255 + p_FmPort->im.bdRingSize = newVal;
60256 +
60257 + return E_OK;
60258 +}
60259 +
60260 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60261 + uint8_t memId,
60262 + uint32_t memAttributes)
60263 +{
60264 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60265 +
60266 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60267 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60268 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60269 +
60270 + p_FmPort->im.fwExtStructsMemId = memId;
60271 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60272 +
60273 + return E_OK;
60274 +}
60275 +
60276 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60277 +{
60278 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60279 +
60280 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60281 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60282 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60283 +
60284 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60285 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60286 +
60287 + if (!FmIsMaster(p_FmPort->h_Fm))
60288 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60289 + "in guest-partitions, IM is always in polling!"));
60290 +
60291 + p_FmPort->polling = TRUE;
60292 +
60293 + return E_OK;
60294 +}
60295 +
60296 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60297 +{
60298 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60299 + t_Error err;
60300 + uint16_t tmpReg16;
60301 + uint32_t tmpReg32;
60302 +
60303 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60304 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60305 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60306 +
60307 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60308 + {
60309 + if (enable)
60310 + {
60311 + p_FmPort->exceptions |= IM_EV_BSY;
60312 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60313 + {
60314 + /* Allocate, configure and register interrupts */
60315 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60316 + if (err)
60317 + RETURN_ERROR(MAJOR, err, NO_MSG);
60318 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60319 +
60320 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60321 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60322 + tmpReg32 = IM_EV_BSY;
60323 + }
60324 + else
60325 + {
60326 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60327 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60328 + }
60329 +
60330 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60331 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60332 + }
60333 + else
60334 + {
60335 + p_FmPort->exceptions &= ~IM_EV_BSY;
60336 + if (!p_FmPort->exceptions && p_FmPort->polling)
60337 + {
60338 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60339 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60340 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60341 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60342 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60343 + }
60344 + else
60345 + {
60346 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60347 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60348 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60349 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60350 + }
60351 + }
60352 + }
60353 + else
60354 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60355 +
60356 + return E_OK;
60357 +}
60358 +
60359 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60360 + uint8_t *p_Data,
60361 + uint16_t length,
60362 + bool lastBuffer,
60363 + t_Handle h_BufContext)
60364 +{
60365 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60366 + uint16_t nextBdId;
60367 + uint32_t bdStatus, nextBdStatus;
60368 + bool firstBuffer;
60369 +
60370 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60371 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60372 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60373 +
60374 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60375 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60376 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60377 +
60378 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60379 + {
60380 + /* Confirm the current BD - BD is available */
60381 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60382 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60383 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60384 + 0,
60385 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60386 +
60387 + bdStatus = length;
60388 +
60389 + /* if this is the first BD of a frame */
60390 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60391 + {
60392 + firstBuffer = TRUE;
60393 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60394 +
60395 + if (!lastBuffer)
60396 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60397 + }
60398 + else
60399 + firstBuffer = FALSE;
60400 +
60401 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60402 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60403 +
60404 + /* deal with last */
60405 + if (lastBuffer)
60406 + {
60407 + /* if single buffer frame */
60408 + if (firstBuffer)
60409 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60410 + else
60411 + {
60412 + /* Set the last BD of the frame */
60413 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60414 + /* Set the first BD of the frame */
60415 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60416 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60417 + }
60418 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60419 + }
60420 + else if (!firstBuffer) /* mid frame buffer */
60421 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60422 +
60423 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60424 + }
60425 + else
60426 + {
60427 + /* Discard current frame. Return error. */
60428 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60429 + {
60430 + /* Error: No free BD */
60431 + /* Response: Discard current frame. Return error. */
60432 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60433 +
60434 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60435 +
60436 + /* Since firstInFrame is not NULL, one buffer at least has already been
60437 + inserted into the BD ring. Using do-while covers the situation of a
60438 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60439 + prior to testing whether or not it's equal to TxBd). */
60440 + do
60441 + {
60442 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60443 + /* Advance BD pointer */
60444 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60445 + } while (cleanBdId != p_FmPort->im.currBdId);
60446 +
60447 + p_FmPort->im.currBdId = cleanBdId;
60448 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60449 + }
60450 +
60451 + return ERROR_CODE(E_FULL);
60452 + }
60453 +
60454 + return E_OK;
60455 +}
60456 +
60457 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60458 +{
60459 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60460 +
60461 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60462 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60463 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60464 +
60465 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60466 +}
60467 +
60468 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60469 +{
60470 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60471 +
60472 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60473 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60474 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60475 +
60476 + return FmPortImRx(p_FmPort);
60477 +}
60478 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60479 new file mode 100755
60480 index 00000000..60acbf34
60481 --- /dev/null
60482 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60483 @@ -0,0 +1,1568 @@
60484 +/*
60485 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60486 + *
60487 + * Redistribution and use in source and binary forms, with or without
60488 + * modification, are permitted provided that the following conditions are met:
60489 + * * Redistributions of source code must retain the above copyright
60490 + * notice, this list of conditions and the following disclaimer.
60491 + * * Redistributions in binary form must reproduce the above copyright
60492 + * notice, this list of conditions and the following disclaimer in the
60493 + * documentation and/or other materials provided with the distribution.
60494 + * * Neither the name of Freescale Semiconductor nor the
60495 + * names of its contributors may be used to endorse or promote products
60496 + * derived from this software without specific prior written permission.
60497 + *
60498 + *
60499 + * ALTERNATIVELY, this software may be distributed under the terms of the
60500 + * GNU General Public License ("GPL") as published by the Free Software
60501 + * Foundation, either version 2 of that License or (at your option) any
60502 + * later version.
60503 + *
60504 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60505 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60506 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60507 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60508 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60509 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60510 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60511 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60512 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60513 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60514 + */
60515 +
60516 +
60517 +#include "common/general.h"
60518 +
60519 +#include "fman_common.h"
60520 +#include "fsl_fman_port.h"
60521 +
60522 +
60523 +/* problem Eyal: the following should not be here*/
60524 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60525 +
60526 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60527 +{
60528 + if (cfg->errata_A006675)
60529 + return NIA_ENG_FM_CTL |
60530 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60531 + else
60532 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60533 +}
60534 +
60535 +static int init_bmi_rx(struct fman_port *port,
60536 + struct fman_port_cfg *cfg,
60537 + struct fman_port_params *params)
60538 +{
60539 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60540 + uint32_t tmp;
60541 +
60542 + /* Rx Configuration register */
60543 + tmp = 0;
60544 + if (port->im_en)
60545 + tmp |= BMI_PORT_CFG_IM;
60546 + else if (cfg->discard_override)
60547 + tmp |= BMI_PORT_CFG_FDOVR;
60548 + iowrite32be(tmp, &regs->fmbm_rcfg);
60549 +
60550 + /* DMA attributes */
60551 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60552 + if (cfg->dma_ic_stash_on)
60553 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60554 + if (cfg->dma_header_stash_on)
60555 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60556 + if (cfg->dma_sg_stash_on)
60557 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60558 + if (cfg->dma_write_optimize)
60559 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60560 + iowrite32be(tmp, &regs->fmbm_rda);
60561 +
60562 + /* Rx FIFO parameters */
60563 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60564 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60565 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60566 + iowrite32be(tmp, &regs->fmbm_rfp);
60567 +
60568 + if (cfg->excessive_threshold_register)
60569 + /* always allow access to the extra resources */
60570 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60571 +
60572 + /* Frame end data */
60573 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60574 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60575 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60576 + BMI_RX_FRAME_END_CUT_SHIFT;
60577 + if (cfg->errata_A006320)
60578 + tmp &= 0xffe0ffff;
60579 + iowrite32be(tmp, &regs->fmbm_rfed);
60580 +
60581 + /* Internal context parameters */
60582 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60583 + BMI_IC_TO_EXT_SHIFT;
60584 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60585 + BMI_IC_FROM_INT_SHIFT;
60586 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60587 + iowrite32be(tmp, &regs->fmbm_ricp);
60588 +
60589 + /* Internal buffer offset */
60590 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60591 + << BMI_INT_BUF_MARG_SHIFT;
60592 + iowrite32be(tmp, &regs->fmbm_rim);
60593 +
60594 + /* External buffer margins */
60595 + if (!port->im_en)
60596 + {
60597 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60598 + BMI_EXT_BUF_MARG_START_SHIFT;
60599 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60600 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60601 + tmp |= BMI_SG_DISABLE;
60602 + iowrite32be(tmp, &regs->fmbm_rebm);
60603 + }
60604 +
60605 + /* Frame attributes */
60606 + tmp = BMI_CMD_RX_MR_DEF;
60607 + if (!port->im_en)
60608 + {
60609 + tmp |= BMI_CMD_ATTR_ORDER;
60610 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60611 + if (cfg->sync_req)
60612 + tmp |= BMI_CMD_ATTR_SYNC;
60613 + }
60614 + iowrite32be(tmp, &regs->fmbm_rfca);
60615 +
60616 + /* NIA */
60617 + if (port->im_en)
60618 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60619 + else
60620 + {
60621 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60622 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60623 + }
60624 + iowrite32be(tmp, &regs->fmbm_rfne);
60625 +
60626 + /* Enqueue NIA */
60627 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60628 +
60629 + /* Default/error queues */
60630 + if (!port->im_en)
60631 + {
60632 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60633 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60634 + }
60635 +
60636 + /* Discard/error masks */
60637 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60638 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60639 +
60640 + /* Statistics counters */
60641 + tmp = 0;
60642 + if (cfg->stats_counters_enable)
60643 + tmp = BMI_COUNTERS_EN;
60644 + iowrite32be(tmp, &regs->fmbm_rstc);
60645 +
60646 + /* Performance counters */
60647 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60648 + tmp = 0;
60649 + if (cfg->perf_counters_enable)
60650 + tmp = BMI_COUNTERS_EN;
60651 + iowrite32be(tmp, &regs->fmbm_rpc);
60652 +
60653 + return 0;
60654 +}
60655 +
60656 +static int init_bmi_tx(struct fman_port *port,
60657 + struct fman_port_cfg *cfg,
60658 + struct fman_port_params *params)
60659 +{
60660 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60661 + uint32_t tmp;
60662 +
60663 + /* Tx Configuration register */
60664 + tmp = 0;
60665 + if (port->im_en)
60666 + tmp |= BMI_PORT_CFG_IM;
60667 + iowrite32be(tmp, &regs->fmbm_tcfg);
60668 +
60669 + /* DMA attributes */
60670 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60671 + if (cfg->dma_ic_stash_on)
60672 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60673 + if (cfg->dma_header_stash_on)
60674 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60675 + if (cfg->dma_sg_stash_on)
60676 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60677 + iowrite32be(tmp, &regs->fmbm_tda);
60678 +
60679 + /* Tx FIFO parameters */
60680 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60681 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60682 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60683 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60684 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60685 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60686 + iowrite32be(tmp, &regs->fmbm_tfp);
60687 +
60688 + /* Frame end data */
60689 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60690 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60691 + iowrite32be(tmp, &regs->fmbm_tfed);
60692 +
60693 + /* Internal context parameters */
60694 + if (!port->im_en)
60695 + {
60696 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60697 + BMI_IC_TO_EXT_SHIFT;
60698 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60699 + BMI_IC_FROM_INT_SHIFT;
60700 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60701 + iowrite32be(tmp, &regs->fmbm_ticp);
60702 + }
60703 + /* Frame attributes */
60704 + tmp = BMI_CMD_TX_MR_DEF;
60705 + if (port->im_en)
60706 + tmp |= BMI_CMD_MR_DEAS;
60707 + else
60708 + {
60709 + tmp |= BMI_CMD_ATTR_ORDER;
60710 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60711 + }
60712 + iowrite32be(tmp, &regs->fmbm_tfca);
60713 +
60714 + /* Dequeue NIA + enqueue NIA */
60715 + if (port->im_en)
60716 + {
60717 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60718 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60719 + }
60720 + else
60721 + {
60722 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60723 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60724 + if (cfg->fmbm_tfne_has_features)
60725 + iowrite32be(!params->dflt_fqid ?
60726 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60727 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60728 + if (!params->dflt_fqid && params->dont_release_buf)
60729 + {
60730 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60731 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60732 + if (cfg->fmbm_tfne_has_features)
60733 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60734 + }
60735 + }
60736 +
60737 + /* Confirmation/error queues */
60738 + if (!port->im_en)
60739 + {
60740 + if (params->dflt_fqid || !params->dont_release_buf)
60741 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60742 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60743 + }
60744 + /* Statistics counters */
60745 + tmp = 0;
60746 + if (cfg->stats_counters_enable)
60747 + tmp = BMI_COUNTERS_EN;
60748 + iowrite32be(tmp, &regs->fmbm_tstc);
60749 +
60750 + /* Performance counters */
60751 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60752 + tmp = 0;
60753 + if (cfg->perf_counters_enable)
60754 + tmp = BMI_COUNTERS_EN;
60755 + iowrite32be(tmp, &regs->fmbm_tpc);
60756 +
60757 + return 0;
60758 +}
60759 +
60760 +static int init_bmi_oh(struct fman_port *port,
60761 + struct fman_port_cfg *cfg,
60762 + struct fman_port_params *params)
60763 +{
60764 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60765 + uint32_t tmp;
60766 +
60767 + /* OP Configuration register */
60768 + tmp = 0;
60769 + if (cfg->discard_override)
60770 + tmp |= BMI_PORT_CFG_FDOVR;
60771 + iowrite32be(tmp, &regs->fmbm_ocfg);
60772 +
60773 + /* DMA attributes */
60774 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60775 + if (cfg->dma_ic_stash_on)
60776 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60777 + if (cfg->dma_header_stash_on)
60778 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60779 + if (cfg->dma_sg_stash_on)
60780 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60781 + if (cfg->dma_write_optimize)
60782 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60783 + iowrite32be(tmp, &regs->fmbm_oda);
60784 +
60785 + /* Tx FIFO parameters */
60786 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60787 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60788 + iowrite32be(tmp, &regs->fmbm_ofp);
60789 +
60790 + /* Internal context parameters */
60791 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60792 + BMI_IC_TO_EXT_SHIFT;
60793 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60794 + BMI_IC_FROM_INT_SHIFT;
60795 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60796 + iowrite32be(tmp, &regs->fmbm_oicp);
60797 +
60798 + /* Frame attributes */
60799 + tmp = BMI_CMD_OP_MR_DEF;
60800 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60801 + if (cfg->sync_req)
60802 + tmp |= BMI_CMD_ATTR_SYNC;
60803 + if (port->type == E_FMAN_PORT_TYPE_OP)
60804 + tmp |= BMI_CMD_ATTR_ORDER;
60805 + iowrite32be(tmp, &regs->fmbm_ofca);
60806 +
60807 + /* Internal buffer offset */
60808 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60809 + << BMI_INT_BUF_MARG_SHIFT;
60810 + iowrite32be(tmp, &regs->fmbm_oim);
60811 +
60812 + /* Dequeue NIA */
60813 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60814 +
60815 + /* NIA and Enqueue NIA */
60816 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60817 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60818 + &regs->fmbm_ofne);
60819 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60820 + } else {
60821 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60822 + &regs->fmbm_ofne);
60823 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60824 + &regs->fmbm_ofene);
60825 + }
60826 +
60827 + /* Default/error queues */
60828 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60829 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60830 +
60831 + /* Discard/error masks */
60832 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60833 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60834 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60835 + }
60836 +
60837 + /* Statistics counters */
60838 + tmp = 0;
60839 + if (cfg->stats_counters_enable)
60840 + tmp = BMI_COUNTERS_EN;
60841 + iowrite32be(tmp, &regs->fmbm_ostc);
60842 +
60843 + /* Performance counters */
60844 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60845 + tmp = 0;
60846 + if (cfg->perf_counters_enable)
60847 + tmp = BMI_COUNTERS_EN;
60848 + iowrite32be(tmp, &regs->fmbm_opc);
60849 +
60850 + return 0;
60851 +}
60852 +
60853 +static int init_qmi(struct fman_port *port,
60854 + struct fman_port_cfg *cfg,
60855 + struct fman_port_params *params)
60856 +{
60857 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60858 + uint32_t tmp;
60859 +
60860 + tmp = 0;
60861 + if (cfg->queue_counters_enable)
60862 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60863 + iowrite32be(tmp, &regs->fmqm_pnc);
60864 +
60865 + /* Rx port configuration */
60866 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60867 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60868 + /* Enqueue NIA */
60869 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60870 + return 0;
60871 + }
60872 +
60873 + /* Continue with Tx and O/H port configuration */
60874 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
60875 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
60876 + /* Enqueue NIA */
60877 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
60878 + &regs->fmqm_pnen);
60879 + /* Dequeue NIA */
60880 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
60881 + } else {
60882 + /* Enqueue NIA */
60883 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60884 + /* Dequeue NIA */
60885 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
60886 + }
60887 +
60888 + /* Dequeue Configuration register */
60889 + tmp = 0;
60890 + if (cfg->deq_high_pri)
60891 + tmp |= QMI_DEQ_CFG_PRI;
60892 +
60893 + switch (cfg->deq_type) {
60894 + case E_FMAN_PORT_DEQ_BY_PRI:
60895 + tmp |= QMI_DEQ_CFG_TYPE1;
60896 + break;
60897 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
60898 + tmp |= QMI_DEQ_CFG_TYPE2;
60899 + break;
60900 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
60901 + tmp |= QMI_DEQ_CFG_TYPE3;
60902 + break;
60903 + default:
60904 + return -EINVAL;
60905 + }
60906 +
60907 + if (cfg->qmi_deq_options_support) {
60908 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
60909 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
60910 + return -EINVAL;
60911 +
60912 + switch (cfg->deq_prefetch_opt) {
60913 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
60914 + break;
60915 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
60916 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
60917 + break;
60918 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
60919 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
60920 + break;
60921 + default:
60922 + return -EINVAL;
60923 + }
60924 + }
60925 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
60926 + QMI_DEQ_CFG_SP_SHIFT;
60927 + tmp |= cfg->deq_byte_cnt;
60928 + iowrite32be(tmp, &regs->fmqm_pndc);
60929 +
60930 + return 0;
60931 +}
60932 +
60933 +static void get_rx_stats_reg(struct fman_port *port,
60934 + enum fman_port_stats_counters counter,
60935 + uint32_t **stats_reg)
60936 +{
60937 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60938 +
60939 + switch (counter) {
60940 + case E_FMAN_PORT_STATS_CNT_FRAME:
60941 + *stats_reg = &regs->fmbm_rfrc;
60942 + break;
60943 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60944 + *stats_reg = &regs->fmbm_rfdc;
60945 + break;
60946 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60947 + *stats_reg = &regs->fmbm_rbdc;
60948 + break;
60949 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
60950 + *stats_reg = &regs->fmbm_rfbc;
60951 + break;
60952 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
60953 + *stats_reg = &regs->fmbm_rlfc;
60954 + break;
60955 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
60956 + *stats_reg = &regs->fmbm_rodc;
60957 + break;
60958 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60959 + *stats_reg = &regs->fmbm_rffc;
60960 + break;
60961 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60962 + *stats_reg = &regs->fmbm_rfldec;
60963 + break;
60964 + default:
60965 + *stats_reg = NULL;
60966 + }
60967 +}
60968 +
60969 +static void get_tx_stats_reg(struct fman_port *port,
60970 + enum fman_port_stats_counters counter,
60971 + uint32_t **stats_reg)
60972 +{
60973 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60974 +
60975 + switch (counter) {
60976 + case E_FMAN_PORT_STATS_CNT_FRAME:
60977 + *stats_reg = &regs->fmbm_tfrc;
60978 + break;
60979 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60980 + *stats_reg = &regs->fmbm_tfdc;
60981 + break;
60982 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60983 + *stats_reg = &regs->fmbm_tbdc;
60984 + break;
60985 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60986 + *stats_reg = &regs->fmbm_tfledc;
60987 + break;
60988 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60989 + *stats_reg = &regs->fmbm_tfufdc;
60990 + break;
60991 + default:
60992 + *stats_reg = NULL;
60993 + }
60994 +}
60995 +
60996 +static void get_oh_stats_reg(struct fman_port *port,
60997 + enum fman_port_stats_counters counter,
60998 + uint32_t **stats_reg)
60999 +{
61000 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61001 +
61002 + switch (counter) {
61003 + case E_FMAN_PORT_STATS_CNT_FRAME:
61004 + *stats_reg = &regs->fmbm_ofrc;
61005 + break;
61006 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61007 + *stats_reg = &regs->fmbm_ofdc;
61008 + break;
61009 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61010 + *stats_reg = &regs->fmbm_obdc;
61011 + break;
61012 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
61013 + *stats_reg = &regs->fmbm_offc;
61014 + break;
61015 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
61016 + *stats_reg = &regs->fmbm_ofldec;
61017 + break;
61018 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
61019 + *stats_reg = &regs->fmbm_ofledc;
61020 + break;
61021 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
61022 + *stats_reg = &regs->fmbm_ofufdc;
61023 + break;
61024 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
61025 + *stats_reg = &regs->fmbm_ofwdc;
61026 + break;
61027 + default:
61028 + *stats_reg = NULL;
61029 + }
61030 +}
61031 +
61032 +static void get_rx_perf_reg(struct fman_port *port,
61033 + enum fman_port_perf_counters counter,
61034 + uint32_t **perf_reg)
61035 +{
61036 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61037 +
61038 + switch (counter) {
61039 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61040 + *perf_reg = &regs->fmbm_rccn;
61041 + break;
61042 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61043 + *perf_reg = &regs->fmbm_rtuc;
61044 + break;
61045 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61046 + *perf_reg = &regs->fmbm_rrquc;
61047 + break;
61048 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61049 + *perf_reg = &regs->fmbm_rduc;
61050 + break;
61051 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61052 + *perf_reg = &regs->fmbm_rfuc;
61053 + break;
61054 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
61055 + *perf_reg = &regs->fmbm_rpac;
61056 + break;
61057 + default:
61058 + *perf_reg = NULL;
61059 + }
61060 +}
61061 +
61062 +static void get_tx_perf_reg(struct fman_port *port,
61063 + enum fman_port_perf_counters counter,
61064 + uint32_t **perf_reg)
61065 +{
61066 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
61067 +
61068 + switch (counter) {
61069 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61070 + *perf_reg = &regs->fmbm_tccn;
61071 + break;
61072 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61073 + *perf_reg = &regs->fmbm_ttuc;
61074 + break;
61075 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61076 + *perf_reg = &regs->fmbm_ttcquc;
61077 + break;
61078 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61079 + *perf_reg = &regs->fmbm_tduc;
61080 + break;
61081 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61082 + *perf_reg = &regs->fmbm_tfuc;
61083 + break;
61084 + default:
61085 + *perf_reg = NULL;
61086 + }
61087 +}
61088 +
61089 +static void get_oh_perf_reg(struct fman_port *port,
61090 + enum fman_port_perf_counters counter,
61091 + uint32_t **perf_reg)
61092 +{
61093 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61094 +
61095 + switch (counter) {
61096 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61097 + *perf_reg = &regs->fmbm_occn;
61098 + break;
61099 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61100 + *perf_reg = &regs->fmbm_otuc;
61101 + break;
61102 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61103 + *perf_reg = &regs->fmbm_oduc;
61104 + break;
61105 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61106 + *perf_reg = &regs->fmbm_ofuc;
61107 + break;
61108 + default:
61109 + *perf_reg = NULL;
61110 + }
61111 +}
61112 +
61113 +static void get_qmi_counter_reg(struct fman_port *port,
61114 + enum fman_port_qmi_counters counter,
61115 + uint32_t **queue_reg)
61116 +{
61117 + struct fman_port_qmi_regs *regs = port->qmi_regs;
61118 +
61119 + switch (counter) {
61120 + case E_FMAN_PORT_ENQ_TOTAL:
61121 + *queue_reg = &regs->fmqm_pnetfc;
61122 + break;
61123 + case E_FMAN_PORT_DEQ_TOTAL:
61124 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61125 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61126 + /* Counter not available for Rx ports */
61127 + *queue_reg = NULL;
61128 + else
61129 + *queue_reg = &regs->fmqm_pndtfc;
61130 + break;
61131 + case E_FMAN_PORT_DEQ_FROM_DFLT:
61132 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61133 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61134 + /* Counter not available for Rx ports */
61135 + *queue_reg = NULL;
61136 + else
61137 + *queue_reg = &regs->fmqm_pndfdc;
61138 + break;
61139 + case E_FMAN_PORT_DEQ_CONFIRM:
61140 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61141 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61142 + /* Counter not available for Rx ports */
61143 + *queue_reg = NULL;
61144 + else
61145 + *queue_reg = &regs->fmqm_pndcc;
61146 + break;
61147 + default:
61148 + *queue_reg = NULL;
61149 + }
61150 +}
61151 +
61152 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
61153 +{
61154 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
61155 + cfg->dma_ic_stash_on = FALSE;
61156 + cfg->dma_header_stash_on = FALSE;
61157 + cfg->dma_sg_stash_on = FALSE;
61158 + cfg->dma_write_optimize = TRUE;
61159 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
61160 + cfg->discard_override = FALSE;
61161 + cfg->checksum_bytes_ignore = 0;
61162 + cfg->rx_cut_end_bytes = 4;
61163 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61164 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61165 + cfg->rx_fd_bits = 0;
61166 + cfg->ic_ext_offset = 0;
61167 + cfg->ic_int_offset = 0;
61168 + cfg->ic_size = 0;
61169 + cfg->int_buf_start_margin = 0;
61170 + cfg->ext_buf_start_margin = 0;
61171 + cfg->ext_buf_end_margin = 0;
61172 + cfg->tx_fifo_min_level = 0;
61173 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
61174 + cfg->stats_counters_enable = TRUE;
61175 + cfg->perf_counters_enable = TRUE;
61176 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
61177 +
61178 + if (type == E_FMAN_PORT_TYPE_HC) {
61179 + cfg->sync_req = FALSE;
61180 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
61181 + } else {
61182 + cfg->sync_req = TRUE;
61183 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
61184 + }
61185 +
61186 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
61187 + cfg->tx_fifo_deq_pipeline_depth = 4;
61188 + cfg->deq_high_pri = TRUE;
61189 + cfg->deq_byte_cnt = 0x1400;
61190 + } else {
61191 + if ((type == E_FMAN_PORT_TYPE_HC) ||
61192 + (type == E_FMAN_PORT_TYPE_OP))
61193 + cfg->tx_fifo_deq_pipeline_depth = 2;
61194 + else
61195 + cfg->tx_fifo_deq_pipeline_depth = 1;
61196 +
61197 + cfg->deq_high_pri = FALSE;
61198 + cfg->deq_byte_cnt = 0x400;
61199 + }
61200 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
61201 +}
61202 +
61203 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
61204 +{
61205 + uint32_t *bp_reg, tmp;
61206 + uint8_t i, id;
61207 +
61208 + /* Find the pool */
61209 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61210 + for (i = 0;
61211 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
61212 + i++) {
61213 + tmp = ioread32be(&bp_reg[i]);
61214 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
61215 + BMI_EXT_BUF_POOL_ID_SHIFT);
61216 +
61217 + if (id == bpid)
61218 + break;
61219 + }
61220 +
61221 + return i;
61222 +}
61223 +
61224 +int fman_port_init(struct fman_port *port,
61225 + struct fman_port_cfg *cfg,
61226 + struct fman_port_params *params)
61227 +{
61228 + int err;
61229 +
61230 + /* Init BMI registers */
61231 + switch (port->type) {
61232 + case E_FMAN_PORT_TYPE_RX:
61233 + case E_FMAN_PORT_TYPE_RX_10G:
61234 + err = init_bmi_rx(port, cfg, params);
61235 + break;
61236 + case E_FMAN_PORT_TYPE_TX:
61237 + case E_FMAN_PORT_TYPE_TX_10G:
61238 + err = init_bmi_tx(port, cfg, params);
61239 + break;
61240 + case E_FMAN_PORT_TYPE_OP:
61241 + case E_FMAN_PORT_TYPE_HC:
61242 + err = init_bmi_oh(port, cfg, params);
61243 + break;
61244 + default:
61245 + return -EINVAL;
61246 + }
61247 +
61248 + if (err)
61249 + return err;
61250 +
61251 + /* Init QMI registers */
61252 + if (!port->im_en)
61253 + {
61254 + err = init_qmi(port, cfg, params);
61255 + return err;
61256 + }
61257 + return 0;
61258 +}
61259 +
61260 +int fman_port_enable(struct fman_port *port)
61261 +{
61262 + uint32_t *bmi_cfg_reg, tmp;
61263 + bool rx_port;
61264 +
61265 + switch (port->type) {
61266 + case E_FMAN_PORT_TYPE_RX:
61267 + case E_FMAN_PORT_TYPE_RX_10G:
61268 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61269 + rx_port = TRUE;
61270 + break;
61271 + case E_FMAN_PORT_TYPE_TX:
61272 + case E_FMAN_PORT_TYPE_TX_10G:
61273 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61274 + rx_port = FALSE;
61275 + break;
61276 + case E_FMAN_PORT_TYPE_OP:
61277 + case E_FMAN_PORT_TYPE_HC:
61278 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61279 + rx_port = FALSE;
61280 + break;
61281 + default:
61282 + return -EINVAL;
61283 + }
61284 +
61285 + /* Enable QMI */
61286 + if (!rx_port) {
61287 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61288 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61289 + }
61290 +
61291 + /* Enable BMI */
61292 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61293 + iowrite32be(tmp, bmi_cfg_reg);
61294 +
61295 + return 0;
61296 +}
61297 +
61298 +int fman_port_disable(const struct fman_port *port)
61299 +{
61300 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61301 + bool rx_port, failure = FALSE;
61302 + int count;
61303 +
61304 + switch (port->type) {
61305 + case E_FMAN_PORT_TYPE_RX:
61306 + case E_FMAN_PORT_TYPE_RX_10G:
61307 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61308 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61309 + rx_port = TRUE;
61310 + break;
61311 + case E_FMAN_PORT_TYPE_TX:
61312 + case E_FMAN_PORT_TYPE_TX_10G:
61313 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61314 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61315 + rx_port = FALSE;
61316 + break;
61317 + case E_FMAN_PORT_TYPE_OP:
61318 + case E_FMAN_PORT_TYPE_HC:
61319 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61320 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61321 + rx_port = FALSE;
61322 + break;
61323 + default:
61324 + return -EINVAL;
61325 + }
61326 +
61327 + /* Disable QMI */
61328 + if (!rx_port) {
61329 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61330 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61331 +
61332 + /* Wait for QMI to finish FD handling */
61333 + count = 100;
61334 + do {
61335 + udelay(10);
61336 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61337 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61338 +
61339 + if (count == 0)
61340 + {
61341 + /* Timeout */
61342 + failure = TRUE;
61343 + }
61344 + }
61345 +
61346 + /* Disable BMI */
61347 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61348 + iowrite32be(tmp, bmi_cfg_reg);
61349 +
61350 + /* Wait for graceful stop end */
61351 + count = 500;
61352 + do {
61353 + udelay(10);
61354 + tmp = ioread32be(bmi_status_reg);
61355 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61356 +
61357 + if (count == 0)
61358 + {
61359 + /* Timeout */
61360 + failure = TRUE;
61361 + }
61362 +
61363 + if (failure)
61364 + return -EBUSY;
61365 +
61366 + return 0;
61367 +}
61368 +
61369 +int fman_port_set_bpools(const struct fman_port *port,
61370 + const struct fman_port_bpools *bp)
61371 +{
61372 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61373 + uint8_t i, max_bp_num;
61374 + bool grp_depl_used = FALSE, rx_port;
61375 +
61376 + switch (port->type) {
61377 + case E_FMAN_PORT_TYPE_RX:
61378 + case E_FMAN_PORT_TYPE_RX_10G:
61379 + max_bp_num = port->ext_pools_num;
61380 + rx_port = TRUE;
61381 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61382 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61383 + break;
61384 + case E_FMAN_PORT_TYPE_OP:
61385 + if (port->fm_rev_maj != 4)
61386 + return -EINVAL;
61387 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61388 + rx_port = FALSE;
61389 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61390 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61391 + break;
61392 + default:
61393 + return -EINVAL;
61394 + }
61395 +
61396 + if (rx_port) {
61397 + /* Check buffers are provided in ascending order */
61398 + for (i = 0;
61399 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61400 + i++) {
61401 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61402 + return -EINVAL;
61403 + }
61404 + }
61405 +
61406 + /* Set up external buffers pools */
61407 + for (i = 0; i < bp->count; i++) {
61408 + tmp = BMI_EXT_BUF_POOL_VALID;
61409 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61410 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61411 +
61412 + if (rx_port) {
61413 + if (bp->counters_enable)
61414 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61415 +
61416 + if (bp->bpool[i].is_backup)
61417 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61418 +
61419 + tmp |= (uint32_t)bp->bpool[i].size;
61420 + }
61421 +
61422 + iowrite32be(tmp, &bp_reg[i]);
61423 + }
61424 +
61425 + /* Clear unused pools */
61426 + for (i = bp->count; i < max_bp_num; i++)
61427 + iowrite32be(0, &bp_reg[i]);
61428 +
61429 + /* Pools depletion */
61430 + tmp = 0;
61431 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61432 + if (bp->bpool[i].grp_bp_depleted) {
61433 + grp_depl_used = TRUE;
61434 + tmp |= 0x80000000 >> i;
61435 + }
61436 +
61437 + if (bp->bpool[i].single_bp_depleted)
61438 + tmp |= 0x80 >> i;
61439 +
61440 + if (bp->bpool[i].pfc_priorities_en)
61441 + tmp |= 0x0100 << i;
61442 + }
61443 +
61444 + if (grp_depl_used)
61445 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61446 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61447 +
61448 + iowrite32be(tmp, bp_depl_reg);
61449 + return 0;
61450 +}
61451 +
61452 +int fman_port_set_rate_limiter(struct fman_port *port,
61453 + struct fman_port_rate_limiter *rate_limiter)
61454 +{
61455 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61456 + uint32_t granularity, tmp;
61457 + uint8_t usec_bit, factor;
61458 +
61459 + switch (port->type) {
61460 + case E_FMAN_PORT_TYPE_TX:
61461 + case E_FMAN_PORT_TYPE_TX_10G:
61462 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61463 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61464 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61465 + break;
61466 + case E_FMAN_PORT_TYPE_OP:
61467 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61468 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61469 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61470 + break;
61471 + default:
61472 + return -EINVAL;
61473 + }
61474 +
61475 + /* Factor is per 1 usec count */
61476 + factor = 1;
61477 + usec_bit = rate_limiter->count_1micro_bit;
61478 +
61479 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61480 + * scale and multiply the factor */
61481 + while (rate_limiter->rate < (granularity / factor)) {
61482 + if (usec_bit == 31)
61483 + /* Can't configure rate limiter - rate is too small */
61484 + return -EINVAL;
61485 +
61486 + usec_bit++;
61487 + factor <<= 1;
61488 + }
61489 +
61490 + /* Figure out register value. The "while" above quarantees that
61491 + * (rate_limiter->rate * factor / granularity) >= 1 */
61492 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61493 +
61494 + /* Check rate limit isn't too large */
61495 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61496 + return -EINVAL;
61497 +
61498 + /* Check burst size is in allowed range */
61499 + if ((rate_limiter->burst_size == 0) ||
61500 + (rate_limiter->burst_size >
61501 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61502 + return -EINVAL;
61503 +
61504 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61505 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61506 +
61507 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61508 + (port->fm_rev_maj == 4)) {
61509 + if (rate_limiter->high_burst_size_gran)
61510 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61511 + }
61512 +
61513 + iowrite32be(tmp, rate_limit_reg);
61514 +
61515 + /* Set up rate limiter scale register */
61516 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61517 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61518 +
61519 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61520 + (port->fm_rev_maj == 4))
61521 + tmp |= rate_limiter->rate_factor;
61522 +
61523 + iowrite32be(tmp, rate_limit_scale_reg);
61524 +
61525 + return 0;
61526 +}
61527 +
61528 +int fman_port_delete_rate_limiter(struct fman_port *port)
61529 +{
61530 + uint32_t *rate_limit_scale_reg;
61531 +
61532 + switch (port->type) {
61533 + case E_FMAN_PORT_TYPE_TX:
61534 + case E_FMAN_PORT_TYPE_TX_10G:
61535 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61536 + break;
61537 + case E_FMAN_PORT_TYPE_OP:
61538 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61539 + break;
61540 + default:
61541 + return -EINVAL;
61542 + }
61543 +
61544 + iowrite32be(0, rate_limit_scale_reg);
61545 + return 0;
61546 +}
61547 +
61548 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61549 +{
61550 + uint32_t *err_mask_reg;
61551 +
61552 + /* Obtain register address */
61553 + switch (port->type) {
61554 + case E_FMAN_PORT_TYPE_RX:
61555 + case E_FMAN_PORT_TYPE_RX_10G:
61556 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61557 + break;
61558 + case E_FMAN_PORT_TYPE_OP:
61559 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61560 + break;
61561 + default:
61562 + return -EINVAL;
61563 + }
61564 +
61565 + iowrite32be(err_mask, err_mask_reg);
61566 + return 0;
61567 +}
61568 +
61569 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61570 +{
61571 + uint32_t *discard_mask_reg;
61572 +
61573 + /* Obtain register address */
61574 + switch (port->type) {
61575 + case E_FMAN_PORT_TYPE_RX:
61576 + case E_FMAN_PORT_TYPE_RX_10G:
61577 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61578 + break;
61579 + case E_FMAN_PORT_TYPE_OP:
61580 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61581 + break;
61582 + default:
61583 + return -EINVAL;
61584 + }
61585 +
61586 + iowrite32be(discard_mask, discard_mask_reg);
61587 + return 0;
61588 +}
61589 +
61590 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61591 + uint8_t rx_fd_bits,
61592 + bool add)
61593 +{
61594 + uint32_t tmp;
61595 +
61596 + switch (port->type) {
61597 + case E_FMAN_PORT_TYPE_RX:
61598 + case E_FMAN_PORT_TYPE_RX_10G:
61599 + break;
61600 + default:
61601 + return -EINVAL;
61602 + }
61603 +
61604 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61605 +
61606 + if (add)
61607 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61608 + else
61609 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61610 +
61611 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61612 + return 0;
61613 +}
61614 +
61615 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61616 + struct fman_port_perf_cnt_params *params)
61617 +{
61618 + uint32_t *pcp_reg, tmp;
61619 +
61620 + /* Obtain register address and check parameters are in range */
61621 + switch (port->type) {
61622 + case E_FMAN_PORT_TYPE_RX:
61623 + case E_FMAN_PORT_TYPE_RX_10G:
61624 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61625 + if ((params->queue_val == 0) ||
61626 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61627 + return -EINVAL;
61628 + break;
61629 + case E_FMAN_PORT_TYPE_TX:
61630 + case E_FMAN_PORT_TYPE_TX_10G:
61631 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61632 + if ((params->queue_val == 0) ||
61633 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61634 + return -EINVAL;
61635 + break;
61636 + case E_FMAN_PORT_TYPE_OP:
61637 + case E_FMAN_PORT_TYPE_HC:
61638 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61639 + if (params->queue_val != 0)
61640 + return -EINVAL;
61641 + break;
61642 + default:
61643 + return -EINVAL;
61644 + }
61645 +
61646 + if ((params->task_val == 0) ||
61647 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61648 + return -EINVAL;
61649 + if ((params->dma_val == 0) ||
61650 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61651 + return -EINVAL;
61652 + if ((params->fifo_val == 0) ||
61653 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61654 + MAX_PERFORMANCE_FIFO_COMP))
61655 + return -EINVAL;
61656 + tmp = (uint32_t)(params->task_val - 1) <<
61657 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61658 + tmp |= (uint32_t)(params->dma_val - 1) <<
61659 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61660 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61661 +
61662 + switch (port->type) {
61663 + case E_FMAN_PORT_TYPE_RX:
61664 + case E_FMAN_PORT_TYPE_RX_10G:
61665 + case E_FMAN_PORT_TYPE_TX:
61666 + case E_FMAN_PORT_TYPE_TX_10G:
61667 + tmp |= (uint32_t)(params->queue_val - 1) <<
61668 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61669 + break;
61670 + default:
61671 + break;
61672 + }
61673 +
61674 +
61675 + iowrite32be(tmp, pcp_reg);
61676 + return 0;
61677 +}
61678 +
61679 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61680 +{
61681 + uint32_t *stats_reg, tmp;
61682 +
61683 + switch (port->type) {
61684 + case E_FMAN_PORT_TYPE_RX:
61685 + case E_FMAN_PORT_TYPE_RX_10G:
61686 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61687 + break;
61688 + case E_FMAN_PORT_TYPE_TX:
61689 + case E_FMAN_PORT_TYPE_TX_10G:
61690 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61691 + break;
61692 + case E_FMAN_PORT_TYPE_OP:
61693 + case E_FMAN_PORT_TYPE_HC:
61694 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61695 + break;
61696 + default:
61697 + return -EINVAL;
61698 + }
61699 +
61700 + tmp = ioread32be(stats_reg);
61701 +
61702 + if (enable)
61703 + tmp |= BMI_COUNTERS_EN;
61704 + else
61705 + tmp &= ~BMI_COUNTERS_EN;
61706 +
61707 + iowrite32be(tmp, stats_reg);
61708 + return 0;
61709 +}
61710 +
61711 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61712 +{
61713 + uint32_t *stats_reg, tmp;
61714 +
61715 + switch (port->type) {
61716 + case E_FMAN_PORT_TYPE_RX:
61717 + case E_FMAN_PORT_TYPE_RX_10G:
61718 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61719 + break;
61720 + case E_FMAN_PORT_TYPE_TX:
61721 + case E_FMAN_PORT_TYPE_TX_10G:
61722 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61723 + break;
61724 + case E_FMAN_PORT_TYPE_OP:
61725 + case E_FMAN_PORT_TYPE_HC:
61726 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61727 + break;
61728 + default:
61729 + return -EINVAL;
61730 + }
61731 +
61732 + tmp = ioread32be(stats_reg);
61733 +
61734 + if (enable)
61735 + tmp |= BMI_COUNTERS_EN;
61736 + else
61737 + tmp &= ~BMI_COUNTERS_EN;
61738 +
61739 + iowrite32be(tmp, stats_reg);
61740 + return 0;
61741 +}
61742 +
61743 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61744 +{
61745 + uint32_t tmp;
61746 +
61747 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61748 +
61749 + if (enable)
61750 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61751 + else
61752 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61753 +
61754 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61755 + return 0;
61756 +}
61757 +
61758 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61759 + uint8_t bpid,
61760 + bool enable)
61761 +{
61762 + uint8_t index;
61763 + uint32_t tmp;
61764 +
61765 + switch (port->type) {
61766 + case E_FMAN_PORT_TYPE_RX:
61767 + case E_FMAN_PORT_TYPE_RX_10G:
61768 + break;
61769 + default:
61770 + return -EINVAL;
61771 + }
61772 +
61773 + /* Find the pool */
61774 + index = fman_port_find_bpool(port, bpid);
61775 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61776 + /* Not found */
61777 + return -EINVAL;
61778 +
61779 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61780 +
61781 + if (enable)
61782 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61783 + else
61784 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61785 +
61786 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61787 + return 0;
61788 +}
61789 +
61790 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61791 + enum fman_port_stats_counters counter)
61792 +{
61793 + uint32_t *stats_reg, ret_val;
61794 +
61795 + switch (port->type) {
61796 + case E_FMAN_PORT_TYPE_RX:
61797 + case E_FMAN_PORT_TYPE_RX_10G:
61798 + get_rx_stats_reg(port, counter, &stats_reg);
61799 + break;
61800 + case E_FMAN_PORT_TYPE_TX:
61801 + case E_FMAN_PORT_TYPE_TX_10G:
61802 + get_tx_stats_reg(port, counter, &stats_reg);
61803 + break;
61804 + case E_FMAN_PORT_TYPE_OP:
61805 + case E_FMAN_PORT_TYPE_HC:
61806 + get_oh_stats_reg(port, counter, &stats_reg);
61807 + break;
61808 + default:
61809 + stats_reg = NULL;
61810 + }
61811 +
61812 + if (stats_reg == NULL)
61813 + return 0;
61814 +
61815 + ret_val = ioread32be(stats_reg);
61816 + return ret_val;
61817 +}
61818 +
61819 +void fman_port_set_stats_counter(struct fman_port *port,
61820 + enum fman_port_stats_counters counter,
61821 + uint32_t value)
61822 +{
61823 + uint32_t *stats_reg;
61824 +
61825 + switch (port->type) {
61826 + case E_FMAN_PORT_TYPE_RX:
61827 + case E_FMAN_PORT_TYPE_RX_10G:
61828 + get_rx_stats_reg(port, counter, &stats_reg);
61829 + break;
61830 + case E_FMAN_PORT_TYPE_TX:
61831 + case E_FMAN_PORT_TYPE_TX_10G:
61832 + get_tx_stats_reg(port, counter, &stats_reg);
61833 + break;
61834 + case E_FMAN_PORT_TYPE_OP:
61835 + case E_FMAN_PORT_TYPE_HC:
61836 + get_oh_stats_reg(port, counter, &stats_reg);
61837 + break;
61838 + default:
61839 + stats_reg = NULL;
61840 + }
61841 +
61842 + if (stats_reg == NULL)
61843 + return;
61844 +
61845 + iowrite32be(value, stats_reg);
61846 +}
61847 +
61848 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61849 + enum fman_port_perf_counters counter)
61850 +{
61851 + uint32_t *perf_reg, ret_val;
61852 +
61853 + switch (port->type) {
61854 + case E_FMAN_PORT_TYPE_RX:
61855 + case E_FMAN_PORT_TYPE_RX_10G:
61856 + get_rx_perf_reg(port, counter, &perf_reg);
61857 + break;
61858 + case E_FMAN_PORT_TYPE_TX:
61859 + case E_FMAN_PORT_TYPE_TX_10G:
61860 + get_tx_perf_reg(port, counter, &perf_reg);
61861 + break;
61862 + case E_FMAN_PORT_TYPE_OP:
61863 + case E_FMAN_PORT_TYPE_HC:
61864 + get_oh_perf_reg(port, counter, &perf_reg);
61865 + break;
61866 + default:
61867 + perf_reg = NULL;
61868 + }
61869 +
61870 + if (perf_reg == NULL)
61871 + return 0;
61872 +
61873 + ret_val = ioread32be(perf_reg);
61874 + return ret_val;
61875 +}
61876 +
61877 +void fman_port_set_perf_counter(struct fman_port *port,
61878 + enum fman_port_perf_counters counter,
61879 + uint32_t value)
61880 +{
61881 + uint32_t *perf_reg;
61882 +
61883 + switch (port->type) {
61884 + case E_FMAN_PORT_TYPE_RX:
61885 + case E_FMAN_PORT_TYPE_RX_10G:
61886 + get_rx_perf_reg(port, counter, &perf_reg);
61887 + break;
61888 + case E_FMAN_PORT_TYPE_TX:
61889 + case E_FMAN_PORT_TYPE_TX_10G:
61890 + get_tx_perf_reg(port, counter, &perf_reg);
61891 + break;
61892 + case E_FMAN_PORT_TYPE_OP:
61893 + case E_FMAN_PORT_TYPE_HC:
61894 + get_oh_perf_reg(port, counter, &perf_reg);
61895 + break;
61896 + default:
61897 + perf_reg = NULL;
61898 + }
61899 +
61900 + if (perf_reg == NULL)
61901 + return;
61902 +
61903 + iowrite32be(value, perf_reg);
61904 +}
61905 +
61906 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
61907 + enum fman_port_qmi_counters counter)
61908 +{
61909 + uint32_t *queue_reg, ret_val;
61910 +
61911 + get_qmi_counter_reg(port, counter, &queue_reg);
61912 +
61913 + if (queue_reg == NULL)
61914 + return 0;
61915 +
61916 + ret_val = ioread32be(queue_reg);
61917 + return ret_val;
61918 +}
61919 +
61920 +void fman_port_set_qmi_counter(struct fman_port *port,
61921 + enum fman_port_qmi_counters counter,
61922 + uint32_t value)
61923 +{
61924 + uint32_t *queue_reg;
61925 +
61926 + get_qmi_counter_reg(port, counter, &queue_reg);
61927 +
61928 + if (queue_reg == NULL)
61929 + return;
61930 +
61931 + iowrite32be(value, queue_reg);
61932 +}
61933 +
61934 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
61935 +{
61936 + uint8_t index;
61937 + uint32_t ret_val;
61938 +
61939 + switch (port->type) {
61940 + case E_FMAN_PORT_TYPE_RX:
61941 + case E_FMAN_PORT_TYPE_RX_10G:
61942 + break;
61943 + default:
61944 + return 0;
61945 + }
61946 +
61947 + /* Find the pool */
61948 + index = fman_port_find_bpool(port, bpid);
61949 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61950 + /* Not found */
61951 + return 0;
61952 +
61953 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
61954 + return ret_val;
61955 +}
61956 +
61957 +void fman_port_set_bpool_counter(struct fman_port *port,
61958 + uint8_t bpid,
61959 + uint32_t value)
61960 +{
61961 + uint8_t index;
61962 +
61963 + switch (port->type) {
61964 + case E_FMAN_PORT_TYPE_RX:
61965 + case E_FMAN_PORT_TYPE_RX_10G:
61966 + break;
61967 + default:
61968 + return;
61969 + }
61970 +
61971 + /* Find the pool */
61972 + index = fman_port_find_bpool(port, bpid);
61973 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61974 + /* Not found */
61975 + return;
61976 +
61977 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
61978 +}
61979 +
61980 +int fman_port_add_congestion_grps(struct fman_port *port,
61981 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61982 +{
61983 + int i;
61984 + uint32_t tmp, *grp_map_reg;
61985 + uint8_t max_grp_map_num;
61986 +
61987 + switch (port->type) {
61988 + case E_FMAN_PORT_TYPE_RX:
61989 + case E_FMAN_PORT_TYPE_RX_10G:
61990 + if (port->fm_rev_maj == 4)
61991 + max_grp_map_num = 1;
61992 + else
61993 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61994 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61995 + break;
61996 + case E_FMAN_PORT_TYPE_OP:
61997 + max_grp_map_num = 1;
61998 + if (port->fm_rev_maj != 4)
61999 + return -EINVAL;
62000 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62001 + break;
62002 + default:
62003 + return -EINVAL;
62004 + }
62005 +
62006 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62007 + if (grps_map[i] == 0)
62008 + continue;
62009 + tmp = ioread32be(&grp_map_reg[i]);
62010 + tmp |= grps_map[i];
62011 + iowrite32be(tmp, &grp_map_reg[i]);
62012 + }
62013 +
62014 + return 0;
62015 +}
62016 +
62017 +int fman_port_remove_congestion_grps(struct fman_port *port,
62018 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
62019 +{
62020 + int i;
62021 + uint32_t tmp, *grp_map_reg;
62022 + uint8_t max_grp_map_num;
62023 +
62024 + switch (port->type) {
62025 + case E_FMAN_PORT_TYPE_RX:
62026 + case E_FMAN_PORT_TYPE_RX_10G:
62027 + if (port->fm_rev_maj == 4)
62028 + max_grp_map_num = 1;
62029 + else
62030 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
62031 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
62032 + break;
62033 + case E_FMAN_PORT_TYPE_OP:
62034 + max_grp_map_num = 1;
62035 + if (port->fm_rev_maj != 4)
62036 + return -EINVAL;
62037 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62038 + break;
62039 + default:
62040 + return -EINVAL;
62041 + }
62042 +
62043 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62044 + if (grps_map[i] == 0)
62045 + continue;
62046 + tmp = ioread32be(&grp_map_reg[i]);
62047 + tmp &= ~grps_map[i];
62048 + iowrite32be(tmp, &grp_map_reg[i]);
62049 + }
62050 + return 0;
62051 +}
62052 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
62053 new file mode 100644
62054 index 00000000..d2c21d34
62055 --- /dev/null
62056 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
62057 @@ -0,0 +1,15 @@
62058 +#
62059 +# Makefile for the Freescale Ethernet controllers
62060 +#
62061 +ccflags-y += -DVERSION=\"\"
62062 +#
62063 +#Include netcomm SW specific definitions
62064 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
62065 +
62066 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
62067 +
62068 +ccflags-y += -I$(NCSW_FM_INC)
62069 +
62070 +obj-y += fsl-ncsw-RTC.o
62071 +
62072 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
62073 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
62074 new file mode 100644
62075 index 00000000..99de427b
62076 --- /dev/null
62077 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
62078 @@ -0,0 +1,692 @@
62079 +/*
62080 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62081 + *
62082 + * Redistribution and use in source and binary forms, with or without
62083 + * modification, are permitted provided that the following conditions are met:
62084 + * * Redistributions of source code must retain the above copyright
62085 + * notice, this list of conditions and the following disclaimer.
62086 + * * Redistributions in binary form must reproduce the above copyright
62087 + * notice, this list of conditions and the following disclaimer in the
62088 + * documentation and/or other materials provided with the distribution.
62089 + * * Neither the name of Freescale Semiconductor nor the
62090 + * names of its contributors may be used to endorse or promote products
62091 + * derived from this software without specific prior written permission.
62092 + *
62093 + *
62094 + * ALTERNATIVELY, this software may be distributed under the terms of the
62095 + * GNU General Public License ("GPL") as published by the Free Software
62096 + * Foundation, either version 2 of that License or (at your option) any
62097 + * later version.
62098 + *
62099 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62100 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62101 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62102 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62103 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62104 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62105 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62106 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62107 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62108 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62109 + */
62110 +
62111 +
62112 +/******************************************************************************
62113 + @File fm_rtc.c
62114 +
62115 + @Description FM RTC driver implementation.
62116 +
62117 + @Cautions None
62118 +*//***************************************************************************/
62119 +#include <linux/math64.h>
62120 +#include "error_ext.h"
62121 +#include "debug_ext.h"
62122 +#include "string_ext.h"
62123 +#include "part_ext.h"
62124 +#include "xx_ext.h"
62125 +#include "ncsw_ext.h"
62126 +
62127 +#include "fm_rtc.h"
62128 +#include "fm_common.h"
62129 +
62130 +
62131 +
62132 +/*****************************************************************************/
62133 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
62134 +{
62135 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62136 + int i;
62137 +
62138 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
62139 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62140 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
62141 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
62142 +
62143 + if (p_Rtc->outputClockDivisor == 0)
62144 + {
62145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
62146 + ("Divisor for output clock (should be positive)"));
62147 + }
62148 +
62149 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
62150 + {
62151 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
62152 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
62153 + {
62154 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
62155 + }
62156 + }
62157 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
62158 + {
62159 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
62160 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
62161 + {
62162 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
62163 + }
62164 + }
62165 +
62166 + return E_OK;
62167 +}
62168 +
62169 +/*****************************************************************************/
62170 +static void RtcExceptions(t_Handle h_FmRtc)
62171 +{
62172 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62173 + struct rtc_regs *p_MemMap;
62174 + register uint32_t events;
62175 +
62176 + ASSERT_COND(p_Rtc);
62177 + p_MemMap = p_Rtc->p_MemMap;
62178 +
62179 + events = fman_rtc_check_and_clear_event(p_MemMap);
62180 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
62181 + {
62182 + if (p_Rtc->alarmParams[0].clearOnExpiration)
62183 + {
62184 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
62185 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
62186 + }
62187 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
62188 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
62189 + }
62190 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
62191 + {
62192 + if (p_Rtc->alarmParams[1].clearOnExpiration)
62193 + {
62194 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
62195 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
62196 + }
62197 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
62198 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
62199 + }
62200 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
62201 + {
62202 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
62203 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
62204 + }
62205 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
62206 + {
62207 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
62208 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
62209 + }
62210 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
62211 + {
62212 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
62213 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
62214 + }
62215 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
62216 + {
62217 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
62218 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
62219 + }
62220 +}
62221 +
62222 +
62223 +/*****************************************************************************/
62224 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
62225 +{
62226 + t_FmRtc *p_Rtc;
62227 +
62228 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
62229 +
62230 + /* Allocate memory for the FM RTC driver parameters */
62231 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
62232 + if (!p_Rtc)
62233 + {
62234 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
62235 + return NULL;
62236 + }
62237 +
62238 + memset(p_Rtc, 0, sizeof(t_FmRtc));
62239 +
62240 + /* Allocate memory for the FM RTC driver parameters */
62241 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
62242 + if (!p_Rtc->p_RtcDriverParam)
62243 + {
62244 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
62245 + XX_Free(p_Rtc);
62246 + return NULL;
62247 + }
62248 +
62249 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
62250 +
62251 + /* Store RTC configuration parameters */
62252 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
62253 +
62254 + /* Set default RTC configuration parameters */
62255 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
62256 +
62257 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
62258 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
62259 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
62260 +
62261 +
62262 + /* Store RTC parameters in the RTC control structure */
62263 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62264 + p_Rtc->h_App = p_FmRtcParam->h_App;
62265 +
62266 + return p_Rtc;
62267 +}
62268 +
62269 +/*****************************************************************************/
62270 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62271 +{
62272 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62273 + struct rtc_cfg *p_RtcDriverParam;
62274 + struct rtc_regs *p_MemMap;
62275 + uint32_t freqCompensation = 0;
62276 + uint64_t tmpDouble;
62277 + bool init_freq_comp = FALSE;
62278 +
62279 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62280 + p_MemMap = p_Rtc->p_MemMap;
62281 +
62282 + if (CheckInitParameters(p_Rtc)!=E_OK)
62283 + RETURN_ERROR(MAJOR, E_CONFLICT,
62284 + ("Init Parameters are not Valid"));
62285 +
62286 + /* TODO check that no timestamping MACs are working in this stage. */
62287 +
62288 + /* find source clock frequency in Mhz */
62289 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62290 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62291 + else
62292 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62293 +
62294 + /* if timer in Master mode Initialize TMR_CTRL */
62295 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62296 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62297 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62298 + else
62299 + {
62300 + /* Initialize TMR_ADD with the initial frequency compensation value:
62301 + freqCompensation = (2^32 / frequency ratio) */
62302 + /* frequency ratio = sorce clock/rtc clock =
62303 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62304 + init_freq_comp = TRUE;
62305 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62306 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62307 + }
62308 +
62309 + /* check the legality of the relation between source and destination clocks */
62310 + /* should be larger than 1.0001 */
62311 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62312 + if ((tmpDouble) <= 10001)
62313 + RETURN_ERROR(MAJOR, E_CONFLICT,
62314 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62315 +
62316 + fman_rtc_init(p_RtcDriverParam,
62317 + p_MemMap,
62318 + FM_RTC_NUM_OF_ALARMS,
62319 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62320 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62321 + init_freq_comp,
62322 + freqCompensation,
62323 + p_Rtc->outputClockDivisor);
62324 +
62325 + /* Register the FM RTC interrupt */
62326 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62327 +
62328 + /* Free parameters structures */
62329 + XX_Free(p_Rtc->p_RtcDriverParam);
62330 + p_Rtc->p_RtcDriverParam = NULL;
62331 +
62332 + return E_OK;
62333 +}
62334 +
62335 +/*****************************************************************************/
62336 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62337 +{
62338 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62339 +
62340 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62341 +
62342 + if (p_Rtc->p_RtcDriverParam)
62343 + {
62344 + XX_Free(p_Rtc->p_RtcDriverParam);
62345 + }
62346 + else
62347 + {
62348 + FM_RTC_Disable(h_FmRtc);
62349 + }
62350 +
62351 + /* Unregister FM RTC interrupt */
62352 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62353 + XX_Free(p_Rtc);
62354 +
62355 + return E_OK;
62356 +}
62357 +
62358 +/*****************************************************************************/
62359 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62360 + e_FmSrcClk srcClk,
62361 + uint32_t freqInMhz)
62362 +{
62363 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62364 +
62365 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62366 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62367 +
62368 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62369 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62370 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62371 +
62372 + return E_OK;
62373 +}
62374 +
62375 +/*****************************************************************************/
62376 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
62377 +{
62378 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62379 +
62380 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62381 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62382 +
62383 + p_Rtc->clockPeriodNanoSec = period;
62384 +
62385 + return E_OK;
62386 +}
62387 +
62388 +/*****************************************************************************/
62389 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
62390 +{
62391 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62392 +
62393 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62394 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62395 +
62396 + p_Rtc->p_RtcDriverParam->bypass = enabled;
62397 +
62398 + return E_OK;
62399 +}
62400 +
62401 +/*****************************************************************************/
62402 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
62403 +{
62404 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62405 +
62406 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62407 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62408 +
62409 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
62410 +
62411 + return E_OK;
62412 +}
62413 +
62414 +/*****************************************************************************/
62415 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62416 +{
62417 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62418 +
62419 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62420 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62421 +
62422 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62423 +
62424 + return E_OK;
62425 +}
62426 +
62427 +/*****************************************************************************/
62428 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62429 +{
62430 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62431 +
62432 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62433 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62434 +
62435 + p_Rtc->outputClockDivisor = divisor;
62436 +
62437 + return E_OK;
62438 +}
62439 +
62440 +/*****************************************************************************/
62441 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62442 +{
62443 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62444 +
62445 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62446 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62447 +
62448 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62449 +
62450 + return E_OK;
62451 +}
62452 +
62453 +/*****************************************************************************/
62454 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62455 + uint8_t alarmId,
62456 + e_FmRtcAlarmPolarity alarmPolarity)
62457 +{
62458 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62459 +
62460 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62461 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62462 +
62463 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62464 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62465 +
62466 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62467 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62468 +
62469 + return E_OK;
62470 +}
62471 +
62472 +/*****************************************************************************/
62473 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62474 + uint8_t triggerId,
62475 + e_FmRtcTriggerPolarity triggerPolarity)
62476 +{
62477 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
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 (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62483 + {
62484 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62485 + }
62486 +
62487 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62488 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62489 +
62490 + return E_OK;
62491 +}
62492 +
62493 +/*****************************************************************************/
62494 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62495 +{
62496 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62497 +
62498 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62499 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62500 +
62501 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62502 + return E_OK;
62503 +}
62504 +
62505 +/*****************************************************************************/
62506 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62507 +{
62508 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62509 +
62510 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62511 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62512 +
62513 + /* TODO A check must be added here, that no timestamping MAC's
62514 + * are working in this stage. */
62515 + fman_rtc_disable(p_Rtc->p_MemMap);
62516 +
62517 + return E_OK;
62518 +}
62519 +
62520 +/*****************************************************************************/
62521 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62522 +{
62523 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62524 +
62525 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62526 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62527 +
62528 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62529 + return E_OK;
62530 +}
62531 +
62532 +/*****************************************************************************/
62533 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62534 +{
62535 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62536 + uint64_t tmpAlarm;
62537 + bool enable = FALSE;
62538 +
62539 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62540 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62541 +
62542 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62543 + {
62544 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62545 + }
62546 +
62547 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62548 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62549 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62550 + p_Rtc->clockPeriodNanoSec));
62551 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62552 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62553 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62554 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62555 + p_Rtc->clockPeriodNanoSec));
62556 +
62557 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62558 + {
62559 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62560 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62561 + enable = TRUE;
62562 + }
62563 +
62564 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62565 +
62566 + return E_OK;
62567 +}
62568 +
62569 +/*****************************************************************************/
62570 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62571 +{
62572 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62573 + bool enable = FALSE;
62574 + uint64_t tmpFiper;
62575 +
62576 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62577 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62578 +
62579 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62580 + {
62581 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62582 + }
62583 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62584 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62585 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62586 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62587 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62588 + p_Rtc->clockPeriodNanoSec));
62589 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62590 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62591 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62592 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62593 + p_Rtc->clockPeriodNanoSec));
62594 + if (tmpFiper & 0xffffffff00000000LL)
62595 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62596 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62597 + p_Rtc->clockPeriodNanoSec));
62598 +
62599 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62600 + {
62601 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62602 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62603 + enable = TRUE;
62604 + }
62605 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62606 + return E_OK;
62607 +}
62608 +
62609 +/*****************************************************************************/
62610 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62611 +{
62612 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62613 +
62614 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62615 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62616 +
62617 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62618 + {
62619 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62620 + }
62621 +
62622 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62623 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62624 +
62625 + return E_OK;
62626 +}
62627 +
62628 +/*****************************************************************************/
62629 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62630 +{
62631 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62632 + bool enable = FALSE;
62633 +
62634 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62635 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62636 +
62637 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62638 + {
62639 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62640 + }
62641 +
62642 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62643 + {
62644 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62645 + enable = TRUE;
62646 + }
62647 +
62648 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62649 + return E_OK;
62650 +}
62651 +
62652 +/*****************************************************************************/
62653 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62654 +{
62655 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62656 +
62657 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62658 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62659 +
62660 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62661 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62662 +
62663 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62664 +
62665 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62666 +
62667 + return E_OK;
62668 +}
62669 +
62670 +/*****************************************************************************/
62671 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62672 + uint8_t triggerId,
62673 + uint64_t *p_TimeStamp)
62674 +{
62675 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62676 +
62677 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62678 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62679 +
62680 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62681 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62682 +
62683 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62684 +
62685 + return E_OK;
62686 +}
62687 +
62688 +/*****************************************************************************/
62689 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
62690 +{
62691 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62692 +
62693 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62694 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62695 +
62696 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62697 +
62698 + return E_OK;
62699 +}
62700 +
62701 +/*****************************************************************************/
62702 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
62703 +{
62704 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62705 +
62706 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62707 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62708 +
62709 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62710 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62711 +
62712 + return E_OK;
62713 +}
62714 +
62715 +/*****************************************************************************/
62716 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62717 +{
62718 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62719 +
62720 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62721 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62722 +
62723 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62724 +
62725 + return E_OK;
62726 +}
62727 +
62728 +/*****************************************************************************/
62729 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62730 +{
62731 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62732 +
62733 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62734 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62735 +
62736 + /* set the new freqCompensation */
62737 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62738 +
62739 + return E_OK;
62740 +}
62741 +
62742 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62743 +/*****************************************************************************/
62744 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62745 +{
62746 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62747 +
62748 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62749 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62750 +
62751 + /* enable interrupt */
62752 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62753 +
62754 + return E_OK;
62755 +}
62756 +
62757 +/*****************************************************************************/
62758 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62759 +{
62760 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62761 +
62762 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62763 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62764 +
62765 + /* disable interrupt */
62766 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62767 +
62768 + return E_OK;
62769 +}
62770 +#endif
62771 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62772 new file mode 100644
62773 index 00000000..843ca008
62774 --- /dev/null
62775 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62776 @@ -0,0 +1,96 @@
62777 +/*
62778 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62779 + *
62780 + * Redistribution and use in source and binary forms, with or without
62781 + * modification, are permitted provided that the following conditions are met:
62782 + * * Redistributions of source code must retain the above copyright
62783 + * notice, this list of conditions and the following disclaimer.
62784 + * * Redistributions in binary form must reproduce the above copyright
62785 + * notice, this list of conditions and the following disclaimer in the
62786 + * documentation and/or other materials provided with the distribution.
62787 + * * Neither the name of Freescale Semiconductor nor the
62788 + * names of its contributors may be used to endorse or promote products
62789 + * derived from this software without specific prior written permission.
62790 + *
62791 + *
62792 + * ALTERNATIVELY, this software may be distributed under the terms of the
62793 + * GNU General Public License ("GPL") as published by the Free Software
62794 + * Foundation, either version 2 of that License or (at your option) any
62795 + * later version.
62796 + *
62797 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62798 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62799 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62800 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62801 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62802 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62803 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62804 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62805 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62806 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62807 + */
62808 +
62809 +
62810 +/******************************************************************************
62811 + @File fm_rtc.h
62812 +
62813 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62814 +
62815 + @Cautions None
62816 +*//***************************************************************************/
62817 +
62818 +#ifndef __FM_RTC_H__
62819 +#define __FM_RTC_H__
62820 +
62821 +#include "std_ext.h"
62822 +#include "fm_rtc_ext.h"
62823 +
62824 +
62825 +#define __ERR_MODULE__ MODULE_FM_RTC
62826 +
62827 +/* General definitions */
62828 +
62829 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62830 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62831 +#define DEFAULT_BYPASS FALSE
62832 +#define DEFAULT_CLOCK_PERIOD 1000
62833 +
62834 +
62835 +
62836 +typedef struct t_FmRtcAlarm
62837 +{
62838 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62839 + bool clearOnExpiration;
62840 +} t_FmRtcAlarm;
62841 +
62842 +typedef struct t_FmRtcPeriodicPulse
62843 +{
62844 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62845 +} t_FmRtcPeriodicPulse;
62846 +
62847 +typedef struct t_FmRtcExternalTrigger
62848 +{
62849 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62850 +} t_FmRtcExternalTrigger;
62851 +
62852 +
62853 +/**************************************************************************//**
62854 + @Description RTC FM driver control structure.
62855 +*//***************************************************************************/
62856 +typedef struct t_FmRtc
62857 +{
62858 + t_Part *p_Part; /**< Pointer to the integration device */
62859 + t_Handle h_Fm;
62860 + t_Handle h_App; /**< Application handle */
62861 + struct rtc_regs *p_MemMap;
62862 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62863 + uint32_t srcClkFreqMhz;
62864 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62865 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62866 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62867 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62868 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62869 +} t_FmRtc;
62870 +
62871 +
62872 +#endif /* __FM_RTC_H__ */
62873 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62874 new file mode 100755
62875 index 00000000..acdf507e
62876 --- /dev/null
62877 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62878 @@ -0,0 +1,334 @@
62879 +/*
62880 + * Copyright 2008-2013 Freescale Semiconductor Inc.
62881 + *
62882 + * Redistribution and use in source and binary forms, with or without
62883 + * modification, are permitted provided that the following conditions are met:
62884 + * * Redistributions of source code must retain the above copyright
62885 + * notice, this list of conditions and the following disclaimer.
62886 + * * Redistributions in binary form must reproduce the above copyright
62887 + * notice, this list of conditions and the following disclaimer in the
62888 + * documentation and/or other materials provided with the distribution.
62889 + * * Neither the name of Freescale Semiconductor nor the
62890 + * names of its contributors may be used to endorse or promote products
62891 + * derived from this software without specific prior written permission.
62892 + *
62893 + *
62894 + * ALTERNATIVELY, this software may be distributed under the terms of the
62895 + * GNU General Public License ("GPL") as published by the Free Software
62896 + * Foundation, either version 2 of that License or (at your option) any
62897 + * later version.
62898 + *
62899 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62900 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62901 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62902 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62903 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62904 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62905 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62906 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62907 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62908 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62909 + */
62910 +
62911 +#include "fsl_fman_rtc.h"
62912 +
62913 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
62914 +{
62915 + int i;
62916 + cfg->src_clk = DEFAULT_SRC_CLOCK;
62917 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
62918 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
62919 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
62920 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
62921 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
62922 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
62923 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
62924 +}
62925 +
62926 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
62927 +{
62928 + return ioread32be(&regs->tmr_tevent);
62929 +}
62930 +
62931 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
62932 +{
62933 + return ioread32be(&regs->tmr_tevent) & ev_mask;
62934 +}
62935 +
62936 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
62937 +{
62938 + return ioread32be(&regs->tmr_temask);
62939 +}
62940 +
62941 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
62942 +{
62943 + iowrite32be(mask, &regs->tmr_temask);
62944 +}
62945 +
62946 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
62947 +{
62948 + iowrite32be(events, &regs->tmr_tevent);
62949 +}
62950 +
62951 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
62952 +{
62953 + uint32_t event;
62954 +
62955 + event = ioread32be(&regs->tmr_tevent);
62956 + event &= ioread32be(&regs->tmr_temask);
62957 +
62958 + if (event)
62959 + iowrite32be(event, &regs->tmr_tevent);
62960 + return event;
62961 +}
62962 +
62963 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
62964 +{
62965 + return ioread32be(&regs->tmr_add);
62966 +}
62967 +
62968 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
62969 +{
62970 + iowrite32be(val, &regs->tmr_add);
62971 +}
62972 +
62973 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
62974 +{
62975 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
62976 +}
62977 +
62978 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
62979 +{
62980 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
62981 +}
62982 +
62983 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
62984 +{
62985 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
62986 +}
62987 +
62988 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
62989 +{
62990 + iowrite32be(val, &regs->tmr_fiper[index]);
62991 +}
62992 +
62993 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
62994 +{
62995 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
62996 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
62997 +}
62998 +
62999 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
63000 +{
63001 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
63002 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
63003 +}
63004 +
63005 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
63006 +{
63007 + uint64_t time;
63008 + /* TMR_CNT_L must be read first to get an accurate value */
63009 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
63010 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
63011 + << 32);
63012 +
63013 + return time;
63014 +}
63015 +
63016 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
63017 +{
63018 + return ioread32be(&regs->tmr_ctrl);
63019 +}
63020 +
63021 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
63022 +{
63023 + iowrite32be(val, &regs->tmr_ctrl);
63024 +}
63025 +
63026 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
63027 +{
63028 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
63029 + udelay(10);
63030 + fman_rtc_set_timer_ctrl(regs, 0);
63031 +}
63032 +
63033 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
63034 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
63035 + uint32_t freq_compensation, uint32_t output_clock_divisor)
63036 +{
63037 + uint32_t tmr_ctrl;
63038 + int i;
63039 +
63040 + fman_rtc_timers_soft_reset(regs);
63041 +
63042 + /* Set the source clock */
63043 + switch (cfg->src_clk) {
63044 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
63045 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
63046 + break;
63047 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
63048 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
63049 + break;
63050 + default:
63051 + /* Use a clock from the External TMR reference clock.*/
63052 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
63053 + break;
63054 + }
63055 +
63056 + /* whatever period the user picked, the timestamp will advance in '1'
63057 + * every time the period passed. */
63058 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
63059 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
63060 +
63061 + if (cfg->invert_input_clk_phase)
63062 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
63063 + if (cfg->invert_output_clk_phase)
63064 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
63065 +
63066 + for (i = 0; i < num_alarms; i++) {
63067 + if (cfg->alarm_polarity[i] ==
63068 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
63069 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
63070 + }
63071 +
63072 + for (i = 0; i < num_ext_triggers; i++)
63073 + if (cfg->trigger_polarity[i] ==
63074 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
63075 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
63076 +
63077 + if (!cfg->timer_slave_mode && cfg->bypass)
63078 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
63079 +
63080 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
63081 + if (init_freq_comp)
63082 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
63083 +
63084 + /* Clear TMR_ALARM registers */
63085 + for (i = 0; i < num_alarms; i++)
63086 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
63087 +
63088 + /* Clear TMR_TEVENT */
63089 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
63090 +
63091 + /* Initialize TMR_TEMASK */
63092 + fman_rtc_set_interrupt_mask(regs, 0);
63093 +
63094 + /* Clear TMR_FIPER registers */
63095 + for (i = 0; i < num_fipers; i++)
63096 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
63097 +
63098 + /* Initialize TMR_PRSC */
63099 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
63100 +
63101 + /* Clear TMR_OFF */
63102 + fman_rtc_set_timer_offset(regs, 0);
63103 +}
63104 +
63105 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
63106 +{
63107 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
63108 +}
63109 +
63110 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
63111 +{
63112 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
63113 +
63114 + /* TODO check that no timestamping MACs are working in this stage. */
63115 + if (reset_clock) {
63116 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
63117 +
63118 + udelay(10);
63119 + /* Clear TMR_OFF */
63120 + fman_rtc_set_timer_offset(regs, 0);
63121 + }
63122 +
63123 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
63124 +}
63125 +
63126 +void fman_rtc_disable(struct rtc_regs *regs)
63127 +{
63128 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
63129 + & ~(FMAN_RTC_TMR_CTRL_TE)));
63130 +}
63131 +
63132 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
63133 +{
63134 + uint32_t tmp_reg;
63135 + if (id == 0)
63136 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
63137 + else
63138 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
63139 + fman_rtc_disable_interupt(regs, tmp_reg);
63140 +
63141 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
63142 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
63143 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
63144 +
63145 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
63146 +}
63147 +
63148 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
63149 +{
63150 + uint32_t tmpReg, tmp_ctrl;
63151 +
63152 + if (id == 0)
63153 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63154 + else
63155 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63156 + fman_rtc_disable_interupt(regs, tmpReg);
63157 +
63158 + if (id == 0)
63159 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63160 + else
63161 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63162 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
63163 + if (tmp_ctrl & tmpReg)
63164 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
63165 +}
63166 +
63167 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
63168 +{
63169 + uint32_t tmpReg;
63170 + fman_rtc_set_timer_alarm(regs, id, val);
63171 + if (enable) {
63172 + if (id == 0)
63173 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
63174 + else
63175 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
63176 + fman_rtc_enable_interupt(regs, tmpReg);
63177 + }
63178 +}
63179 +
63180 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
63181 + bool enable)
63182 +{
63183 + uint32_t tmpReg;
63184 + fman_rtc_set_timer_fiper(regs, id, val);
63185 + if (enable) {
63186 + if (id == 0)
63187 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
63188 + else
63189 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
63190 + fman_rtc_enable_interupt(regs, tmpReg);
63191 + }
63192 +}
63193 +
63194 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
63195 + bool use_pulse_as_input)
63196 +{
63197 + uint32_t tmpReg;
63198 + if (enable) {
63199 + if (id == 0)
63200 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63201 + else
63202 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63203 + fman_rtc_enable_interupt(regs, tmpReg);
63204 + }
63205 + if (use_pulse_as_input) {
63206 + if (id == 0)
63207 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63208 + else
63209 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63210 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
63211 + }
63212 +}
63213 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63214 new file mode 100644
63215 index 00000000..fae50ce4
63216 --- /dev/null
63217 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63218 @@ -0,0 +1,15 @@
63219 +#
63220 +# Makefile for the Freescale Ethernet controllers
63221 +#
63222 +ccflags-y += -DVERSION=\"\"
63223 +#
63224 +#Include netcomm SW specific definitions
63225 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63226 +
63227 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63228 +
63229 +ccflags-y += -I$(NCSW_FM_INC)
63230 +
63231 +obj-y += fsl-ncsw-sp.o
63232 +
63233 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
63234 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63235 new file mode 100644
63236 index 00000000..0994f34d
63237 --- /dev/null
63238 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63239 @@ -0,0 +1,757 @@
63240 +/*
63241 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63242 + *
63243 + * Redistribution and use in source and binary forms, with or without
63244 + * modification, are permitted provided that the following conditions are met:
63245 + * * Redistributions of source code must retain the above copyright
63246 + * notice, this list of conditions and the following disclaimer.
63247 + * * Redistributions in binary form must reproduce the above copyright
63248 + * notice, this list of conditions and the following disclaimer in the
63249 + * documentation and/or other materials provided with the distribution.
63250 + * * Neither the name of Freescale Semiconductor nor the
63251 + * names of its contributors may be used to endorse or promote products
63252 + * derived from this software without specific prior written permission.
63253 + *
63254 + *
63255 + * ALTERNATIVELY, this software may be distributed under the terms of the
63256 + * GNU General Public License ("GPL") as published by the Free Software
63257 + * Foundation, either version 2 of that License or (at your option) any
63258 + * later version.
63259 + *
63260 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63261 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63262 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63263 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63264 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63265 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63266 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63267 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63268 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63269 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63270 + */
63271 +
63272 +
63273 +/******************************************************************************
63274 + @File fm_sp.c
63275 +
63276 + @Description FM PCD Storage profile ...
63277 +*//***************************************************************************/
63278 +
63279 +#include "std_ext.h"
63280 +#include "error_ext.h"
63281 +#include "string_ext.h"
63282 +#include "debug_ext.h"
63283 +#include "net_ext.h"
63284 +
63285 +#include "fm_vsp_ext.h"
63286 +#include "fm_sp.h"
63287 +#include "fm_common.h"
63288 +#include "fsl_fman_sp.h"
63289 +
63290 +
63291 +#if (DPAA_VERSION >= 11)
63292 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63293 +{
63294 + t_Error err = E_OK;
63295 +
63296 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63297 + RETURN_ERROR(MAJOR, err, NO_MSG);
63298 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63299 + RETURN_ERROR(MAJOR, err, NO_MSG);
63300 + return err;
63301 +
63302 +}
63303 +
63304 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63305 +{
63306 + t_Error err = E_OK;
63307 +
63308 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63309 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63310 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63311 +
63312 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63313 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63314 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63315 +
63316 + RETURN_ERROR(MAJOR, err, NO_MSG);
63317 +
63318 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63319 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63320 +
63321 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63322 + p_FmVspEntry->portType,
63323 + p_FmVspEntry->portId,
63324 + p_FmVspEntry->relativeProfileId);
63325 +
63326 + return err;
63327 +}
63328 +#endif /* (DPAA_VERSION >= 11) */
63329 +
63330 +
63331 +/*****************************************************************************/
63332 +/* Inter-module API routines */
63333 +/*****************************************************************************/
63334 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63335 + uint8_t *orderedArray,
63336 + uint16_t *sizesArray)
63337 +{
63338 + uint16_t bufSize = 0;
63339 + int i=0, j=0, k=0;
63340 +
63341 + /* First we copy the external buffers pools information to an ordered local array */
63342 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63343 + {
63344 + /* get pool size */
63345 + bufSize = p_FmExtPools->extBufPool[i].size;
63346 +
63347 + /* keep sizes in an array according to poolId for direct access */
63348 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63349 +
63350 + /* save poolId in an ordered array according to size */
63351 + for (j=0;j<=i;j++)
63352 + {
63353 + /* this is the next free place in the array */
63354 + if (j==i)
63355 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63356 + else
63357 + {
63358 + /* find the right place for this poolId */
63359 + if (bufSize < sizesArray[orderedArray[j]])
63360 + {
63361 + /* move the poolIds one place ahead to make room for this poolId */
63362 + for (k=i;k>j;k--)
63363 + orderedArray[k] = orderedArray[k-1];
63364 +
63365 + /* now k==j, this is the place for the new size */
63366 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63367 + break;
63368 + }
63369 + }
63370 + }
63371 + }
63372 +}
63373 +
63374 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63375 + t_FmBackupBmPools *p_FmBackupBmPools,
63376 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63377 +{
63378 +
63379 + int i = 0, j = 0;
63380 + bool found;
63381 + uint8_t count = 0;
63382 +
63383 + if (p_FmExtPools)
63384 + {
63385 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63386 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63387 +
63388 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63389 + {
63390 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63391 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63392 + if (!p_FmExtPools->extBufPool[i].size)
63393 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63394 + }
63395 + }
63396 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63397 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63398 +
63399 + /* backup BM pools indication is valid only for some chip derivatives
63400 + (limited by the config routine) */
63401 + if (p_FmBackupBmPools)
63402 + {
63403 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63404 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63405 + found = FALSE;
63406 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63407 + {
63408 +
63409 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63410 + {
63411 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63412 + {
63413 + found = TRUE;
63414 + break;
63415 + }
63416 + }
63417 + if (!found)
63418 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63419 + else
63420 + found = FALSE;
63421 + }
63422 + }
63423 +
63424 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63425 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63426 + {
63427 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63428 + 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));
63429 +
63430 + if (!p_FmBufPoolDepletion->numOfPools)
63431 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63432 +
63433 + found = FALSE;
63434 + count = 0;
63435 + /* for each pool that is in poolsToConsider, check if it is defined
63436 + in extBufPool */
63437 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63438 + {
63439 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63440 + {
63441 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63442 + {
63443 + if (i == p_FmExtPools->extBufPool[j].id)
63444 + {
63445 + found = TRUE;
63446 + count++;
63447 + break;
63448 + }
63449 + }
63450 + if (!found)
63451 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63452 + else
63453 + found = FALSE;
63454 + }
63455 + }
63456 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63457 + if (count != p_FmBufPoolDepletion->numOfPools)
63458 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63459 + }
63460 +
63461 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63462 + {
63463 + /* calculate vector for number of pools depletion */
63464 + found = FALSE;
63465 + count = 0;
63466 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63467 + {
63468 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63469 + {
63470 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63471 + {
63472 + if (i == p_FmExtPools->extBufPool[j].id)
63473 + {
63474 + found = TRUE;
63475 + count++;
63476 + break;
63477 + }
63478 + }
63479 + if (!found)
63480 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63481 + else
63482 + found = FALSE;
63483 + }
63484 + }
63485 + if (!count)
63486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63487 + }
63488 +
63489 + return E_OK;
63490 +}
63491 +
63492 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63493 +{
63494 + /* Check that divisible by 16 and not larger than 240 */
63495 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63496 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63497 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63498 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63499 +
63500 + /* check that ic size+ic internal offset, does not exceed ic block size */
63501 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63502 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63503 + /* Check that divisible by 16 and not larger than 256 */
63504 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63505 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63506 +
63507 + /* Check that divisible by 16 and not larger than 4K */
63508 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63509 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63510 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63512 +
63513 + return E_OK;
63514 +}
63515 +
63516 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63517 +{
63518 + /* Check the margin definition */
63519 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63520 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63521 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63522 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63523 +
63524 + return E_OK;
63525 +}
63526 +
63527 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63528 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63529 + t_FmSpBufMargins *p_FmSpBufMargins,
63530 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63531 + uint8_t *internalBufferOffset)
63532 +{
63533 + uint32_t tmp;
63534 +
63535 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63536 + ASSERT_COND(p_FmSpIntContextDataCopy);
63537 + ASSERT_COND(p_BufferPrefixContent);
63538 + ASSERT_COND(p_FmSpBufMargins);
63539 + ASSERT_COND(p_FmSpBufferOffsets);
63540 +
63541 + /* Align start of internal context data to 16 byte */
63542 + p_FmSpIntContextDataCopy->extBufOffset =
63543 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63544 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63545 + p_BufferPrefixContent->privDataSize);
63546 +
63547 + /* Translate margin and intContext params to FM parameters */
63548 + /* Initialize with illegal value. Later we'll set legal values. */
63549 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63550 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63551 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63552 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63553 +
63554 + /* Internally the driver supports 4 options
63555 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63556 + relate to it as 1).
63557 + 2. All IC context (from AD) not including debug.*/
63558 +
63559 + /* This 'if' covers option 2. We copy from beginning of context. */
63560 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63561 + {
63562 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63563 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63564 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63565 +
63566 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63567 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63568 + if (p_BufferPrefixContent->passPrsResult)
63569 + p_FmSpBufferOffsets->prsResultOffset =
63570 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63571 + if (p_BufferPrefixContent->passTimeStamp)
63572 + p_FmSpBufferOffsets->timeStampOffset =
63573 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63574 + if (p_BufferPrefixContent->passHashResult)
63575 + p_FmSpBufferOffsets->hashResultOffset =
63576 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63577 + }
63578 + else
63579 + {
63580 + /* This case covers the options under 1 */
63581 + /* Copy size must be in 16-byte granularity. */
63582 + p_FmSpIntContextDataCopy->size =
63583 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63584 + ((p_BufferPrefixContent->passTimeStamp ||
63585 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63586 +
63587 + /* Align start of internal context data to 16 byte */
63588 + p_FmSpIntContextDataCopy->intContextOffset =
63589 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63590 + ((p_BufferPrefixContent->passTimeStamp ||
63591 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63592 +
63593 + if (p_BufferPrefixContent->passPrsResult)
63594 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63595 + if (p_BufferPrefixContent->passTimeStamp)
63596 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63597 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63598 + p_FmSpIntContextDataCopy->extBufOffset;
63599 + if (p_BufferPrefixContent->passHashResult)
63600 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63601 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63602 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63603 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63604 + }
63605 +
63606 + if (p_FmSpIntContextDataCopy->size)
63607 + p_FmSpBufMargins->startMargins =
63608 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63609 + p_FmSpIntContextDataCopy->size);
63610 + else
63611 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63612 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63613 +
63614 + /* save extra space for manip in both external and internal buffers */
63615 + if (p_BufferPrefixContent->manipExtraSpace)
63616 + {
63617 + uint8_t extraSpace;
63618 +#ifdef FM_CAPWAP_SUPPORT
63619 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63620 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63621 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63622 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63623 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63624 +#else
63625 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63626 +#endif /* FM_CAPWAP_SUPPORT */
63627 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63628 + p_FmSpBufMargins->startMargins += extraSpace;
63629 + *internalBufferOffset = extraSpace;
63630 + }
63631 +
63632 + /* align data start */
63633 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63634 + if (tmp)
63635 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63636 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63637 +
63638 + return E_OK;
63639 +}
63640 +/*********************** End of inter-module routines ************************/
63641 +
63642 +
63643 +#if (DPAA_VERSION >= 11)
63644 +/*****************************************************************************/
63645 +/* API routines */
63646 +/*****************************************************************************/
63647 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63648 +{
63649 + t_FmVspEntry *p_FmVspEntry = NULL;
63650 + struct fm_storage_profile_params fm_vsp_params;
63651 +
63652 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63653 + if (!p_FmVspEntry)
63654 + {
63655 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63656 + return NULL;
63657 + }
63658 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63659 +
63660 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63661 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63662 + {
63663 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63664 + XX_Free(p_FmVspEntry);
63665 + return NULL;
63666 + }
63667 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63668 + fman_vsp_defconfig(&fm_vsp_params);
63669 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63670 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63671 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63672 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63673 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63674 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63675 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63676 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63677 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63678 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63679 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63680 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63681 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63682 +
63683 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63684 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63685 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63686 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63687 +
63688 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63689 +
63690 + return p_FmVspEntry;
63691 +}
63692 +
63693 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63694 +{
63695 +
63696 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63697 + struct fm_storage_profile_params fm_vsp_params;
63698 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63699 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63700 + t_Error err;
63701 + uint16_t absoluteProfileId = 0;
63702 + int i = 0;
63703 +
63704 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63705 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63706 +
63707 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63708 +
63709 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63710 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63711 +
63712 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63713 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63714 + &p_FmVspEntry->bufMargins,
63715 + &p_FmVspEntry->bufferOffsets,
63716 + &p_FmVspEntry->internalBufferOffset);
63717 + if (err != E_OK)
63718 + RETURN_ERROR(MAJOR, err, NO_MSG);
63719 +
63720 +
63721 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63722 + if (err != E_OK)
63723 + RETURN_ERROR(MAJOR, err, NO_MSG);
63724 +
63725 +
63726 + p_FmVspEntry->p_FmSpRegsBase =
63727 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63728 + if (!p_FmVspEntry->p_FmSpRegsBase)
63729 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63730 +
63731 + /* order external buffer pools in ascending order of buffer pools sizes */
63732 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63733 + orderedArray,
63734 + sizesArray);
63735 +
63736 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63737 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63738 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63739 + {
63740 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63741 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63742 + }
63743 +
63744 + /* on user responsibility to fill it according requirement */
63745 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63746 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63747 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63748 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63749 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63750 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63751 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63752 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63753 +
63754 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63755 + {
63756 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63757 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63758 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63759 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63760 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63761 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63762 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63763 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63764 + }
63765 + else
63766 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63767 +
63768 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63769 + {
63770 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63771 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63772 + }
63773 + else
63774 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63775 +
63776 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63777 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63778 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63779 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63780 +
63781 + /* no check on err - it was checked earlier */
63782 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63783 + p_FmVspEntry->portType,
63784 + p_FmVspEntry->portId,
63785 + p_FmVspEntry->relativeProfileId,
63786 + &absoluteProfileId);
63787 +
63788 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63789 + ASSERT_COND(fm_vsp_params.int_context);
63790 + ASSERT_COND(fm_vsp_params.buf_margins);
63791 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63792 +
63793 + /* Set all registers related to VSP */
63794 + 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);
63795 +
63796 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63797 +
63798 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63799 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63800 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63801 +
63802 + return E_OK;
63803 +}
63804 +
63805 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63806 +{
63807 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63808 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63809 + XX_Free(p_FmVspEntry);
63810 + return E_OK;
63811 +}
63812 +
63813 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
63814 +{
63815 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63816 +
63817 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63818 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63819 +
63820 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63821 + /* if dataAlign was not initialized by user, we return to driver's default */
63822 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63823 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63824 +
63825 + return E_OK;
63826 +}
63827 +
63828 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63829 +{
63830 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63831 +
63832 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63833 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63834 +
63835 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63836 +
63837 + return E_OK;
63838 +}
63839 +
63840 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63841 +{
63842 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63843 +
63844 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63845 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63846 +
63847 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63848 +
63849 + return E_OK;
63850 +}
63851 +
63852 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63853 +{
63854 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63855 +
63856 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63857 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63858 +
63859 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63860 +
63861 + return E_OK;
63862 +}
63863 +
63864 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63865 +{
63866 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63867 +
63868 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63869 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63870 +
63871 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63872 +
63873 + return E_OK;
63874 +}
63875 +
63876 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
63877 +{
63878 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63879 +
63880 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63881 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63882 +
63883 +
63884 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
63885 +
63886 + return E_OK;
63887 +}
63888 +
63889 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
63890 +{
63891 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63892 +
63893 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63894 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63895 +
63896 +
63897 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
63898 +
63899 + return E_OK;
63900 +}
63901 +
63902 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
63903 +{
63904 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63905 +
63906 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63907 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63908 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
63909 +
63910 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
63911 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63912 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
63913 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
63914 +
63915 + return E_OK;
63916 +}
63917 +
63918 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
63919 +{
63920 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63921 +
63922 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63923 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63924 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
63925 +
63926 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
63927 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63928 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
63929 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
63930 +
63931 + return E_OK;
63932 +}
63933 +
63934 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
63935 +{
63936 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63937 +
63938 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
63939 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
63940 +
63941 + return p_FmVspEntry->bufferOffsets.dataOffset;
63942 +}
63943 +
63944 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
63945 +{
63946 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63947 +
63948 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63949 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63950 +
63951 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
63952 + return NULL;
63953 +
63954 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
63955 +}
63956 +
63957 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
63958 +{
63959 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63960 +
63961 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63962 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63963 +
63964 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
63965 + return NULL;
63966 +
63967 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
63968 +}
63969 +
63970 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
63971 +{
63972 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63973 +
63974 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63975 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63976 +
63977 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
63978 + return NULL;
63979 +
63980 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
63981 +}
63982 +
63983 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
63984 +{
63985 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63986 +
63987 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63988 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63989 +
63990 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
63991 + return NULL;
63992 +
63993 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
63994 +}
63995 +
63996 +#endif /* (DPAA_VERSION >= 11) */
63997 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
63998 new file mode 100644
63999 index 00000000..9c171d85
64000 --- /dev/null
64001 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
64002 @@ -0,0 +1,85 @@
64003 +/*
64004 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64005 + *
64006 + * Redistribution and use in source and binary forms, with or without
64007 + * modification, are permitted provided that the following conditions are met:
64008 + * * Redistributions of source code must retain the above copyright
64009 + * notice, this list of conditions and the following disclaimer.
64010 + * * Redistributions in binary form must reproduce the above copyright
64011 + * notice, this list of conditions and the following disclaimer in the
64012 + * documentation and/or other materials provided with the distribution.
64013 + * * Neither the name of Freescale Semiconductor nor the
64014 + * names of its contributors may be used to endorse or promote products
64015 + * derived from this software without specific prior written permission.
64016 + *
64017 + *
64018 + * ALTERNATIVELY, this software may be distributed under the terms of the
64019 + * GNU General Public License ("GPL") as published by the Free Software
64020 + * Foundation, either version 2 of that License or (at your option) any
64021 + * later version.
64022 + *
64023 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64024 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64025 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64026 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64027 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64028 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64029 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64030 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64031 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64032 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64033 + */
64034 +
64035 +
64036 +/******************************************************************************
64037 + @File fm_sp.h
64038 +
64039 + @Description FM SP ...
64040 +*//***************************************************************************/
64041 +#ifndef __FM_SP_H
64042 +#define __FM_SP_H
64043 +
64044 +#include "std_ext.h"
64045 +#include "error_ext.h"
64046 +#include "list_ext.h"
64047 +
64048 +#include "fm_sp_common.h"
64049 +#include "fm_common.h"
64050 +
64051 +
64052 +#define __ERR_MODULE__ MODULE_FM_SP
64053 +
64054 +typedef struct {
64055 + t_FmBufferPrefixContent bufferPrefixContent;
64056 + e_FmDmaSwapOption dmaSwapData;
64057 + e_FmDmaCacheOption dmaIntContextCacheAttr;
64058 + e_FmDmaCacheOption dmaHeaderCacheAttr;
64059 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
64060 + bool dmaWriteOptimize;
64061 + uint16_t liodnOffset;
64062 + bool noScatherGather;
64063 + t_FmBufPoolDepletion *p_BufPoolDepletion;
64064 + t_FmBackupBmPools *p_BackupBmPools;
64065 + t_FmExtPools extBufPools;
64066 +} t_FmVspEntryDriverParams;
64067 +
64068 +typedef struct {
64069 + bool valid;
64070 + volatile bool lock;
64071 + uint8_t pointedOwners;
64072 + uint16_t absoluteSpId;
64073 + uint8_t internalBufferOffset;
64074 + t_FmSpBufMargins bufMargins;
64075 + t_FmSpIntContextDataCopy intContext;
64076 + t_FmSpBufferOffsets bufferOffsets;
64077 + t_Handle h_Fm;
64078 + e_FmPortType portType; /**< Port type */
64079 + uint8_t portId; /**< Port Id - relative to type */
64080 + uint8_t relativeProfileId;
64081 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
64082 + t_FmExtPools extBufPools;
64083 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
64084 +} t_FmVspEntry;
64085 +
64086 +
64087 +#endif /* __FM_SP_H */
64088 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
64089 new file mode 100755
64090 index 00000000..0f772e91
64091 --- /dev/null
64092 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
64093 @@ -0,0 +1,197 @@
64094 +/*
64095 + * Copyright 2013 Freescale Semiconductor Inc.
64096 + *
64097 + * Redistribution and use in source and binary forms, with or without
64098 + * modification, are permitted provided that the following conditions are met:
64099 + * * Redistributions of source code must retain the above copyright
64100 + * notice, this list of conditions and the following disclaimer.
64101 + * * Redistributions in binary form must reproduce the above copyright
64102 + * notice, this list of conditions and the following disclaimer in the
64103 + * documentation and/or other materials provided with the distribution.
64104 + * * Neither the name of Freescale Semiconductor nor the
64105 + * names of its contributors may be used to endorse or promote products
64106 + * derived from this software without specific prior written permission.
64107 + *
64108 + *
64109 + * ALTERNATIVELY, this software may be distributed under the terms of the
64110 + * GNU General Public License ("GPL") as published by the Free Software
64111 + * Foundation, either version 2 of that License or (at your option) any
64112 + * later version.
64113 + *
64114 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64115 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64116 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64117 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64118 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64119 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64120 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64121 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64122 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64123 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64124 + */
64125 +
64126 +#include "fsl_fman_sp.h"
64127 +
64128 +
64129 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
64130 + uint16_t index)
64131 +{
64132 + struct fm_pcd_storage_profile_regs *sp_regs;
64133 + sp_regs = &regs[index];
64134 + return ioread32be(&sp_regs->fm_sp_acnt);
64135 +}
64136 +
64137 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
64138 + uint16_t index, uint32_t value)
64139 +{
64140 + struct fm_pcd_storage_profile_regs *sp_regs;
64141 + sp_regs = &regs[index];
64142 + iowrite32be(value, &sp_regs->fm_sp_acnt);
64143 +}
64144 +
64145 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
64146 +{
64147 + cfg->dma_swap_data =
64148 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
64149 + cfg->int_context_cache_attr =
64150 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
64151 + cfg->header_cache_attr =
64152 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
64153 + cfg->scatter_gather_cache_attr =
64154 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
64155 + cfg->dma_write_optimize =
64156 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
64157 + cfg->no_scather_gather =
64158 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
64159 +}
64160 +
64161 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
64162 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
64163 +{
64164 + int i, j;
64165 + uint32_t vector = 0;
64166 + for (i = 0; i < max_pools; i++)
64167 + if (pools[i])
64168 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
64169 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
64170 + vector |= mask >> j;
64171 + break;
64172 + }
64173 + return vector;
64174 +}
64175 +
64176 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
64177 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
64178 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
64179 + int max_num_of_pfc_priorities)
64180 +{
64181 + int i = 0, j = 0;
64182 + struct fm_pcd_storage_profile_regs *sp_regs;
64183 + uint32_t tmp_reg, vector;
64184 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
64185 + struct fman_buf_pool_depletion *buf_pool_depletion =
64186 + &fm_vsp_params->buf_pool_depletion;
64187 + struct fman_backup_bm_pools *backup_pools =
64188 + &fm_vsp_params->backup_pools;
64189 + struct fman_sp_int_context_data_copy *int_context_data_copy =
64190 + fm_vsp_params->int_context;
64191 + struct fman_sp_buf_margins *external_buffer_margins =
64192 + fm_vsp_params->buf_margins;
64193 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
64194 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
64195 +
64196 + sp_regs = &regs[index];
64197 +
64198 + /* fill external buffers manager pool information register*/
64199 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
64200 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
64201 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
64202 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
64203 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
64204 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
64205 + /* functionality available only for some deriviatives
64206 + (limited by config) */
64207 + for (j = 0; j < backup_pools->num_backup_pools; j++)
64208 + if (ext_buf_pools->ext_buf_pool[i].id ==
64209 + backup_pools->pool_ids[j]) {
64210 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
64211 + break;
64212 + }
64213 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
64214 + }
64215 +
64216 + /* clear unused pools */
64217 + for (i = ext_buf_pools->num_pools_used;
64218 + i < port_max_num_of_ext_pools; i++)
64219 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
64220 +
64221 + /* fill pool depletion register*/
64222 + tmp_reg = 0;
64223 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
64224 + /* calculate vector for number of pools depletion */
64225 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64226 + pools_to_consider, ext_buf_pools, 0x80000000);
64227 +
64228 + /* configure num of pools and vector for number of pools mode */
64229 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
64230 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
64231 + tmp_reg |= vector;
64232 + }
64233 +
64234 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
64235 + /* calculate vector for number of pools depletion */
64236 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64237 + pools_to_consider_for_single_mode,
64238 + ext_buf_pools, 0x00000080);
64239 +
64240 + /* configure num of pools and vector for number of pools mode */
64241 + tmp_reg |= vector;
64242 + }
64243 +
64244 + /* fill QbbPEV */
64245 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
64246 + vector = 0;
64247 + for (i = 0; i < max_num_of_pfc_priorities; i++)
64248 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
64249 + vector |= 0x00000100 << i;
64250 + tmp_reg |= vector;
64251 + }
64252 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
64253 +
64254 + /* fill dma attributes register */
64255 + tmp_reg = 0;
64256 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
64257 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
64258 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
64259 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
64260 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
64261 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
64262 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
64263 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
64264 + if (fm_vsp_params->dma_write_optimize)
64265 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
64266 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
64267 +
64268 + /* IC parameters - fill internal context parameters register */
64269 + tmp_reg = 0;
64270 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
64271 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
64272 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
64273 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
64274 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
64275 + FMAN_SP_IC_SIZE_SHIFT);
64276 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
64277 +
64278 + /* buffer margins - fill external buffer margins register */
64279 + tmp_reg = 0;
64280 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64281 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64282 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64283 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64284 + if (no_scather_gather)
64285 + tmp_reg |= FMAN_SP_SG_DISABLE;
64286 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64287 +
64288 + /* buffer margins - fill spliodn register */
64289 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64290 +}
64291 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64292 new file mode 100644
64293 index 00000000..a870b47e
64294 --- /dev/null
64295 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64296 @@ -0,0 +1,5216 @@
64297 +/*
64298 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64299 + *
64300 + * Redistribution and use in source and binary forms, with or without
64301 + * modification, are permitted provided that the following conditions are met:
64302 + * * Redistributions of source code must retain the above copyright
64303 + * notice, this list of conditions and the following disclaimer.
64304 + * * Redistributions in binary form must reproduce the above copyright
64305 + * notice, this list of conditions and the following disclaimer in the
64306 + * documentation and/or other materials provided with the distribution.
64307 + * * Neither the name of Freescale Semiconductor nor the
64308 + * names of its contributors may be used to endorse or promote products
64309 + * derived from this software without specific prior written permission.
64310 + *
64311 + *
64312 + * ALTERNATIVELY, this software may be distributed under the terms of the
64313 + * GNU General Public License ("GPL") as published by the Free Software
64314 + * Foundation, either version 2 of that License or (at your option) any
64315 + * later version.
64316 + *
64317 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64318 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64319 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64320 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64321 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64322 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64323 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64324 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64325 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64326 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64327 + */
64328 +
64329 +
64330 +/******************************************************************************
64331 + @File fm.c
64332 +
64333 + @Description FM driver routines implementation.
64334 +*//***************************************************************************/
64335 +#include "std_ext.h"
64336 +#include "error_ext.h"
64337 +#include "xx_ext.h"
64338 +#include "string_ext.h"
64339 +#include "sprint_ext.h"
64340 +#include "debug_ext.h"
64341 +#include "fm_muram_ext.h"
64342 +#include <linux/math64.h>
64343 +
64344 +#include "fm_common.h"
64345 +#include "fm_ipc.h"
64346 +#include "fm.h"
64347 +#ifndef CONFIG_FMAN_ARM
64348 +#include <linux/fsl/svr.h>
64349 +#endif
64350 +#include "fsl_fman.h"
64351 +
64352 +
64353 +/****************************************/
64354 +/* static functions */
64355 +/****************************************/
64356 +
64357 +static volatile bool blockingFlag = FALSE;
64358 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64359 + uint8_t *p_Msg,
64360 + uint8_t *p_Reply,
64361 + uint32_t replyLength,
64362 + t_Error status)
64363 +{
64364 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64365 + blockingFlag = FALSE;
64366 +}
64367 +
64368 +static void FreeInitResources(t_Fm *p_Fm)
64369 +{
64370 + if (p_Fm->camBaseAddr)
64371 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64372 + if (p_Fm->fifoBaseAddr)
64373 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64374 + if (p_Fm->resAddr)
64375 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64376 +}
64377 +
64378 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64379 +{
64380 + t_FMIramRegs *p_Iram;
64381 +
64382 + ASSERT_COND(p_Fm);
64383 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64384 +
64385 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64386 +}
64387 +
64388 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64389 +{
64390 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64391 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64392 +#if (DPAA_VERSION < 11)
64393 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64394 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64395 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64396 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64397 +#endif /* (DPAA_VERSION < 11) */
64398 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64399 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64400 +// 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))
64401 +// 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));
64402 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64403 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64404 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64405 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64406 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64407 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64408 +#if (DPAA_VERSION < 11)
64409 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64410 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64411 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64412 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64413 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64414 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64415 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64416 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64417 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64418 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64419 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64420 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64421 +#else /* (DPAA_VERSION >= 11) */
64422 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64423 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64424 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64425 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64426 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64427 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64428 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64429 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64430 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64431 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64432 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64433 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64434 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64435 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64436 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64437 +#endif /* (DPAA_VERSION < 11) */
64438 +
64439 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64440 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64441 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64442 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64443 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64444 +
64445 +#if (DPAA_VERSION >= 11)
64446 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64447 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64448 +#endif /* (DPAA_VERSION >= 11) */
64449 +
64450 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64451 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64452 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64453 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64454 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64455 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64456 + p_Fm->p_FmStateStruct->totalFifoSize,
64457 + BMI_MAX_FIFO_SIZE));
64458 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64459 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64460 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64461 +
64462 +#ifdef FM_HAS_TOTAL_DMAS
64463 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64464 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64465 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64466 +#endif /* FM_HAS_TOTAL_DMAS */
64467 +
64468 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64469 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64470 +
64471 + if (!p_Fm->f_Exception)
64472 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64473 + if (!p_Fm->f_BusError)
64474 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64475 +
64476 +#ifdef FM_NO_WATCHDOG
64477 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64478 + (p_Fm->p_FmDriverParam->dma_watchdog))
64479 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64480 +#endif /* FM_NO_WATCHDOG */
64481 +
64482 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64483 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64484 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64485 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64486 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64487 +
64488 +#ifdef FM_NO_TNUM_AGING
64489 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64490 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64491 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64492 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64493 +#endif /* FM_NO_TNUM_AGING */
64494 +
64495 + /* check that user did not set revision-dependent exceptions */
64496 +#ifdef FM_NO_DISPATCH_RAM_ECC
64497 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64498 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64499 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64500 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64501 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64502 +
64503 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64504 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64505 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64506 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64507 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64508 +
64509 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64510 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64511 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64512 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64513 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64514 +
64515 + return E_OK;
64516 +}
64517 +
64518 +
64519 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64520 +{
64521 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64522 +
64523 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64524 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64525 +
64526 + /* If the MAC is running on guest-partition and we have IPC session with it,
64527 + we inform him about the event through IPC; otherwise, we ignore the event. */
64528 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64529 + {
64530 + t_Error err;
64531 + t_FmIpcIsr fmIpcIsr;
64532 + t_FmIpcMsg msg;
64533 +
64534 + memset(&msg, 0, sizeof(msg));
64535 + msg.msgId = FM_GUEST_ISR;
64536 + fmIpcIsr.pendingReg = pendingReg;
64537 + fmIpcIsr.boolErr = FALSE;
64538 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64539 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64540 + (uint8_t*)&msg,
64541 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64542 + NULL,
64543 + NULL,
64544 + NULL,
64545 + NULL);
64546 + if (err != E_OK)
64547 + REPORT_ERROR(MINOR, err, NO_MSG);
64548 + }
64549 + else
64550 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64551 +}
64552 +
64553 +static void BmiErrEvent(t_Fm *p_Fm)
64554 +{
64555 + uint32_t event;
64556 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64557 +
64558 +
64559 + event = fman_get_bmi_err_event(bmi_rg);
64560 +
64561 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64562 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64563 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64564 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64565 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64566 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64567 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64568 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64569 +}
64570 +
64571 +static void QmiErrEvent(t_Fm *p_Fm)
64572 +{
64573 + uint32_t event;
64574 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64575 +
64576 + event = fman_get_qmi_err_event(qmi_rg);
64577 +
64578 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64579 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64580 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64581 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64582 +}
64583 +
64584 +static void DmaErrEvent(t_Fm *p_Fm)
64585 +{
64586 + uint32_t status, com_id;
64587 + uint8_t tnum;
64588 + uint8_t hardwarePortId;
64589 + uint8_t relativePortId;
64590 + uint16_t liodn;
64591 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64592 +
64593 + status = fman_get_dma_err_event(dma_rg);
64594 +
64595 + if (status & DMA_STATUS_BUS_ERR)
64596 + {
64597 + com_id = fman_get_dma_com_id(dma_rg);
64598 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64599 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64600 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64601 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64602 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64603 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64604 + p_Fm->f_BusError(p_Fm->h_App,
64605 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64606 + relativePortId,
64607 + fman_get_dma_addr(dma_rg),
64608 + tnum,
64609 + liodn);
64610 + }
64611 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64612 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64613 + if (status & DMA_STATUS_READ_ECC)
64614 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64615 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64616 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64617 + if (status & DMA_STATUS_FM_WRITE_ECC)
64618 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64619 + }
64620 +
64621 +static void FpmErrEvent(t_Fm *p_Fm)
64622 +{
64623 + uint32_t event;
64624 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64625 +
64626 + event = fman_get_fpm_err_event(fpm_rg);
64627 +
64628 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64629 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64630 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64631 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64632 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64633 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64634 +}
64635 +
64636 +static void MuramErrIntr(t_Fm *p_Fm)
64637 +{
64638 + uint32_t event;
64639 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64640 +
64641 + event = fman_get_muram_err_event(fpm_rg);
64642 +
64643 + if (event & FPM_RAM_MURAM_ECC)
64644 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64645 +}
64646 +
64647 +static void IramErrIntr(t_Fm *p_Fm)
64648 +{
64649 + uint32_t event;
64650 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64651 +
64652 + event = fman_get_iram_err_event(fpm_rg);
64653 +
64654 + if (event & FPM_RAM_IRAM_ECC)
64655 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64656 +}
64657 +
64658 +static void QmiEvent(t_Fm *p_Fm)
64659 +{
64660 + uint32_t event;
64661 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64662 +
64663 + event = fman_get_qmi_event(qmi_rg);
64664 +
64665 + if (event & QMI_INTR_EN_SINGLE_ECC)
64666 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64667 +}
64668 +
64669 +static void UnimplementedIsr(t_Handle h_Arg)
64670 +{
64671 + UNUSED(h_Arg);
64672 +
64673 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64674 +}
64675 +
64676 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64677 +{
64678 + UNUSED(h_Arg); UNUSED(event);
64679 +
64680 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64681 +}
64682 +
64683 +static void EnableTimeStamp(t_Fm *p_Fm)
64684 +{
64685 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64686 +
64687 + ASSERT_COND(p_Fm->p_FmStateStruct);
64688 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64689 +
64690 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64691 +
64692 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64693 +}
64694 +
64695 +static t_Error ClearIRam(t_Fm *p_Fm)
64696 +{
64697 + t_FMIramRegs *p_Iram;
64698 + int i;
64699 + int iram_size;
64700 +
64701 + ASSERT_COND(p_Fm);
64702 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64703 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64704 +
64705 + /* Enable the auto-increment */
64706 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64707 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64708 +
64709 + for (i=0; i < (iram_size/4); i++)
64710 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64711 +
64712 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64713 + CORE_MemoryBarrier();
64714 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64715 +
64716 + return E_OK;
64717 +}
64718 +
64719 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64720 +{
64721 + t_FMIramRegs *p_Iram;
64722 + int i;
64723 + uint32_t tmp;
64724 + uint8_t compTo16;
64725 +
64726 + ASSERT_COND(p_Fm);
64727 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64728 +
64729 + /* Enable the auto-increment */
64730 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64731 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64732 +
64733 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64734 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64735 +
64736 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64737 + if (compTo16)
64738 + for (i=0; i < ((16-compTo16) / 4); i++)
64739 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64740 +
64741 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64742 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64743 +
64744 + /* verify that writing has completed */
64745 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64746 +
64747 + if (p_Fm->fwVerify)
64748 + {
64749 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64750 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64751 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64752 + {
64753 + tmp = GET_UINT32(p_Iram->idata);
64754 + if (tmp != p_Fm->firmware.p_Code[i])
64755 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64756 + ("UCode write error : write 0x%x, read 0x%x",
64757 + p_Fm->firmware.p_Code[i],tmp));
64758 + }
64759 + WRITE_UINT32(p_Iram->iadd, 0x0);
64760 + }
64761 +
64762 + /* Enable patch from IRAM */
64763 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64764 + XX_UDelay(1000);
64765 +
64766 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64767 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64768 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64769 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64770 +
64771 + return E_OK;
64772 +}
64773 +
64774 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64775 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64776 +{
64777 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64778 + uint32_t tmpReg;
64779 + uint32_t savedSpliodn[63];
64780 +
64781 + /* write to IRAM first location the debug instruction */
64782 + WRITE_UINT32(p_Iram->iadd, 0);
64783 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64784 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64785 +
64786 + WRITE_UINT32(p_Iram->iadd, 0);
64787 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64788 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64789 +
64790 + /* Enable patch from IRAM */
64791 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64792 + CORE_MemoryBarrier();
64793 + XX_UDelay(100);
64794 + IO2MemCpy32((uint8_t *)savedSpliodn,
64795 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64796 + 63*sizeof(uint32_t));
64797 +
64798 + /* reset FMAN */
64799 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64800 + CORE_MemoryBarrier();
64801 + XX_UDelay(100);
64802 +
64803 + /* verify breakpoint debug status register */
64804 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64805 + if (!tmpReg)
64806 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64807 +
64808 + /*************************************/
64809 + /* Load FMan-Controller code to IRAM */
64810 + /*************************************/
64811 + ClearIRam(p_Fm);
64812 + if (p_Fm->firmware.p_Code &&
64813 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64814 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64815 + XX_UDelay(100);
64816 +
64817 + /* reset FMAN again to start the microcode */
64818 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64819 + CORE_MemoryBarrier();
64820 + XX_UDelay(100);
64821 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64822 + (uint8_t *)savedSpliodn,
64823 + 63*sizeof(uint32_t));
64824 +
64825 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64826 + {
64827 + fman_resume(p_Fm->p_FmFpmRegs);
64828 + CORE_MemoryBarrier();
64829 + XX_UDelay(100);
64830 + }
64831 +
64832 + return E_OK;
64833 +}
64834 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64835 +
64836 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64837 +{
64838 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64839 +do { \
64840 + 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);\
64841 +} while (0)
64842 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64843 +do { \
64844 + 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);\
64845 +} while (0)
64846 +
64847 + /* error interrupts */
64848 + if (pending & ERR_INTR_EN_1G_MAC0)
64849 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64850 + if (pending & ERR_INTR_EN_1G_MAC1)
64851 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64852 + if (pending & ERR_INTR_EN_1G_MAC2)
64853 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64854 + if (pending & ERR_INTR_EN_1G_MAC3)
64855 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64856 + if (pending & ERR_INTR_EN_1G_MAC4)
64857 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64858 + if (pending & ERR_INTR_EN_1G_MAC5)
64859 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64860 + if (pending & ERR_INTR_EN_1G_MAC6)
64861 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64862 + if (pending & ERR_INTR_EN_1G_MAC7)
64863 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64864 + if (pending & ERR_INTR_EN_10G_MAC0)
64865 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64866 + if (pending & ERR_INTR_EN_10G_MAC1)
64867 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64868 +}
64869 +
64870 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64871 +{
64872 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64873 +do { \
64874 + 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);\
64875 +} while (0)
64876 +#define FM_G_CALL_10G_MAC_ISR(_id) \
64877 +do { \
64878 + 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);\
64879 +} while (0)
64880 +
64881 + if (pending & INTR_EN_1G_MAC0)
64882 + FM_G_CALL_1G_MAC_ISR(0);
64883 + if (pending & INTR_EN_1G_MAC1)
64884 + FM_G_CALL_1G_MAC_ISR(1);
64885 + if (pending & INTR_EN_1G_MAC2)
64886 + FM_G_CALL_1G_MAC_ISR(2);
64887 + if (pending & INTR_EN_1G_MAC3)
64888 + FM_G_CALL_1G_MAC_ISR(3);
64889 + if (pending & INTR_EN_1G_MAC4)
64890 + FM_G_CALL_1G_MAC_ISR(4);
64891 + if (pending & INTR_EN_1G_MAC5)
64892 + FM_G_CALL_1G_MAC_ISR(5);
64893 + if (pending & INTR_EN_1G_MAC6)
64894 + FM_G_CALL_1G_MAC_ISR(6);
64895 + if (pending & INTR_EN_1G_MAC7)
64896 + FM_G_CALL_1G_MAC_ISR(7);
64897 + if (pending & INTR_EN_10G_MAC0)
64898 + FM_G_CALL_10G_MAC_ISR(0);
64899 + if (pending & INTR_EN_10G_MAC1)
64900 + FM_G_CALL_10G_MAC_ISR(1);
64901 + if (pending & INTR_EN_TMR)
64902 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
64903 +}
64904 +
64905 +#if (DPAA_VERSION >= 11)
64906 +static t_Error SetVSPWindow(t_Handle h_Fm,
64907 + uint8_t hardwarePortId,
64908 + uint8_t baseStorageProfile,
64909 + uint8_t log2NumOfProfiles)
64910 +{
64911 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64912 +
64913 + ASSERT_COND(h_Fm);
64914 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64915 +
64916 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
64917 + !p_Fm->p_FmBmiRegs &&
64918 + p_Fm->h_IpcSessions[0])
64919 + {
64920 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
64921 + t_FmIpcMsg msg;
64922 + t_Error err = E_OK;
64923 +
64924 + memset(&msg, 0, sizeof(msg));
64925 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
64926 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
64927 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
64928 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
64929 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
64930 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
64931 +
64932 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64933 + (uint8_t*)&msg,
64934 + sizeof(msg.msgId),
64935 + NULL,
64936 + NULL,
64937 + NULL,
64938 + NULL);
64939 + if (err != E_OK)
64940 + RETURN_ERROR(MINOR, err, NO_MSG);
64941 + return E_OK;
64942 + }
64943 + else if (!p_Fm->p_FmBmiRegs)
64944 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
64945 + ("Either IPC or 'baseAddress' is required!"));
64946 +
64947 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
64948 + hardwarePortId,
64949 + baseStorageProfile,
64950 + log2NumOfProfiles);
64951 +
64952 + return E_OK;
64953 +}
64954 +
64955 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64956 +{
64957 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64958 + uint8_t profilesFound = 0;
64959 + int i = 0;
64960 + uint32_t intFlags;
64961 +
64962 + if (!numOfProfiles)
64963 + return E_OK;
64964 +
64965 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
64966 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
64967 + return (uint8_t)ILLEGAL_BASE;
64968 +
64969 + if (p_Fm->h_IpcSessions[0])
64970 + {
64971 + t_FmIpcResourceAllocParams ipcAllocParams;
64972 + t_FmIpcMsg msg;
64973 + t_FmIpcReply reply;
64974 + t_Error err;
64975 + uint32_t replyLength;
64976 +
64977 + memset(&msg, 0, sizeof(msg));
64978 + memset(&reply, 0, sizeof(reply));
64979 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64980 + ipcAllocParams.guestId = p_Fm->guestId;
64981 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64982 + ipcAllocParams.base = p_Fm->partVSPBase;
64983 + msg.msgId = FM_VSP_ALLOC;
64984 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64985 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64986 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64987 + (uint8_t*)&msg,
64988 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64989 + (uint8_t*)&reply,
64990 + &replyLength,
64991 + NULL,
64992 + NULL);
64993 + if ((err != E_OK) ||
64994 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
64995 + RETURN_ERROR(MAJOR, err, NO_MSG);
64996 + else
64997 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
64998 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
64999 + RETURN_ERROR(MAJOR, err, NO_MSG);
65000 + }
65001 + if (p_Fm->guestId != NCSW_MASTER_ID)
65002 + {
65003 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65004 + return (uint8_t)ILLEGAL_BASE;
65005 + }
65006 +
65007 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65008 + for (i = base; i < base + numOfProfiles; i++)
65009 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
65010 + profilesFound++;
65011 + else
65012 + break;
65013 +
65014 + if (profilesFound == numOfProfiles)
65015 + for (i = base; i<base + numOfProfiles; i++)
65016 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
65017 + else
65018 + {
65019 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65020 + return (uint8_t)ILLEGAL_BASE;
65021 + }
65022 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65023 +
65024 + return base;
65025 +}
65026 +
65027 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
65028 +{
65029 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65030 + int i = 0;
65031 +
65032 + ASSERT_COND(p_Fm);
65033 +
65034 + if (p_Fm->h_IpcSessions[0])
65035 + {
65036 + t_FmIpcResourceAllocParams ipcAllocParams;
65037 + t_FmIpcMsg msg;
65038 + t_FmIpcReply reply;
65039 + uint32_t replyLength;
65040 + t_Error err;
65041 +
65042 + memset(&msg, 0, sizeof(msg));
65043 + memset(&reply, 0, sizeof(reply));
65044 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
65045 + ipcAllocParams.guestId = p_Fm->guestId;
65046 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
65047 + ipcAllocParams.base = p_Fm->partVSPBase;
65048 + msg.msgId = FM_VSP_FREE;
65049 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
65050 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65051 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65052 + (uint8_t*)&msg,
65053 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
65054 + (uint8_t*)&reply,
65055 + &replyLength,
65056 + NULL,
65057 + NULL);
65058 + if (err != E_OK)
65059 + REPORT_ERROR(MAJOR, err, NO_MSG);
65060 + return;
65061 + }
65062 + if (p_Fm->guestId != NCSW_MASTER_ID)
65063 + {
65064 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65065 + return;
65066 + }
65067 +
65068 + ASSERT_COND(p_Fm->p_FmSp);
65069 +
65070 + for (i=base; i<numOfProfiles; i++)
65071 + {
65072 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
65073 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
65074 + else
65075 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
65076 + }
65077 +}
65078 +#endif /* (DPAA_VERSION >= 11) */
65079 +
65080 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
65081 + uint8_t *p_Msg,
65082 + uint32_t msgLength,
65083 + uint8_t *p_Reply,
65084 + uint32_t *p_ReplyLength)
65085 +{
65086 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65087 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65088 +
65089 + UNUSED(p_Reply);
65090 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65091 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
65092 +
65093 +#ifdef DISABLE_SANITY_CHECKS
65094 + UNUSED(msgLength);
65095 +#endif /* DISABLE_SANITY_CHECKS */
65096 +
65097 + ASSERT_COND(p_Msg);
65098 +
65099 + *p_ReplyLength = 0;
65100 +
65101 + switch (p_IpcMsg->msgId)
65102 + {
65103 + case (FM_GUEST_ISR):
65104 + {
65105 + t_FmIpcIsr ipcIsr;
65106 +
65107 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
65108 + if (ipcIsr.boolErr)
65109 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
65110 + else
65111 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
65112 + break;
65113 + }
65114 + default:
65115 + *p_ReplyLength = 0;
65116 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65117 + }
65118 + return E_OK;
65119 +}
65120 +
65121 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
65122 + uint8_t *p_Msg,
65123 + uint32_t msgLength,
65124 + uint8_t *p_Reply,
65125 + uint32_t *p_ReplyLength)
65126 +{
65127 + t_Error err;
65128 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65129 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65130 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
65131 +
65132 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65133 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
65134 +
65135 +#ifdef DISABLE_SANITY_CHECKS
65136 + UNUSED(msgLength);
65137 +#endif /* DISABLE_SANITY_CHECKS */
65138 +
65139 + ASSERT_COND(p_IpcMsg);
65140 +
65141 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
65142 + *p_ReplyLength = 0;
65143 +
65144 + switch (p_IpcMsg->msgId)
65145 + {
65146 + case (FM_GET_SET_PORT_PARAMS):
65147 + {
65148 + t_FmIpcPortInInitParams ipcInitParams;
65149 + t_FmInterModulePortInitParams initParams;
65150 + t_FmIpcPortOutInitParams ipcOutInitParams;
65151 +
65152 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
65153 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
65154 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
65155 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
65156 + initParams.liodnOffset = ipcInitParams.liodnOffset;
65157 + initParams.numOfTasks = ipcInitParams.numOfTasks;
65158 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
65159 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
65160 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
65161 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
65162 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
65163 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
65164 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
65165 + initParams.liodnBase = ipcInitParams.liodnBase;
65166 +
65167 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
65168 +
65169 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
65170 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
65171 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
65172 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
65173 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
65174 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
65175 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
65176 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
65177 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
65178 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
65179 + break;
65180 + }
65181 + case (FM_SET_SIZE_OF_FIFO):
65182 + {
65183 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65184 +
65185 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65186 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
65187 + ipcPortRsrcParams.hardwarePortId,
65188 + &ipcPortRsrcParams.val,
65189 + &ipcPortRsrcParams.extra,
65190 + (bool)ipcPortRsrcParams.boolInitialConfig);
65191 + *p_ReplyLength = sizeof(uint32_t);
65192 + break;
65193 + }
65194 + case (FM_SET_NUM_OF_TASKS):
65195 + {
65196 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65197 +
65198 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65199 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
65200 + (uint8_t*)&ipcPortRsrcParams.val,
65201 + (uint8_t*)&ipcPortRsrcParams.extra,
65202 + (bool)ipcPortRsrcParams.boolInitialConfig);
65203 + *p_ReplyLength = sizeof(uint32_t);
65204 + break;
65205 + }
65206 + case (FM_SET_NUM_OF_OPEN_DMAS):
65207 + {
65208 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65209 +
65210 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65211 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
65212 + (uint8_t*)&ipcPortRsrcParams.val,
65213 + (uint8_t*)&ipcPortRsrcParams.extra,
65214 + (bool)ipcPortRsrcParams.boolInitialConfig);
65215 + *p_ReplyLength = sizeof(uint32_t);
65216 + break;
65217 + }
65218 + case (FM_RESUME_STALLED_PORT):
65219 + *p_ReplyLength = sizeof(uint32_t);
65220 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
65221 + break;
65222 + case (FM_MASTER_IS_ALIVE):
65223 + {
65224 + uint8_t guestId = p_IpcMsg->msgBody[0];
65225 + /* build the FM master partition IPC address */
65226 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
65227 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
65228 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
65229 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
65230 + if (p_Fm->h_IpcSessions[guestId] == NULL)
65231 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
65232 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
65233 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65234 + break;
65235 + }
65236 + case (FM_IS_PORT_STALLED):
65237 + {
65238 + bool tmp;
65239 +
65240 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
65241 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
65242 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65243 + break;
65244 + }
65245 + case (FM_RESET_MAC):
65246 + {
65247 + t_FmIpcMacParams ipcMacParams;
65248 +
65249 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
65250 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
65251 + (e_FmMacType)(ipcMacParams.enumType),
65252 + ipcMacParams.id);
65253 + *p_ReplyLength = sizeof(uint32_t);
65254 + break;
65255 + }
65256 + case (FM_SET_MAC_MAX_FRAME):
65257 + {
65258 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
65259 +
65260 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
65261 + err = FmSetMacMaxFrame(p_Fm,
65262 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
65263 + ipcMacMaxFrameParams.macParams.id,
65264 + ipcMacMaxFrameParams.maxFrameLength);
65265 + if (err != E_OK)
65266 + REPORT_ERROR(MINOR, err, NO_MSG);
65267 + break;
65268 + }
65269 +#if (DPAA_VERSION >= 11)
65270 + case (FM_VSP_ALLOC) :
65271 + {
65272 + t_FmIpcResourceAllocParams ipcAllocParams;
65273 + uint8_t vspBase;
65274 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65275 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65276 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
65277 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65278 + break;
65279 + }
65280 + case (FM_VSP_FREE) :
65281 + {
65282 + t_FmIpcResourceAllocParams ipcAllocParams;
65283 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65284 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65285 + break;
65286 + }
65287 + case (FM_VSP_SET_PORT_WINDOW) :
65288 + {
65289 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65290 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65291 + err = SetVSPWindow(h_Fm,
65292 + ipcVspSetPortWindow.hardwarePortId,
65293 + ipcVspSetPortWindow.baseStorageProfile,
65294 + ipcVspSetPortWindow.log2NumOfProfiles);
65295 + return err;
65296 + }
65297 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65298 + {
65299 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65300 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65301 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65302 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65303 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65304 + return err;
65305 + }
65306 +#endif /* (DPAA_VERSION >= 11) */
65307 +
65308 + case (FM_FREE_PORT):
65309 + {
65310 + t_FmInterModulePortFreeParams portParams;
65311 + t_FmIpcPortFreeParams ipcPortParams;
65312 +
65313 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65314 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65315 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65316 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65317 + FmFreePortParams(h_Fm, &portParams);
65318 + break;
65319 + }
65320 + case (FM_REGISTER_INTR):
65321 + {
65322 + t_FmIpcRegisterIntr ipcRegIntr;
65323 +
65324 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65325 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65326 + break;
65327 + }
65328 + case (FM_GET_PARAMS):
65329 + {
65330 + t_FmIpcParams ipcParams;
65331 +
65332 + /* Get clock frequency */
65333 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65334 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65335 +
65336 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65337 +
65338 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65339 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65340 + break;
65341 + }
65342 + case (FM_GET_FMAN_CTRL_CODE_REV):
65343 + {
65344 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65345 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65346 +
65347 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65348 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65349 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65350 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65351 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65352 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65353 + break;
65354 + }
65355 +
65356 + case (FM_DMA_STAT):
65357 + {
65358 + t_FmDmaStatus dmaStatus;
65359 + t_FmIpcDmaStatus ipcDmaStatus;
65360 +
65361 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65362 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65363 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65364 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65365 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65366 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65367 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65368 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65369 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65370 + break;
65371 + }
65372 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65373 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65374 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65375 + break;
65376 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65377 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65378 + break;
65379 + case (FM_GET_TIMESTAMP_SCALE):
65380 + {
65381 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65382 +
65383 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65384 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65385 + break;
65386 + }
65387 + case (FM_GET_COUNTER):
65388 + {
65389 + e_FmCounters inCounter;
65390 + uint32_t outCounter;
65391 +
65392 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65393 + outCounter = FM_GetCounter(h_Fm, inCounter);
65394 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65395 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65396 + break;
65397 + }
65398 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65399 + {
65400 + t_FmIpcFmanEvents ipcFmanEvents;
65401 +
65402 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65403 + FmSetFmanCtrlIntr(h_Fm,
65404 + ipcFmanEvents.eventRegId,
65405 + ipcFmanEvents.enableEvents);
65406 + break;
65407 + }
65408 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65409 + {
65410 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65411 +
65412 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65413 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65414 + break;
65415 + }
65416 + case (FM_GET_PHYS_MURAM_BASE):
65417 + {
65418 + t_FmPhysAddr physAddr;
65419 + t_FmIpcPhysAddr ipcPhysAddr;
65420 +
65421 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65422 + ipcPhysAddr.high = physAddr.high;
65423 + ipcPhysAddr.low = physAddr.low;
65424 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65425 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65426 + break;
65427 + }
65428 + case (FM_ENABLE_RAM_ECC):
65429 + {
65430 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65431 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65432 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65433 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65434 + UNUSED(err);
65435 +#else
65436 + REPORT_ERROR(MINOR, err, NO_MSG);
65437 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65438 + break;
65439 + }
65440 + case (FM_DISABLE_RAM_ECC):
65441 + {
65442 +
65443 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65444 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65445 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65446 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65447 + UNUSED(err);
65448 +#else
65449 + REPORT_ERROR(MINOR, err, NO_MSG);
65450 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65451 + break;
65452 + }
65453 + case (FM_SET_NUM_OF_FMAN_CTRL):
65454 + {
65455 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65456 +
65457 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65458 + err = FmSetNumOfRiscsPerPort(h_Fm,
65459 + ipcPortNumOfFmanCtrls.hardwarePortId,
65460 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65461 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65462 + if (err != E_OK)
65463 + REPORT_ERROR(MINOR, err, NO_MSG);
65464 + break;
65465 + }
65466 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65467 + case (FM_10G_TX_ECC_WA):
65468 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65469 + *p_ReplyLength = sizeof(uint32_t);
65470 + break;
65471 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65472 + default:
65473 + *p_ReplyLength = 0;
65474 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65475 + }
65476 + return E_OK;
65477 +}
65478 +
65479 +
65480 +/****************************************/
65481 +/* Inter-Module functions */
65482 +/****************************************/
65483 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65484 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65485 +{
65486 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65487 + t_Error err = E_OK;
65488 + t_FmIpcMsg msg;
65489 + t_FmIpcReply reply;
65490 + uint32_t replyLength;
65491 + uint8_t rxHardwarePortId, txHardwarePortId;
65492 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65493 +
65494 + if (p_Fm->guestId != NCSW_MASTER_ID)
65495 + {
65496 + memset(&msg, 0, sizeof(msg));
65497 + memset(&reply, 0, sizeof(reply));
65498 + msg.msgId = FM_10G_TX_ECC_WA;
65499 + msg.msgBody[0] = macId;
65500 + replyLength = sizeof(uint32_t);
65501 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65502 + (uint8_t*)&msg,
65503 + sizeof(msg.msgId)+sizeof(macId),
65504 + (uint8_t*)&reply,
65505 + &replyLength,
65506 + NULL,
65507 + NULL)) != E_OK)
65508 + RETURN_ERROR(MINOR, err, NO_MSG);
65509 + if (replyLength != sizeof(uint32_t))
65510 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65511 + return (t_Error)(reply.error);
65512 + }
65513 +
65514 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65515 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65516 +
65517 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65518 + macId,
65519 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65520 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65521 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65522 + macId,
65523 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65524 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65525 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65526 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65527 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65528 + ("MAC should be initialized prior to Rx and Tx ports!"));
65529 +
65530 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65531 +}
65532 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65533 +
65534 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65535 +{
65536 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65537 +
65538 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65539 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65540 +
65541 + return p_Fm->tnumAgingPeriod;
65542 +}
65543 +
65544 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65545 + uint8_t portNum,
65546 + bool preFetchConfigured)
65547 +{
65548 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65549 +
65550 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65551 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65552 +
65553 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65554 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65555 +
65556 + return E_OK;
65557 +}
65558 +
65559 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65560 + uint8_t portNum,
65561 + bool *p_PortConfigured,
65562 + bool *p_PreFetchConfigured)
65563 +{
65564 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65565 +
65566 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65567 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65568 +
65569 + /* If the prefetch wasn't configured yet (not enable or disabled)
65570 + we return the value TRUE as it was already configured */
65571 + if (!p_Fm->portsPreFetchConfigured[portNum])
65572 + {
65573 + *p_PortConfigured = FALSE;
65574 + *p_PreFetchConfigured = FALSE;
65575 + }
65576 + else
65577 + {
65578 + *p_PortConfigured = TRUE;
65579 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65580 + }
65581 +
65582 + return E_OK;
65583 +}
65584 +
65585 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65586 + uint32_t congestionGroupId,
65587 + uint8_t priorityBitMap)
65588 +{
65589 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65590 + uint32_t regNum;
65591 +
65592 + ASSERT_COND(h_Fm);
65593 +
65594 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65595 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65596 + ("Congestion group ID bigger than %d",
65597 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65598 +
65599 + if (p_Fm->guestId == NCSW_MASTER_ID)
65600 + {
65601 + ASSERT_COND(p_Fm->baseAddr);
65602 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65603 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65604 + congestionGroupId,
65605 + priorityBitMap,
65606 + regNum);
65607 + }
65608 + else if (p_Fm->h_IpcSessions[0])
65609 + {
65610 + t_Error err;
65611 + t_FmIpcMsg msg;
65612 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65613 +
65614 + memset(&msg, 0, sizeof(msg));
65615 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65616 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65617 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65618 +
65619 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65620 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65621 +
65622 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65623 + (uint8_t*)&msg,
65624 + sizeof(msg.msgId),
65625 + NULL,
65626 + NULL,
65627 + NULL,
65628 + NULL);
65629 + if (err != E_OK)
65630 + RETURN_ERROR(MINOR, err, NO_MSG);
65631 + }
65632 + else
65633 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65634 +
65635 + return E_OK;
65636 +}
65637 +
65638 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65639 +{
65640 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65641 +
65642 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65643 +
65644 + if (!p_Fm->baseAddr)
65645 + {
65646 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65647 + ("No base-addr; probably Guest with IPC!"));
65648 + return 0;
65649 + }
65650 +
65651 + return (p_Fm->baseAddr + FM_MM_PRS);
65652 +}
65653 +
65654 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65655 +{
65656 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65657 +
65658 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65659 +
65660 + if (!p_Fm->baseAddr)
65661 + {
65662 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65663 + ("No base-addr; probably Guest with IPC!"));
65664 + return 0;
65665 + }
65666 +
65667 + return (p_Fm->baseAddr + FM_MM_KG);
65668 +}
65669 +
65670 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65671 +{
65672 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65673 +
65674 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65675 +
65676 + if (!p_Fm->baseAddr)
65677 + {
65678 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65679 + ("No base-addr; probably Guest with IPC!"));
65680 + return 0;
65681 + }
65682 +
65683 + return (p_Fm->baseAddr + FM_MM_PLCR);
65684 +}
65685 +
65686 +#if (DPAA_VERSION >= 11)
65687 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65688 +{
65689 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65690 +
65691 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65692 +
65693 + return p_Fm->vspBaseAddr;
65694 +}
65695 +#endif /* (DPAA_VERSION >= 11) */
65696 +
65697 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65698 +{
65699 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65700 +
65701 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65702 +
65703 + return (p_Fm->h_FmMuram);
65704 +}
65705 +
65706 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65707 +{
65708 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65709 +
65710 + if (p_Fm->fmMuramPhysBaseAddr)
65711 + {
65712 + /* General FM driver initialization */
65713 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65714 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65715 + return;
65716 + }
65717 +
65718 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65719 +
65720 + if (p_Fm->h_IpcSessions[0])
65721 + {
65722 + t_Error err;
65723 + t_FmIpcMsg msg;
65724 + t_FmIpcReply reply;
65725 + uint32_t replyLength;
65726 + t_FmIpcPhysAddr ipcPhysAddr;
65727 +
65728 + memset(&msg, 0, sizeof(msg));
65729 + memset(&reply, 0, sizeof(reply));
65730 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65731 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65732 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65733 + (uint8_t*)&msg,
65734 + sizeof(msg.msgId),
65735 + (uint8_t*)&reply,
65736 + &replyLength,
65737 + NULL,
65738 + NULL);
65739 + if (err != E_OK)
65740 + {
65741 + REPORT_ERROR(MINOR, err, NO_MSG);
65742 + return;
65743 + }
65744 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65745 + {
65746 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65747 + return;
65748 + }
65749 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65750 + p_FmPhysAddr->high = ipcPhysAddr.high;
65751 + p_FmPhysAddr->low = ipcPhysAddr.low;
65752 + }
65753 + else
65754 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65755 + ("running in guest-mode without neither IPC nor mapped register!"));
65756 +}
65757 +
65758 +#if (DPAA_VERSION >= 11)
65759 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65760 + e_FmPortType portType,
65761 + uint8_t portId,
65762 + uint8_t numOfVSPs)
65763 +{
65764 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65765 + t_Error err = E_OK;
65766 + uint32_t profilesFound, intFlags;
65767 + uint8_t first, i;
65768 + uint8_t log2Num;
65769 + uint8_t swPortIndex=0, hardwarePortId;
65770 +
65771 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65772 +
65773 + if (!numOfVSPs)
65774 + return E_OK;
65775 +
65776 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65777 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65778 +
65779 + if (!POWER_OF_2(numOfVSPs))
65780 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65781 +
65782 + LOG2((uint64_t)numOfVSPs, log2Num);
65783 +
65784 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65785 + first = 0;
65786 + else
65787 + first = 1<<log2Num;
65788 +
65789 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65790 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65791 +
65792 + if (first < p_Fm->partVSPBase)
65793 + while (first < p_Fm->partVSPBase)
65794 + first = first + numOfVSPs;
65795 +
65796 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65797 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65798 +
65799 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65800 + profilesFound = 0;
65801 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65802 + {
65803 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65804 + {
65805 + profilesFound++;
65806 + i++;
65807 + if (profilesFound == numOfVSPs)
65808 + break;
65809 + }
65810 + else
65811 + {
65812 + profilesFound = 0;
65813 + /* advance i to the next aligned address */
65814 + first = i = (uint8_t)(first + numOfVSPs);
65815 + }
65816 + }
65817 + if (profilesFound == numOfVSPs)
65818 + for (i = first; i<first + numOfVSPs; i++)
65819 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65820 + else
65821 + {
65822 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65823 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65824 + }
65825 +
65826 + hardwarePortId = SwPortIdToHwPortId(portType,
65827 + portId,
65828 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65829 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65830 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65831 +
65832 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65833 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65834 +
65835 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65836 + for (i = first; i < first + numOfVSPs; i++)
65837 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65838 +
65839 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65840 +
65841 + return err;
65842 +}
65843 +
65844 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65845 + e_FmPortType portType,
65846 + uint8_t portId)
65847 +{
65848 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65849 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65850 + uint32_t intFlags;
65851 +
65852 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65853 +
65854 + hardwarePortId = SwPortIdToHwPortId(portType,
65855 + portId,
65856 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65857 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65858 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65859 +
65860 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65861 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65862 +
65863 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65864 + for (i = first; i < first + numOfVSPs; i++)
65865 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65866 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65867 +
65868 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65869 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65870 +
65871 + return E_OK;
65872 +}
65873 +#endif /* (DPAA_VERSION >= 11) */
65874 +
65875 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
65876 +{
65877 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65878 + uint8_t i;
65879 +
65880 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65881 +
65882 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65883 + p_Fm->h_IpcSessions[0])
65884 + {
65885 + t_Error err;
65886 + t_FmIpcMsg msg;
65887 + t_FmIpcReply reply;
65888 + uint32_t replyLength;
65889 +
65890 + memset(&msg, 0, sizeof(msg));
65891 + memset(&reply, 0, sizeof(reply));
65892 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
65893 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65894 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65895 + (uint8_t*)&msg,
65896 + sizeof(msg.msgId),
65897 + (uint8_t*)&reply,
65898 + &replyLength,
65899 + NULL,
65900 + NULL)) != E_OK)
65901 + RETURN_ERROR(MAJOR, err, NO_MSG);
65902 +
65903 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
65904 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65905 +
65906 + *p_EventId = *(uint8_t*)(reply.replyBody);
65907 +
65908 + return (t_Error)(reply.error);
65909 + }
65910 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65911 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65912 + ("running in guest-mode without IPC!"));
65913 +
65914 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
65915 + if (!p_Fm->usedEventRegs[i])
65916 + {
65917 + p_Fm->usedEventRegs[i] = TRUE;
65918 + *p_EventId = i;
65919 + break;
65920 + }
65921 +
65922 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
65923 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
65924 +
65925 + return E_OK;
65926 +}
65927 +
65928 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
65929 +{
65930 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65931 +
65932 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
65933 +
65934 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65935 + p_Fm->h_IpcSessions[0])
65936 + {
65937 + t_Error err;
65938 + t_FmIpcMsg msg;
65939 +
65940 + memset(&msg, 0, sizeof(msg));
65941 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
65942 + msg.msgBody[0] = eventId;
65943 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65944 + (uint8_t*)&msg,
65945 + sizeof(msg.msgId)+sizeof(eventId),
65946 + NULL,
65947 + NULL,
65948 + NULL,
65949 + NULL);
65950 + if (err != E_OK)
65951 + REPORT_ERROR(MINOR, err, NO_MSG);
65952 + return;
65953 + }
65954 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65955 + {
65956 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65957 + ("running in guest-mode without IPC!"));
65958 + return;
65959 + }
65960 +
65961 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
65962 +}
65963 +
65964 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
65965 +{
65966 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65967 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65968 +
65969 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65970 + !p_Fm->p_FmFpmRegs &&
65971 + p_Fm->h_IpcSessions[0])
65972 + {
65973 + t_FmIpcFmanEvents fmanCtrl;
65974 + t_Error err;
65975 + t_FmIpcMsg msg;
65976 +
65977 + fmanCtrl.eventRegId = eventRegId;
65978 + fmanCtrl.enableEvents = enableEvents;
65979 + memset(&msg, 0, sizeof(msg));
65980 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
65981 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
65982 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65983 + (uint8_t*)&msg,
65984 + sizeof(msg.msgId)+sizeof(fmanCtrl),
65985 + NULL,
65986 + NULL,
65987 + NULL,
65988 + NULL);
65989 + if (err != E_OK)
65990 + REPORT_ERROR(MINOR, err, NO_MSG);
65991 + return;
65992 + }
65993 + else if (!p_Fm->p_FmFpmRegs)
65994 + {
65995 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65996 + ("Either IPC or 'baseAddress' is required!"));
65997 + return;
65998 + }
65999 +
66000 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66001 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
66002 +}
66003 +
66004 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66005 +{
66006 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66007 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66008 +
66009 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66010 + !p_Fm->p_FmFpmRegs &&
66011 + p_Fm->h_IpcSessions[0])
66012 + {
66013 + t_Error err;
66014 + t_FmIpcMsg msg;
66015 + t_FmIpcReply reply;
66016 + uint32_t replyLength, ctrlIntr;
66017 +
66018 + memset(&msg, 0, sizeof(msg));
66019 + memset(&reply, 0, sizeof(reply));
66020 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
66021 + msg.msgBody[0] = eventRegId;
66022 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66023 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66024 + (uint8_t*)&msg,
66025 + sizeof(msg.msgId)+sizeof(eventRegId),
66026 + (uint8_t*)&reply,
66027 + &replyLength,
66028 + NULL,
66029 + NULL);
66030 + if (err != E_OK)
66031 + {
66032 + REPORT_ERROR(MINOR, err, NO_MSG);
66033 + return 0;
66034 + }
66035 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66036 + {
66037 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66038 + return 0;
66039 + }
66040 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
66041 + return ctrlIntr;
66042 + }
66043 + else if (!p_Fm->p_FmFpmRegs)
66044 + {
66045 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66046 + ("Either IPC or 'baseAddress' is required!"));
66047 + return 0;
66048 + }
66049 +
66050 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
66051 +}
66052 +
66053 +void FmRegisterIntr(t_Handle h_Fm,
66054 + e_FmEventModules module,
66055 + uint8_t modId,
66056 + e_FmIntrType intrType,
66057 + void (*f_Isr) (t_Handle h_Arg),
66058 + t_Handle h_Arg)
66059 +{
66060 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66061 + int event = 0;
66062 +
66063 + ASSERT_COND(h_Fm);
66064 +
66065 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
66066 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66067 +
66068 + /* register in local FM structure */
66069 + p_Fm->intrMng[event].f_Isr = f_Isr;
66070 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
66071 +
66072 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66073 + p_Fm->h_IpcSessions[0])
66074 + {
66075 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
66076 + t_Error err;
66077 + t_FmIpcMsg msg;
66078 +
66079 + /* register in Master FM structure */
66080 + fmIpcRegisterIntr.event = (uint32_t)event;
66081 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
66082 + memset(&msg, 0, sizeof(msg));
66083 + msg.msgId = FM_REGISTER_INTR;
66084 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
66085 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66086 + (uint8_t*)&msg,
66087 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
66088 + NULL,
66089 + NULL,
66090 + NULL,
66091 + NULL);
66092 + if (err != E_OK)
66093 + REPORT_ERROR(MINOR, err, NO_MSG);
66094 + }
66095 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66096 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66097 + ("running in guest-mode without IPC!"));
66098 +}
66099 +
66100 +void FmUnregisterIntr(t_Handle h_Fm,
66101 + e_FmEventModules module,
66102 + uint8_t modId,
66103 + e_FmIntrType intrType)
66104 +{
66105 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66106 + int event = 0;
66107 +
66108 + ASSERT_COND(h_Fm);
66109 +
66110 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
66111 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66112 +
66113 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
66114 + p_Fm->intrMng[event].h_SrcHandle = NULL;
66115 +}
66116 +
66117 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
66118 +{
66119 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66120 +
66121 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66122 +
66123 + if (p_Fm->guestId != NCSW_MASTER_ID)
66124 + {
66125 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66126 + return;
66127 + }
66128 +
66129 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
66130 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
66131 +}
66132 +
66133 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66134 +{
66135 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66136 +
66137 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66138 +
66139 + if (p_Fm->guestId != NCSW_MASTER_ID)
66140 + {
66141 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66142 + return;
66143 + }
66144 +
66145 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
66146 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
66147 +}
66148 +
66149 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
66150 +{
66151 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66152 +
66153 + if (p_Fm->h_Pcd)
66154 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
66155 +
66156 + p_Fm->h_Pcd = h_FmPcd;
66157 +}
66158 +
66159 +void FmUnregisterPcd(t_Handle h_Fm)
66160 +{
66161 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66162 +
66163 + if (!p_Fm->h_Pcd)
66164 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
66165 +
66166 + p_Fm->h_Pcd = NULL;
66167 +}
66168 +
66169 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
66170 +{
66171 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66172 +
66173 + return p_Fm->h_Pcd;
66174 +}
66175 +
66176 +uint8_t FmGetId(t_Handle h_Fm)
66177 +{
66178 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66179 +
66180 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
66181 +
66182 + return p_Fm->p_FmStateStruct->fmId;
66183 +}
66184 +
66185 +t_Error FmReset(t_Handle h_Fm)
66186 +{
66187 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66188 +
66189 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66190 +
66191 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66192 + CORE_MemoryBarrier();
66193 + XX_UDelay(100);
66194 +
66195 + return E_OK;
66196 +}
66197 +
66198 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
66199 + uint8_t hardwarePortId,
66200 + uint8_t numOfFmanCtrls,
66201 + t_FmFmanCtrl orFmanCtrl)
66202 +{
66203 +
66204 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66205 + struct fman_fpm_regs *fpm_rg;
66206 +
66207 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66208 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
66209 +
66210 + fpm_rg = p_Fm->p_FmFpmRegs;
66211 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66212 + !p_Fm->p_FmFpmRegs &&
66213 + p_Fm->h_IpcSessions[0])
66214 + {
66215 + t_Error err;
66216 + t_FmIpcPortNumOfFmanCtrls params;
66217 + t_FmIpcMsg msg;
66218 +
66219 + memset(&msg, 0, sizeof(msg));
66220 + params.hardwarePortId = hardwarePortId;
66221 + params.numOfFmanCtrls = numOfFmanCtrls;
66222 + params.orFmanCtrl = orFmanCtrl;
66223 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
66224 + memcpy(msg.msgBody, &params, sizeof(params));
66225 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66226 + (uint8_t*)&msg,
66227 + sizeof(msg.msgId) +sizeof(params),
66228 + NULL,
66229 + NULL,
66230 + NULL,
66231 + NULL);
66232 + if (err != E_OK)
66233 + RETURN_ERROR(MINOR, err, NO_MSG);
66234 + return E_OK;
66235 + }
66236 + else if (!p_Fm->p_FmFpmRegs)
66237 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66238 + ("Either IPC or 'baseAddress' is required!"));
66239 +
66240 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
66241 +
66242 + return E_OK;
66243 +}
66244 +
66245 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
66246 +{
66247 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66248 + t_Error err;
66249 + uint32_t intFlags;
66250 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
66251 + struct fman_rg fman_rg;
66252 +
66253 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
66254 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
66255 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
66256 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
66257 +
66258 + if (p_Fm->guestId != NCSW_MASTER_ID)
66259 + {
66260 + t_FmIpcPortInInitParams portInParams;
66261 + t_FmIpcPortOutInitParams portOutParams;
66262 + t_FmIpcMsg msg;
66263 + t_FmIpcReply reply;
66264 + uint32_t replyLength;
66265 +
66266 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
66267 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
66268 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
66269 + portInParams.liodnOffset = p_PortParams->liodnOffset;
66270 + portInParams.numOfTasks = p_PortParams->numOfTasks;
66271 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
66272 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
66273 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
66274 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
66275 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
66276 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66277 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
66278 + portInParams.liodnBase = p_PortParams->liodnBase;
66279 +
66280 + memset(&msg, 0, sizeof(msg));
66281 + memset(&reply, 0, sizeof(reply));
66282 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66283 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66284 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66285 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66286 + (uint8_t*)&msg,
66287 + sizeof(msg.msgId) +sizeof(portInParams),
66288 + (uint8_t*)&reply,
66289 + &replyLength,
66290 + NULL,
66291 + NULL)) != E_OK)
66292 + RETURN_ERROR(MINOR, err, NO_MSG);
66293 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66294 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66295 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66296 +
66297 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66298 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66299 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66300 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66301 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66302 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66303 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66304 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66305 +
66306 + return (t_Error)(reply.error);
66307 + }
66308 +
66309 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66310 +
66311 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66312 + if (p_PortParams->independentMode)
66313 + {
66314 + /* set port parameters */
66315 + p_Fm->independentMode = p_PortParams->independentMode;
66316 + /* disable dispatch limit */
66317 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66318 + }
66319 +
66320 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66321 + {
66322 + if (p_Fm->hcPortInitialized)
66323 + {
66324 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66325 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66326 + }
66327 + else
66328 + p_Fm->hcPortInitialized = TRUE;
66329 + }
66330 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66331 +
66332 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66333 + if (err)
66334 + {
66335 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66336 + RETURN_ERROR(MAJOR, err, NO_MSG);
66337 + }
66338 +
66339 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66340 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66341 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66342 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66343 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66344 + /* for transmit & O/H ports */
66345 + {
66346 + uint8_t enqTh;
66347 + uint8_t deqTh;
66348 +
66349 + /* update qmi ENQ/DEQ threshold */
66350 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66351 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66352 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66353 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66354 + {
66355 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66356 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66357 + }
66358 +
66359 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66360 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66361 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66362 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66363 + {
66364 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66365 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66366 + }
66367 + }
66368 +
66369 +#ifdef FM_LOW_END_RESTRICTION
66370 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66371 + {
66372 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66373 + {
66374 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66375 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66376 + }
66377 + else
66378 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66379 + }
66380 +#endif /* FM_LOW_END_RESTRICTION */
66381 +
66382 + err = FmSetSizeOfFifo(p_Fm,
66383 + hardwarePortId,
66384 + &p_PortParams->sizeOfFifo,
66385 + &p_PortParams->extraSizeOfFifo,
66386 + TRUE);
66387 + if (err)
66388 + {
66389 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66390 + RETURN_ERROR(MAJOR, err, NO_MSG);
66391 + }
66392 +
66393 + err = FmSetNumOfOpenDmas(p_Fm,
66394 + hardwarePortId,
66395 + &p_PortParams->numOfOpenDmas,
66396 + &p_PortParams->numOfExtraOpenDmas,
66397 + TRUE);
66398 + if (err)
66399 + {
66400 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66401 + RETURN_ERROR(MAJOR, err, NO_MSG);
66402 + }
66403 +
66404 + fman_set_liodn_per_port(&fman_rg,
66405 + hardwarePortId,
66406 + p_PortParams->liodnBase,
66407 + p_PortParams->liodnOffset);
66408 +
66409 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66410 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66411 + hardwarePortId,
66412 + p_PortParams->independentMode,
66413 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66414 +
66415 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66416 +
66417 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66418 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66419 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66420 + {
66421 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66422 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66423 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66424 + else
66425 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66426 + }
66427 + else
66428 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66429 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66430 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66431 + {
66432 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66433 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66434 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66435 + else
66436 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66437 + }
66438 +
66439 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66440 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66441 +
66442 + return E_OK;
66443 +}
66444 +
66445 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66446 +{
66447 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66448 + uint32_t intFlags;
66449 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66450 + uint8_t numOfTasks, numOfDmas, macId;
66451 + uint16_t sizeOfFifo;
66452 + t_Error err;
66453 + t_FmIpcPortFreeParams portParams;
66454 + t_FmIpcMsg msg;
66455 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66456 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66457 +
66458 + if (p_Fm->guestId != NCSW_MASTER_ID)
66459 + {
66460 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66461 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66462 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66463 + memset(&msg, 0, sizeof(msg));
66464 + msg.msgId = FM_FREE_PORT;
66465 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66466 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66467 + (uint8_t*)&msg,
66468 + sizeof(msg.msgId)+sizeof(portParams),
66469 + NULL,
66470 + NULL,
66471 + NULL,
66472 + NULL);
66473 + if (err != E_OK)
66474 + REPORT_ERROR(MINOR, err, NO_MSG);
66475 + return;
66476 + }
66477 +
66478 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66479 +
66480 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66481 +
66482 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66483 + {
66484 + ASSERT_COND(p_Fm->hcPortInitialized);
66485 + p_Fm->hcPortInitialized = FALSE;
66486 + }
66487 +
66488 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66489 +
66490 + /* free numOfTasks */
66491 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66492 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66493 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66494 +
66495 + /* free numOfOpenDmas */
66496 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66497 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66498 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66499 +
66500 +#ifdef FM_HAS_TOTAL_DMAS
66501 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66502 + {
66503 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66504 + fman_set_num_of_open_dmas(bmi_rg,
66505 + hardwarePortId,
66506 + 1,
66507 + 0,
66508 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66509 + }
66510 +#endif /* FM_HAS_TOTAL_DMAS */
66511 +
66512 + /* free sizeOfFifo */
66513 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66514 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66515 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66516 +
66517 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66518 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66519 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66520 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66521 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66522 + /* for transmit & O/H ports */
66523 + {
66524 + uint8_t enqTh;
66525 + uint8_t deqTh;
66526 +
66527 + /* update qmi ENQ/DEQ threshold */
66528 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66529 +
66530 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66531 + so we can enlarge enqTh */
66532 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66533 +
66534 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66535 + so we can reduce deqTh */
66536 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66537 +
66538 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66539 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66540 + }
66541 +
66542 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66543 +
66544 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66545 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66546 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66547 + {
66548 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66549 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66550 + }
66551 + else
66552 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66553 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66554 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66555 + {
66556 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66557 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66558 + }
66559 +
66560 +#ifdef FM_LOW_END_RESTRICTION
66561 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66562 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66563 +#endif /* FM_LOW_END_RESTRICTION */
66564 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66565 +}
66566 +
66567 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66568 +{
66569 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66570 + t_Error err;
66571 + t_FmIpcMsg msg;
66572 + t_FmIpcReply reply;
66573 + uint32_t replyLength;
66574 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66575 +
66576 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66577 + !p_Fm->baseAddr &&
66578 + p_Fm->h_IpcSessions[0])
66579 + {
66580 + memset(&msg, 0, sizeof(msg));
66581 + memset(&reply, 0, sizeof(reply));
66582 + msg.msgId = FM_IS_PORT_STALLED;
66583 + msg.msgBody[0] = hardwarePortId;
66584 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66585 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66586 + (uint8_t*)&msg,
66587 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66588 + (uint8_t*)&reply,
66589 + &replyLength,
66590 + NULL,
66591 + NULL);
66592 + if (err != E_OK)
66593 + RETURN_ERROR(MINOR, err, NO_MSG);
66594 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66595 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66596 +
66597 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66598 +
66599 + return (t_Error)(reply.error);
66600 + }
66601 + else if (!p_Fm->baseAddr)
66602 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66603 + ("Either IPC or 'baseAddress' is required!"));
66604 +
66605 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66606 +
66607 + return E_OK;
66608 +}
66609 +
66610 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66611 +{
66612 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66613 + t_Error err;
66614 + bool isStalled;
66615 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66616 +
66617 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66618 + !p_Fm->baseAddr &&
66619 + p_Fm->h_IpcSessions[0])
66620 + {
66621 + t_FmIpcMsg msg;
66622 + t_FmIpcReply reply;
66623 + uint32_t replyLength;
66624 +
66625 + memset(&msg, 0, sizeof(msg));
66626 + memset(&reply, 0, sizeof(reply));
66627 + msg.msgId = FM_RESUME_STALLED_PORT;
66628 + msg.msgBody[0] = hardwarePortId;
66629 + replyLength = sizeof(uint32_t);
66630 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66631 + (uint8_t*)&msg,
66632 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66633 + (uint8_t*)&reply,
66634 + &replyLength,
66635 + NULL,
66636 + NULL);
66637 + if (err != E_OK)
66638 + RETURN_ERROR(MINOR, err, NO_MSG);
66639 + if (replyLength != sizeof(uint32_t))
66640 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66641 + return (t_Error)(reply.error);
66642 + }
66643 + else if (!p_Fm->baseAddr)
66644 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66645 + ("Either IPC or 'baseAddress' is required!"));
66646 +
66647 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66648 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66649 +
66650 + /* Get port status */
66651 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66652 + if (err)
66653 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66654 + if (!isStalled)
66655 + return E_OK;
66656 +
66657 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66658 +
66659 + return E_OK;
66660 +}
66661 +
66662 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66663 +{
66664 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66665 + t_Error err;
66666 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66667 +
66668 +#if (DPAA_VERSION >= 11)
66669 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66670 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66671 + ("FMan MAC reset!"));
66672 +#endif /*(DPAA_VERSION >= 11)*/
66673 +
66674 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66675 + !p_Fm->baseAddr &&
66676 + p_Fm->h_IpcSessions[0])
66677 + {
66678 + t_FmIpcMacParams macParams;
66679 + t_FmIpcMsg msg;
66680 + t_FmIpcReply reply;
66681 + uint32_t replyLength;
66682 +
66683 + memset(&msg, 0, sizeof(msg));
66684 + memset(&reply, 0, sizeof(reply));
66685 + macParams.id = macId;
66686 + macParams.enumType = (uint32_t)type;
66687 + msg.msgId = FM_RESET_MAC;
66688 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66689 + replyLength = sizeof(uint32_t);
66690 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66691 + (uint8_t*)&msg,
66692 + sizeof(msg.msgId)+sizeof(macParams),
66693 + (uint8_t*)&reply,
66694 + &replyLength,
66695 + NULL,
66696 + NULL);
66697 + if (err != E_OK)
66698 + RETURN_ERROR(MINOR, err, NO_MSG);
66699 + if (replyLength != sizeof(uint32_t))
66700 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66701 + return (t_Error)(reply.error);
66702 + }
66703 + else if (!p_Fm->baseAddr)
66704 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66705 + ("Either IPC or 'baseAddress' is required!"));
66706 +
66707 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66708 +
66709 + if (err == -EBUSY)
66710 + return ERROR_CODE(E_TIMEOUT);
66711 + else if (err)
66712 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66713 +
66714 + return E_OK;
66715 +}
66716 +
66717 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66718 +{
66719 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66720 +
66721 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66722 + p_Fm->h_IpcSessions[0])
66723 + {
66724 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66725 + t_Error err;
66726 + t_FmIpcMsg msg;
66727 +
66728 + memset(&msg, 0, sizeof(msg));
66729 + macMaxFrameLengthParams.macParams.id = macId;
66730 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66731 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66732 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66733 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66734 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66735 + (uint8_t*)&msg,
66736 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66737 + NULL,
66738 + NULL,
66739 + NULL,
66740 + NULL);
66741 + if (err != E_OK)
66742 + RETURN_ERROR(MINOR, err, NO_MSG);
66743 + return E_OK;
66744 + }
66745 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66746 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66747 + ("running in guest-mode without IPC!"));
66748 +
66749 + /* if port is already initialized, check that MaxFrameLength is smaller
66750 + * or equal to the port's max */
66751 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66752 + if (type == e_FM_MAC_10G)
66753 + {
66754 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66755 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66756 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66757 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66758 + else
66759 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66760 +
66761 + }
66762 + else
66763 +#else
66764 + UNUSED(type);
66765 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66766 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66767 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66768 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66769 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66770 + else
66771 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66772 +
66773 + return E_OK;
66774 +}
66775 +
66776 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66777 +{
66778 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66779 +
66780 + /* for multicore environment: this depends on the
66781 + * fact that fmClkFreq was properly initialized at "init". */
66782 + return p_Fm->p_FmStateStruct->fmClkFreq;
66783 +}
66784 +
66785 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66786 +{
66787 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66788 +
66789 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66790 +}
66791 +
66792 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66793 +{
66794 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66795 +
66796 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66797 + !p_Fm->baseAddr &&
66798 + p_Fm->h_IpcSessions[0])
66799 + {
66800 + t_Error err;
66801 + t_FmIpcMsg msg;
66802 + t_FmIpcReply reply;
66803 + uint32_t replyLength, timeStamp;
66804 +
66805 + memset(&msg, 0, sizeof(msg));
66806 + memset(&reply, 0, sizeof(reply));
66807 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66808 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66809 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66810 + (uint8_t*)&msg,
66811 + sizeof(msg.msgId),
66812 + (uint8_t*)&reply,
66813 + &replyLength,
66814 + NULL,
66815 + NULL)) != E_OK)
66816 + {
66817 + REPORT_ERROR(MAJOR, err, NO_MSG);
66818 + return 0;
66819 + }
66820 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66821 + {
66822 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66823 + return 0;
66824 + }
66825 +
66826 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66827 + return timeStamp;
66828 + }
66829 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66830 + p_Fm->baseAddr)
66831 + {
66832 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66833 + {
66834 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66835 + return 0;
66836 + }
66837 + }
66838 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66839 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66840 +
66841 + return p_Fm->p_FmStateStruct->count1MicroBit;
66842 +}
66843 +
66844 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66845 +{
66846 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66847 +
66848 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66849 +
66850 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66851 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66852 +
66853 + return FM_EnableRamsEcc(p_Fm);
66854 +}
66855 +
66856 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66857 +{
66858 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66859 +
66860 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66861 +
66862 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66863 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66864 +
66865 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66866 + {
66867 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66868 + return FM_DisableRamsEcc(p_Fm);
66869 + }
66870 +
66871 + return E_OK;
66872 +}
66873 +
66874 +uint8_t FmGetGuestId(t_Handle h_Fm)
66875 +{
66876 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66877 +
66878 + return p_Fm->guestId;
66879 +}
66880 +
66881 +bool FmIsMaster(t_Handle h_Fm)
66882 +{
66883 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66884 +
66885 + return (p_Fm->guestId == NCSW_MASTER_ID);
66886 +}
66887 +
66888 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
66889 + uint8_t hardwarePortId,
66890 + uint32_t *p_SizeOfFifo,
66891 + uint32_t *p_ExtraSizeOfFifo,
66892 + bool initialConfig)
66893 +{
66894 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66895 + t_FmIpcPortRsrcParams rsrcParams;
66896 + t_Error err;
66897 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66898 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
66899 + uint16_t currentVal = 0, currentExtraVal = 0;
66900 +
66901 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66902 + !p_Fm->baseAddr &&
66903 + p_Fm->h_IpcSessions[0])
66904 + {
66905 + t_FmIpcMsg msg;
66906 + t_FmIpcReply reply;
66907 + uint32_t replyLength;
66908 +
66909 + rsrcParams.hardwarePortId = hardwarePortId;
66910 + rsrcParams.val = sizeOfFifo;
66911 + rsrcParams.extra = extraSizeOfFifo;
66912 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66913 +
66914 + memset(&msg, 0, sizeof(msg));
66915 + memset(&reply, 0, sizeof(reply));
66916 + msg.msgId = FM_SET_SIZE_OF_FIFO;
66917 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66918 + replyLength = sizeof(uint32_t);
66919 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66920 + (uint8_t*)&msg,
66921 + sizeof(msg.msgId) + sizeof(rsrcParams),
66922 + (uint8_t*)&reply,
66923 + &replyLength,
66924 + NULL,
66925 + NULL)) != E_OK)
66926 + RETURN_ERROR(MINOR, err, NO_MSG);
66927 + if (replyLength != sizeof(uint32_t))
66928 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66929 + return (t_Error)(reply.error);
66930 + }
66931 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66932 + p_Fm->baseAddr)
66933 + {
66934 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
66935 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66936 + }
66937 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66938 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66939 + ("running in guest-mode without neither IPC nor mapped register!"));
66940 +
66941 + if (!initialConfig)
66942 + {
66943 + /* !initialConfig - runtime change of existing value.
66944 + * - read the current FIFO and extra FIFO size */
66945 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
66946 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66947 + }
66948 +
66949 + if (extraSizeOfFifo > currentExtraVal)
66950 + {
66951 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
66952 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
66953 + * must be initialized to 1 buffer per port
66954 + */
66955 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
66956 +
66957 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
66958 + }
66959 +
66960 + /* check that there are enough uncommitted fifo size */
66961 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
66962 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
66963 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
66964 + ("Port request fifo size + accumulated size > total FIFO size:"));
66965 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66966 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
66967 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
66968 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
66969 + p_Fm->p_FmStateStruct->totalFifoSize));
66970 + }
66971 + else
66972 + {
66973 + /* update accumulated */
66974 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
66975 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
66976 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
66977 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66978 + }
66979 +
66980 + return E_OK;
66981 +}
66982 +
66983 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
66984 + uint8_t hardwarePortId,
66985 + uint8_t *p_NumOfTasks,
66986 + uint8_t *p_NumOfExtraTasks,
66987 + bool initialConfig)
66988 +{
66989 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66990 + t_Error err;
66991 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66992 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
66993 +
66994 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66995 +
66996 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66997 + !p_Fm->baseAddr &&
66998 + p_Fm->h_IpcSessions[0])
66999 + {
67000 + t_FmIpcPortRsrcParams rsrcParams;
67001 + t_FmIpcMsg msg;
67002 + t_FmIpcReply reply;
67003 + uint32_t replyLength;
67004 +
67005 + rsrcParams.hardwarePortId = hardwarePortId;
67006 + rsrcParams.val = numOfTasks;
67007 + rsrcParams.extra = numOfExtraTasks;
67008 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67009 +
67010 + memset(&msg, 0, sizeof(msg));
67011 + memset(&reply, 0, sizeof(reply));
67012 + msg.msgId = FM_SET_NUM_OF_TASKS;
67013 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67014 + replyLength = sizeof(uint32_t);
67015 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67016 + (uint8_t*)&msg,
67017 + sizeof(msg.msgId) + sizeof(rsrcParams),
67018 + (uint8_t*)&reply,
67019 + &replyLength,
67020 + NULL,
67021 + NULL)) != E_OK)
67022 + RETURN_ERROR(MINOR, err, NO_MSG);
67023 + if (replyLength != sizeof(uint32_t))
67024 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67025 + return (t_Error)(reply.error);
67026 + }
67027 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67028 + p_Fm->baseAddr)
67029 + {
67030 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
67031 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67032 + }
67033 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67034 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67035 + ("running in guest-mode without neither IPC nor mapped register!"));
67036 +
67037 + if (!initialConfig)
67038 + {
67039 + /* !initialConfig - runtime change of existing value.
67040 + * - read the current number of tasks */
67041 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
67042 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
67043 + }
67044 +
67045 + if (numOfExtraTasks > currentExtraVal)
67046 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
67047 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
67048 +
67049 + /* check that there are enough uncommitted tasks */
67050 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
67051 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
67052 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67053 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
67054 + p_Fm->p_FmStateStruct->fmId));
67055 + else
67056 + {
67057 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
67058 + /* update accumulated */
67059 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
67060 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
67061 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67062 + }
67063 +
67064 + return E_OK;
67065 +}
67066 +
67067 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
67068 + uint8_t hardwarePortId,
67069 + uint8_t *p_NumOfOpenDmas,
67070 + uint8_t *p_NumOfExtraOpenDmas,
67071 + bool initialConfig)
67072 +
67073 +{
67074 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67075 + t_Error err;
67076 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67077 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
67078 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
67079 +
67080 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67081 +
67082 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67083 + !p_Fm->baseAddr &&
67084 + p_Fm->h_IpcSessions[0])
67085 + {
67086 + t_FmIpcPortRsrcParams rsrcParams;
67087 + t_FmIpcMsg msg;
67088 + t_FmIpcReply reply;
67089 + uint32_t replyLength;
67090 +
67091 + rsrcParams.hardwarePortId = hardwarePortId;
67092 + rsrcParams.val = numOfOpenDmas;
67093 + rsrcParams.extra = numOfExtraOpenDmas;
67094 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67095 +
67096 + memset(&msg, 0, sizeof(msg));
67097 + memset(&reply, 0, sizeof(reply));
67098 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
67099 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67100 + replyLength = sizeof(uint32_t);
67101 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67102 + (uint8_t*)&msg,
67103 + sizeof(msg.msgId) + sizeof(rsrcParams),
67104 + (uint8_t*)&reply,
67105 + &replyLength,
67106 + NULL,
67107 + NULL)) != E_OK)
67108 + RETURN_ERROR(MINOR, err, NO_MSG);
67109 + if (replyLength != sizeof(uint32_t))
67110 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67111 + return (t_Error)(reply.error);
67112 + }
67113 +#ifdef FM_HAS_TOTAL_DMAS
67114 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67115 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
67116 +#else
67117 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67118 + p_Fm->baseAddr &&
67119 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
67120 + {
67121 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
67122 +
67123 + if (!numOfOpenDmas)
67124 + {
67125 + /* first config without explic it value: Do Nothing - reset value shouldn't be
67126 + changed, read register for port save */
67127 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67128 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67129 + }
67130 + else
67131 + /* whether it is the first time with explicit value, or runtime "set" - write register */
67132 + fman_set_num_of_open_dmas(bmi_rg,
67133 + hardwarePortId,
67134 + numOfOpenDmas,
67135 + numOfExtraOpenDmas,
67136 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67137 + }
67138 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67139 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67140 + ("running in guest-mode without neither IPC nor mapped register!"));
67141 +#endif /* FM_HAS_TOTAL_DMAS */
67142 +
67143 + if (!initialConfig)
67144 + {
67145 + /* !initialConfig - runtime change of existing value.
67146 + * - read the current number of open Dma's */
67147 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67148 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67149 + }
67150 +
67151 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
67152 + /* it's illegal to be in a state where this is not the first set and no value is specified */
67153 + ASSERT_COND(initialConfig || numOfOpenDmas);
67154 + if (!numOfOpenDmas)
67155 + {
67156 + /* !numOfOpenDmas - first configuration according to values in regs.
67157 + * - read the current number of open Dma's */
67158 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67159 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67160 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
67161 + * reset values will be used and we just save these values for resource management */
67162 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67163 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
67164 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
67165 + *p_NumOfOpenDmas = currentVal;
67166 + *p_NumOfExtraOpenDmas = currentExtraVal;
67167 + return E_OK;
67168 + }
67169 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
67170 +
67171 + if (numOfExtraOpenDmas > currentExtraVal)
67172 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67173 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
67174 +
67175 +#ifdef FM_HAS_TOTAL_DMAS
67176 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
67177 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
67178 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
67179 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67180 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
67181 + p_Fm->p_FmStateStruct->fmId));
67182 +#else
67183 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
67184 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
67185 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
67186 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
67187 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
67188 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
67189 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67190 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
67191 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
67192 +#endif /* FM_HAS_TOTAL_DMAS */
67193 + else
67194 + {
67195 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
67196 + /* update acummulated */
67197 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
67198 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
67199 +
67200 +#ifdef FM_HAS_TOTAL_DMAS
67201 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67202 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67203 +#endif /* FM_HAS_TOTAL_DMAS */
67204 + fman_set_num_of_open_dmas(bmi_rg,
67205 + hardwarePortId,
67206 + numOfOpenDmas,
67207 + numOfExtraOpenDmas,
67208 + totalNumDmas);
67209 + }
67210 +
67211 + return E_OK;
67212 +}
67213 +
67214 +#if (DPAA_VERSION >= 11)
67215 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
67216 + e_FmPortType portType,
67217 + uint8_t portId,
67218 + uint16_t relativeProfile)
67219 +{
67220 + t_Fm *p_Fm;
67221 + t_FmSp *p_FmPcdSp;
67222 + uint8_t swPortIndex=0, hardwarePortId;
67223 +
67224 + ASSERT_COND(h_Fm);
67225 + p_Fm = (t_Fm*)h_Fm;
67226 +
67227 + hardwarePortId = SwPortIdToHwPortId(portType,
67228 + portId,
67229 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67230 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67231 + ASSERT_COND(hardwarePortId);
67232 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67233 +
67234 + p_FmPcdSp = p_Fm->p_FmSp;
67235 + ASSERT_COND(p_FmPcdSp);
67236 +
67237 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67238 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
67239 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67240 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
67241 +
67242 + return E_OK;
67243 +}
67244 +
67245 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
67246 + e_FmPortType portType,
67247 + uint8_t portId,
67248 + uint16_t relativeProfile,
67249 + uint16_t *p_AbsoluteId)
67250 +{
67251 + t_Fm *p_Fm;
67252 + t_FmSp *p_FmPcdSp;
67253 + uint8_t swPortIndex=0, hardwarePortId;
67254 + t_Error err;
67255 +
67256 + ASSERT_COND(h_Fm);
67257 + p_Fm = (t_Fm*)h_Fm;
67258 +
67259 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
67260 + if (err != E_OK)
67261 + return err;
67262 +
67263 + hardwarePortId = SwPortIdToHwPortId(portType,
67264 + portId,
67265 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67266 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67267 + ASSERT_COND(hardwarePortId);
67268 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67269 +
67270 + p_FmPcdSp = p_Fm->p_FmSp;
67271 + ASSERT_COND(p_FmPcdSp);
67272 +
67273 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
67274 +
67275 + return E_OK;
67276 +}
67277 +#endif /* (DPAA_VERSION >= 11) */
67278 +
67279 +static t_Error InitFmDma(t_Fm *p_Fm)
67280 +{
67281 + t_Error err;
67282 +
67283 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67284 + if (err != E_OK)
67285 + return err;
67286 +
67287 + /* Allocate MURAM for CAM */
67288 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67289 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67290 + DMA_CAM_ALIGN));
67291 + if (!p_Fm->camBaseAddr)
67292 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67293 +
67294 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67295 + 0,
67296 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67297 +
67298 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67299 + {
67300 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67301 +
67302 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67303 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67304 + 64));
67305 + if (!p_Fm->camBaseAddr)
67306 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67307 +
67308 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67309 + 0,
67310 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67311 +
67312 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67313 + {
67314 + case (8):
67315 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67316 + break;
67317 + case (16):
67318 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67319 + break;
67320 + case (24):
67321 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67322 + break;
67323 + case (32):
67324 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67325 + break;
67326 + default:
67327 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67328 + }
67329 + }
67330 +
67331 + p_Fm->p_FmDriverParam->cam_base_addr =
67332 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67333 +
67334 + return E_OK;
67335 +}
67336 +
67337 +static t_Error InitFmFpm(t_Fm *p_Fm)
67338 +{
67339 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67340 +}
67341 +
67342 +static t_Error InitFmBmi(t_Fm *p_Fm)
67343 +{
67344 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67345 +}
67346 +
67347 +static t_Error InitFmQmi(t_Fm *p_Fm)
67348 +{
67349 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67350 +}
67351 +
67352 +static t_Error InitGuestMode(t_Fm *p_Fm)
67353 +{
67354 + t_Error err = E_OK;
67355 + int i;
67356 + t_FmIpcMsg msg;
67357 + t_FmIpcReply reply;
67358 + uint32_t replyLength;
67359 +
67360 + ASSERT_COND(p_Fm);
67361 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67362 +
67363 + /* build the FM guest partition IPC address */
67364 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67365 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67366 +
67367 + /* build the FM master partition IPC address */
67368 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67369 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67370 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67371 +
67372 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67373 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67374 +
67375 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67376 + if (p_Fm->h_IpcSessions[0])
67377 + {
67378 + uint8_t isMasterAlive;
67379 + t_FmIpcParams ipcParams;
67380 +
67381 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67382 + if (err)
67383 + RETURN_ERROR(MAJOR, err, NO_MSG);
67384 +
67385 + memset(&msg, 0, sizeof(msg));
67386 + memset(&reply, 0, sizeof(reply));
67387 + msg.msgId = FM_MASTER_IS_ALIVE;
67388 + msg.msgBody[0] = p_Fm->guestId;
67389 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67390 + do
67391 + {
67392 + blockingFlag = TRUE;
67393 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67394 + (uint8_t*)&msg,
67395 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67396 + (uint8_t*)&reply,
67397 + &replyLength,
67398 + IpcMsgCompletionCB,
67399 + p_Fm)) != E_OK)
67400 + REPORT_ERROR(MINOR, err, NO_MSG);
67401 + while (blockingFlag) ;
67402 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67403 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67404 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67405 + } while (!isMasterAlive);
67406 +
67407 + /* read FM parameters and save */
67408 + memset(&msg, 0, sizeof(msg));
67409 + memset(&reply, 0, sizeof(reply));
67410 + msg.msgId = FM_GET_PARAMS;
67411 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67412 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67413 + (uint8_t*)&msg,
67414 + sizeof(msg.msgId),
67415 + (uint8_t*)&reply,
67416 + &replyLength,
67417 + NULL,
67418 + NULL)) != E_OK)
67419 + RETURN_ERROR(MAJOR, err, NO_MSG);
67420 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67421 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67422 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67423 +
67424 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67425 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67426 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67427 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67428 + }
67429 + else
67430 + {
67431 + DBG(WARNING, ("FM Guest mode - without IPC"));
67432 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67433 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67434 + if (p_Fm->baseAddr)
67435 + {
67436 + fman_get_revision(p_Fm->p_FmFpmRegs,
67437 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67438 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67439 +
67440 + }
67441 + }
67442 +
67443 +#if (DPAA_VERSION >= 11)
67444 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67445 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67446 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67447 +#endif /* (DPAA_VERSION >= 11) */
67448 +
67449 + /* General FM driver initialization */
67450 + if (p_Fm->baseAddr)
67451 + p_Fm->fmMuramPhysBaseAddr =
67452 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67453 +
67454 + XX_Free(p_Fm->p_FmDriverParam);
67455 + p_Fm->p_FmDriverParam = NULL;
67456 +
67457 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67458 + (p_Fm->h_IpcSessions[0]))
67459 + {
67460 + FM_DisableRamsEcc(p_Fm);
67461 + FmMuramClear(p_Fm->h_FmMuram);
67462 + FM_EnableRamsEcc(p_Fm);
67463 + }
67464 +
67465 + return E_OK;
67466 +}
67467 +
67468 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67469 +{
67470 + switch (exception) {
67471 + case e_FM_EX_DMA_BUS_ERROR:
67472 + return E_FMAN_EX_DMA_BUS_ERROR;
67473 + case e_FM_EX_DMA_READ_ECC:
67474 + return E_FMAN_EX_DMA_READ_ECC;
67475 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67476 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67477 + case e_FM_EX_DMA_FM_WRITE_ECC:
67478 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67479 + case e_FM_EX_FPM_STALL_ON_TASKS:
67480 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67481 + case e_FM_EX_FPM_SINGLE_ECC:
67482 + return E_FMAN_EX_FPM_SINGLE_ECC;
67483 + case e_FM_EX_FPM_DOUBLE_ECC:
67484 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67485 + case e_FM_EX_QMI_SINGLE_ECC:
67486 + return E_FMAN_EX_QMI_SINGLE_ECC;
67487 + case e_FM_EX_QMI_DOUBLE_ECC:
67488 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67489 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67490 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67491 + case e_FM_EX_BMI_LIST_RAM_ECC:
67492 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67493 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67494 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67495 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67496 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67497 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67498 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67499 + case e_FM_EX_IRAM_ECC:
67500 + return E_FMAN_EX_IRAM_ECC;
67501 + case e_FM_EX_MURAM_ECC:
67502 + return E_FMAN_EX_MURAM_ECC;
67503 + default:
67504 + return E_FMAN_EX_DMA_BUS_ERROR;
67505 + }
67506 +}
67507 +
67508 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67509 +{
67510 + switch (type)
67511 + {
67512 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67513 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67514 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67515 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67516 + case (e_FM_PORT_TYPE_RX):
67517 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67518 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67519 + case (e_FM_PORT_TYPE_RX_10G):
67520 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67521 + * This is the reason why the 1G port offset is used.
67522 + */
67523 + if (majorRev == 6 && minorRev == 4)
67524 + {
67525 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67526 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67527 + }
67528 + else
67529 + {
67530 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67531 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67532 + }
67533 + case (e_FM_PORT_TYPE_TX):
67534 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67535 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67536 + case (e_FM_PORT_TYPE_TX_10G):
67537 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67538 + * This is the reason why the 1G port offset is used.
67539 + */
67540 + if (majorRev == 6 && minorRev == 4)
67541 + {
67542 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67543 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67544 + }
67545 + else
67546 + {
67547 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67548 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67549 + }
67550 + default:
67551 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67552 + return 0;
67553 + }
67554 +}
67555 +
67556 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67557 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67558 +{
67559 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67560 +
67561 + DECLARE_DUMP;
67562 +
67563 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67564 +
67565 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67566 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67567 + p_Fm->baseAddr), E_INVALID_OPERATION);
67568 +
67569 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67570 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67571 +
67572 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67573 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67574 +
67575 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67576 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67577 +
67578 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67579 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67580 +
67581 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67582 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67583 +
67584 + return E_OK;
67585 +}
67586 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67587 +
67588 +
67589 +/*****************************************************************************/
67590 +/* API Init unit functions */
67591 +/*****************************************************************************/
67592 +t_Handle FM_Config(t_FmParams *p_FmParam)
67593 +{
67594 + t_Fm *p_Fm;
67595 + uint8_t i;
67596 + uintptr_t baseAddr;
67597 +
67598 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67599 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67600 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67601 + E_INVALID_VALUE, NULL);
67602 +
67603 + baseAddr = p_FmParam->baseAddr;
67604 +
67605 + /* Allocate FM structure */
67606 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67607 + if (!p_Fm)
67608 + {
67609 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67610 + return NULL;
67611 + }
67612 + memset(p_Fm, 0, sizeof(t_Fm));
67613 +
67614 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67615 + if (!p_Fm->p_FmStateStruct)
67616 + {
67617 + XX_Free(p_Fm);
67618 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67619 + return NULL;
67620 + }
67621 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67622 +
67623 + /* Initialize FM parameters which will be kept by the driver */
67624 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67625 + p_Fm->guestId = p_FmParam->guestId;
67626 +
67627 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67628 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67629 +
67630 + /* Allocate the FM driver's parameters structure */
67631 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67632 + if (!p_Fm->p_FmDriverParam)
67633 + {
67634 + XX_Free(p_Fm->p_FmStateStruct);
67635 + XX_Free(p_Fm);
67636 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67637 + return NULL;
67638 + }
67639 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67640 +
67641 +#if (DPAA_VERSION >= 11)
67642 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67643 + if (!p_Fm->p_FmSp)
67644 + {
67645 + XX_Free(p_Fm->p_FmDriverParam);
67646 + XX_Free(p_Fm->p_FmStateStruct);
67647 + XX_Free(p_Fm);
67648 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67649 + return NULL;
67650 + }
67651 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67652 +
67653 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67654 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67655 +#endif /* (DPAA_VERSION >= 11) */
67656 +
67657 + /* Initialize FM parameters which will be kept by the driver */
67658 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67659 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67660 + p_Fm->h_App = p_FmParam->h_App;
67661 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67662 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67663 + p_Fm->f_Exception = p_FmParam->f_Exception;
67664 + p_Fm->f_BusError = p_FmParam->f_BusError;
67665 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67666 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67667 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67668 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67669 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67670 + p_Fm->baseAddr = baseAddr;
67671 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67672 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67673 + p_Fm->hcPortInitialized = FALSE;
67674 + p_Fm->independentMode = FALSE;
67675 +
67676 + p_Fm->h_Spinlock = XX_InitSpinlock();
67677 + if (!p_Fm->h_Spinlock)
67678 + {
67679 + XX_Free(p_Fm->p_FmDriverParam);
67680 + XX_Free(p_Fm->p_FmStateStruct);
67681 + XX_Free(p_Fm);
67682 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67683 + return NULL;
67684 + }
67685 +
67686 +#if (DPAA_VERSION >= 11)
67687 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67688 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67689 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67690 +#endif /* (DPAA_VERSION >= 11) */
67691 +
67692 + fman_defconfig(p_Fm->p_FmDriverParam,
67693 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67694 +/* overide macros dependent parameters */
67695 +#ifdef FM_PEDANTIC_DMA
67696 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67697 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67698 +#endif /* FM_PEDANTIC_DMA */
67699 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67700 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67701 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67702 +
67703 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67704 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67705 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67706 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67707 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67708 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67709 + p_Fm->firmware.size = p_FmParam->firmware.size;
67710 + if (p_Fm->firmware.size)
67711 + {
67712 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67713 + if (!p_Fm->firmware.p_Code)
67714 + {
67715 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67716 + XX_Free(p_Fm->p_FmStateStruct);
67717 + XX_Free(p_Fm->p_FmDriverParam);
67718 + XX_Free(p_Fm);
67719 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67720 + return NULL;
67721 + }
67722 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67723 + }
67724 +
67725 + if (p_Fm->guestId != NCSW_MASTER_ID)
67726 + return p_Fm;
67727 +
67728 + /* read revision */
67729 + /* Chip dependent, will be configured in Init */
67730 + fman_get_revision(p_Fm->p_FmFpmRegs,
67731 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67732 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67733 +
67734 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67735 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67736 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67737 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67738 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67739 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67740 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67741 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67742 +
67743 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67744 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67745 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67746 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67747 +
67748 +#ifdef FM_HAS_TOTAL_DMAS
67749 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67750 +#endif /* FM_HAS_TOTAL_DMAS */
67751 +#if (DPAA_VERSION < 11)
67752 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67753 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67754 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67755 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67756 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67757 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67758 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67759 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67760 +#endif /* (DPAA_VERSION < 11) */
67761 +#ifdef FM_NO_TNUM_AGING
67762 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67763 +#endif
67764 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67765 +
67766 + return p_Fm;
67767 +}
67768 +
67769 +/**************************************************************************//**
67770 + @Function FM_Init
67771 +
67772 + @Description Initializes the FM module
67773 +
67774 + @Param[in] h_Fm - FM module descriptor
67775 +
67776 + @Return E_OK on success; Error code otherwise.
67777 +*//***************************************************************************/
67778 +t_Error FM_Init(t_Handle h_Fm)
67779 +{
67780 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67781 + struct fman_cfg *p_FmDriverParam = NULL;
67782 + t_Error err = E_OK;
67783 + int i;
67784 + t_FmRevisionInfo revInfo;
67785 + struct fman_rg fman_rg;
67786 +
67787 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67788 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67789 +
67790 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67791 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67792 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67793 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67794 +
67795 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67796 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67797 +
67798 + if (p_Fm->guestId != NCSW_MASTER_ID)
67799 + return InitGuestMode(p_Fm);
67800 +
67801 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67802 + * according to chip. otherwise, we use user's configuration.
67803 + */
67804 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67805 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67806 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67807 +
67808 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67809 +
67810 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67811 +
67812 + FM_GetRevision(p_Fm, &revInfo);
67813 +
67814 + /* clear revision-dependent non existing exception */
67815 +#ifdef FM_NO_DISPATCH_RAM_ECC
67816 + if ((revInfo.majorRev != 4) &&
67817 + (revInfo.majorRev < 6))
67818 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67819 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67820 +
67821 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67822 + if (revInfo.majorRev == 4)
67823 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67824 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67825 +
67826 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67827 + if (revInfo.majorRev >= 6)
67828 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67829 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67830 +
67831 + FmMuramClear(p_Fm->h_FmMuram);
67832 +
67833 + /* clear CPG */
67834 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67835 +
67836 + /* add to the default exceptions the user's definitions */
67837 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67838 +
67839 + /* Reset the FM if required */
67840 + if (p_Fm->resetOnInit)
67841 + {
67842 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67843 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67844 + RETURN_ERROR(MAJOR, err, NO_MSG);
67845 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67846 +
67847 + if (p_Fm->f_ResetOnInitOverride)
67848 + {
67849 + /* Perform user specific FMan reset */
67850 + p_Fm->f_ResetOnInitOverride(h_Fm);
67851 + }
67852 + else
67853 + {
67854 + /* Perform FMan reset */
67855 + FmReset(h_Fm);
67856 + }
67857 +
67858 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67859 + {
67860 + fman_resume(p_Fm->p_FmFpmRegs);
67861 + XX_UDelay(100);
67862 + }
67863 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67864 + }
67865 +
67866 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67867 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67868 + {
67869 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67870 + /* Load FMan-Controller code to IRAM */
67871 +
67872 + ClearIRam(p_Fm);
67873 +
67874 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
67875 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
67876 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67877 + }
67878 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67879 +
67880 +#ifdef FM_CAPWAP_SUPPORT
67881 + /* save first 256 byte in MURAM */
67882 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
67883 + if (!p_Fm->resAddr)
67884 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
67885 +
67886 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
67887 +#endif /* FM_CAPWAP_SUPPORT */
67888 +
67889 +#if (DPAA_VERSION >= 11)
67890 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67891 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67892 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67893 +#endif /* (DPAA_VERSION >= 11) */
67894 +
67895 + /* General FM driver initialization */
67896 + p_Fm->fmMuramPhysBaseAddr =
67897 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67898 +
67899 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67900 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67901 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67902 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
67903 +
67904 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
67905 +
67906 + /**********************/
67907 + /* Init DMA Registers */
67908 + /**********************/
67909 + err = InitFmDma(p_Fm);
67910 + if (err != E_OK)
67911 + {
67912 + FreeInitResources(p_Fm);
67913 + RETURN_ERROR(MAJOR, err, NO_MSG);
67914 + }
67915 +
67916 + /**********************/
67917 + /* Init FPM Registers */
67918 + /**********************/
67919 + err = InitFmFpm(p_Fm);
67920 + if (err != E_OK)
67921 + {
67922 + FreeInitResources(p_Fm);
67923 + RETURN_ERROR(MAJOR, err, NO_MSG);
67924 + }
67925 +
67926 + /* define common resources */
67927 + /* allocate MURAM for FIFO according to total size */
67928 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67929 + p_Fm->p_FmStateStruct->totalFifoSize,
67930 + BMI_FIFO_ALIGN));
67931 + if (!p_Fm->fifoBaseAddr)
67932 + {
67933 + FreeInitResources(p_Fm);
67934 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
67935 + }
67936 +
67937 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67938 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
67939 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
67940 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
67941 +
67942 + /**********************/
67943 + /* Init BMI Registers */
67944 + /**********************/
67945 + err = InitFmBmi(p_Fm);
67946 + if (err != E_OK)
67947 + {
67948 + FreeInitResources(p_Fm);
67949 + RETURN_ERROR(MAJOR, err, NO_MSG);
67950 + }
67951 +
67952 + /**********************/
67953 + /* Init QMI Registers */
67954 + /**********************/
67955 + err = InitFmQmi(p_Fm);
67956 + if (err != E_OK)
67957 + {
67958 + FreeInitResources(p_Fm);
67959 + RETURN_ERROR(MAJOR, err, NO_MSG);
67960 + }
67961 +
67962 + /* build the FM master partition IPC address */
67963 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67964 + {
67965 + FreeInitResources(p_Fm);
67966 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67967 + }
67968 +
67969 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67970 + if (err)
67971 + {
67972 + FreeInitResources(p_Fm);
67973 + RETURN_ERROR(MAJOR, err, NO_MSG);
67974 + }
67975 +
67976 + /* Register the FM interrupts handlers */
67977 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67978 + {
67979 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
67980 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
67981 + }
67982 +
67983 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67984 + {
67985 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
67986 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
67987 + }
67988 +
67989 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
67990 + if (err != E_OK)
67991 + return err; /* FIXME */
67992 +
67993 + EnableTimeStamp(p_Fm);
67994 +
67995 + if (p_Fm->firmware.p_Code)
67996 + {
67997 + XX_Free(p_Fm->firmware.p_Code);
67998 + p_Fm->firmware.p_Code = NULL;
67999 + }
68000 +
68001 + XX_Free(p_Fm->p_FmDriverParam);
68002 + p_Fm->p_FmDriverParam = NULL;
68003 +
68004 + return E_OK;
68005 +}
68006 +
68007 +/**************************************************************************//**
68008 + @Function FM_Free
68009 +
68010 + @Description Frees all resources that were assigned to FM module.
68011 +
68012 + Calling this routine invalidates the descriptor.
68013 +
68014 + @Param[in] h_Fm - FM module descriptor
68015 +
68016 + @Return E_OK on success; Error code otherwise.
68017 +*//***************************************************************************/
68018 +t_Error FM_Free(t_Handle h_Fm)
68019 +{
68020 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68021 + struct fman_rg fman_rg;
68022 +
68023 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68024 +
68025 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68026 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68027 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68028 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68029 +
68030 + if (p_Fm->guestId != NCSW_MASTER_ID)
68031 + {
68032 +#if (DPAA_VERSION >= 11)
68033 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68034 +
68035 + if (p_Fm->p_FmSp)
68036 + {
68037 + XX_Free(p_Fm->p_FmSp);
68038 + p_Fm->p_FmSp = NULL;
68039 + }
68040 +#endif /* (DPAA_VERSION >= 11) */
68041 +
68042 + if (p_Fm->fmModuleName[0] != 0)
68043 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68044 +
68045 + if (!p_Fm->recoveryMode)
68046 + XX_Free(p_Fm->p_FmStateStruct);
68047 +
68048 + XX_Free(p_Fm);
68049 +
68050 + return E_OK;
68051 + }
68052 +
68053 + fman_free_resources(&fman_rg);
68054 +
68055 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
68056 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68057 +
68058 + if (p_Fm->p_FmStateStruct)
68059 + {
68060 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
68061 + {
68062 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
68063 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
68064 + }
68065 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
68066 + {
68067 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
68068 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
68069 + }
68070 + }
68071 +
68072 +#if (DPAA_VERSION >= 11)
68073 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68074 +
68075 + if (p_Fm->p_FmSp)
68076 + {
68077 + XX_Free(p_Fm->p_FmSp);
68078 + p_Fm->p_FmSp = NULL;
68079 + }
68080 +#endif /* (DPAA_VERSION >= 11) */
68081 +
68082 + if (p_Fm->h_Spinlock)
68083 + XX_FreeSpinlock(p_Fm->h_Spinlock);
68084 +
68085 + if (p_Fm->p_FmDriverParam)
68086 + {
68087 + if (p_Fm->firmware.p_Code)
68088 + XX_Free(p_Fm->firmware.p_Code);
68089 + XX_Free(p_Fm->p_FmDriverParam);
68090 + p_Fm->p_FmDriverParam = NULL;
68091 + }
68092 +
68093 + FreeInitResources(p_Fm);
68094 +
68095 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
68096 + XX_Free(p_Fm->p_FmStateStruct);
68097 +
68098 + XX_Free(p_Fm);
68099 +
68100 + return E_OK;
68101 +}
68102 +
68103 +/*************************************************/
68104 +/* API Advanced Init unit functions */
68105 +/*************************************************/
68106 +
68107 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
68108 +{
68109 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68110 +
68111 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68112 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68113 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68114 +
68115 + p_Fm->resetOnInit = enable;
68116 +
68117 + return E_OK;
68118 +}
68119 +
68120 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
68121 +{
68122 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68123 +
68124 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68125 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68126 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68127 +
68128 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
68129 +
68130 + return E_OK;
68131 +}
68132 +
68133 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
68134 +{
68135 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68136 +
68137 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68138 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68139 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68140 +
68141 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
68142 +
68143 + return E_OK;
68144 +}
68145 +
68146 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
68147 +{
68148 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68149 + enum fman_dma_cache_override fsl_cache_override;
68150 +
68151 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68152 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68153 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68154 +
68155 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
68156 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
68157 +
68158 + return E_OK;
68159 +}
68160 +
68161 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
68162 +{
68163 + t_Fm *p_Fm = (t_Fm*)h_Fm;
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 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
68170 +
68171 + return E_OK;
68172 +}
68173 +
68174 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
68175 +{
68176 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68177 + enum fman_dma_aid_mode fsl_aid_mode;
68178 +
68179 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68180 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68181 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68182 +
68183 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
68184 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
68185 +
68186 + return E_OK;
68187 +}
68188 +
68189 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
68190 +{
68191 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68192 +
68193 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68194 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68195 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68196 +
68197 +#if (DPAA_VERSION >= 11)
68198 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68199 +#else
68200 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
68201 +
68202 + return E_OK;
68203 +#endif /* (DPAA_VERSION >= 11) */
68204 +}
68205 +
68206 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
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 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
68215 +
68216 + return E_OK;
68217 +}
68218 +
68219 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
68220 +{
68221 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68222 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
68223 +
68224 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68225 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68226 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68227 +
68228 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
68229 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
68230 +
68231 + return E_OK;
68232 +}
68233 +
68234 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
68235 +{
68236 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68237 +
68238 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68239 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68240 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68241 +
68242 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
68243 +
68244 + return E_OK;
68245 +}
68246 +
68247 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
68248 +{
68249 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68250 + enum fman_dma_emergency_level fsl_dma_emer;
68251 +
68252 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68253 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68254 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68255 +
68256 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
68257 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
68258 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
68259 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
68260 +
68261 + return E_OK;
68262 +}
68263 +
68264 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
68265 +{
68266 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68267 +
68268 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68269 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68270 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68271 +
68272 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
68273 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
68274 +
68275 + return E_OK;
68276 +}
68277 +
68278 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
68279 +{
68280 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68281 + enum fman_dma_err fsl_dma_err;
68282 +
68283 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68284 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68285 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68286 +
68287 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68288 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68289 +
68290 + return E_OK;
68291 +}
68292 +
68293 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68294 +{
68295 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68296 + enum fman_catastrophic_err fsl_catastrophic_err;
68297 +
68298 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68299 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68300 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68301 +
68302 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68303 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68304 +
68305 + return E_OK;
68306 +}
68307 +
68308 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68309 +{
68310 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68311 +
68312 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68313 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68314 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68315 +
68316 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68317 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68318 +
68319 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68320 +
68321 + return E_OK;
68322 +}
68323 +
68324 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68325 +{
68326 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68327 +
68328 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68329 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68330 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68331 +
68332 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68333 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68334 +
68335 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68336 +
68337 + return E_OK;
68338 +}
68339 +
68340 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
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 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68349 +
68350 + return E_OK;
68351 +}
68352 +
68353 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
68354 +{
68355 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68356 +
68357 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68358 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68359 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68360 +
68361 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68362 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68363 +
68364 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68365 +
68366 + return E_OK;
68367 +}
68368 +
68369 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68370 +{
68371 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68372 + uint32_t bitMask = 0;
68373 +
68374 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68375 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68376 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68377 +
68378 + GET_EXCEPTION_FLAG(bitMask, exception);
68379 + if (bitMask)
68380 + {
68381 + if (enable)
68382 + p_Fm->userSetExceptions |= bitMask;
68383 + else
68384 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68385 + }
68386 + else
68387 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68388 +
68389 + return E_OK;
68390 +}
68391 +
68392 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68393 +{
68394 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68395 +
68396 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68397 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68398 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68399 +
68400 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68401 +
68402 + return E_OK;
68403 +}
68404 +
68405 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
68406 +{
68407 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68408 +
68409 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68410 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68411 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68412 +
68413 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
68414 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68415 +
68416 + return E_OK;
68417 +}
68418 +
68419 +/****************************************************/
68420 +/* Hidden-DEBUG Only API */
68421 +/****************************************************/
68422 +
68423 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68424 +{
68425 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68426 +
68427 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68428 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68429 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68430 +
68431 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68432 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68433 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68434 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68435 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68436 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68437 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68438 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68439 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68440 +
68441 + return E_OK;
68442 +}
68443 +
68444 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68445 +{
68446 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68447 +
68448 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68449 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68450 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68451 +
68452 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68453 +
68454 + return E_OK;
68455 +}
68456 +
68457 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68458 +
68459 +{
68460 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68461 +
68462 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68463 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68464 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68465 +
68466 +#if (DPAA_VERSION >= 11)
68467 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68468 +#else
68469 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68470 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68471 +
68472 + return E_OK;
68473 +#endif
68474 +}
68475 +
68476 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68477 +{
68478 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68479 +
68480 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68481 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68482 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68483 +
68484 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68485 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68486 +
68487 + return E_OK;
68488 +}
68489 +
68490 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68491 +{
68492 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68493 +
68494 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68495 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68496 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68497 +
68498 +#if (DPAA_VERSION >= 11)
68499 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68500 +#else
68501 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68502 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68503 +
68504 + return E_OK;
68505 +#endif
68506 +}
68507 +
68508 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68509 +{
68510 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68511 +
68512 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68513 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68514 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68515 +
68516 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68517 +
68518 + return E_OK;
68519 +}
68520 +
68521 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68522 +{
68523 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68524 +
68525 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68526 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68527 +UNUSED(p_Fm);
68528 +
68529 + return E_OK;
68530 +}
68531 +
68532 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68533 +{
68534 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68535 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68536 + {
68537 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68538 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68539 + }
68540 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68541 + {
68542 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68543 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68544 + }
68545 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68546 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68547 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68548 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68549 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68550 + {
68551 + if (p_Params->setParams.sleep)
68552 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68553 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68554 + else
68555 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68556 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68557 + }
68558 + if (p_Params->getParams.type & GET_FM_CLD)
68559 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68560 + if (p_Params->getParams.type & GET_FMQM_GS)
68561 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68562 + if (p_Params->getParams.type & GET_FM_NPI)
68563 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68564 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68565 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68566 + return E_OK;
68567 +}
68568 +
68569 +
68570 +/****************************************************/
68571 +/* API Run-time Control uint functions */
68572 +/****************************************************/
68573 +void FM_EventIsr(t_Handle h_Fm)
68574 +{
68575 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68576 + { \
68577 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68578 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68579 + else \
68580 + 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);\
68581 + }
68582 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68583 + { \
68584 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68585 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68586 + else \
68587 + 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);\
68588 + }
68589 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68590 + uint32_t pending, event;
68591 + struct fman_fpm_regs *fpm_rg;
68592 +
68593 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68594 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68595 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68596 +
68597 + fpm_rg = p_Fm->p_FmFpmRegs;
68598 +
68599 + /* normal interrupts */
68600 + pending = fman_get_normal_pending(fpm_rg);
68601 + if (!pending)
68602 + return;
68603 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68604 + {
68605 + t_FmGetSetParams fmGetSetParams;
68606 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68607 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68608 + fmGetSetParams.setParams.sleep = 0;
68609 + FmGetSetParams(h_Fm, &fmGetSetParams);
68610 + }
68611 + if (pending & INTR_EN_QMI)
68612 + QmiEvent(p_Fm);
68613 + if (pending & INTR_EN_PRS)
68614 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68615 + if (pending & INTR_EN_PLCR)
68616 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68617 + if (pending & INTR_EN_TMR)
68618 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68619 +
68620 + /* MAC events may belong to different partitions */
68621 + if (pending & INTR_EN_1G_MAC0)
68622 + FM_M_CALL_1G_MAC_ISR(0);
68623 + if (pending & INTR_EN_1G_MAC1)
68624 + FM_M_CALL_1G_MAC_ISR(1);
68625 + if (pending & INTR_EN_1G_MAC2)
68626 + FM_M_CALL_1G_MAC_ISR(2);
68627 + if (pending & INTR_EN_1G_MAC3)
68628 + FM_M_CALL_1G_MAC_ISR(3);
68629 + if (pending & INTR_EN_1G_MAC4)
68630 + FM_M_CALL_1G_MAC_ISR(4);
68631 + if (pending & INTR_EN_1G_MAC5)
68632 + FM_M_CALL_1G_MAC_ISR(5);
68633 + if (pending & INTR_EN_1G_MAC6)
68634 + FM_M_CALL_1G_MAC_ISR(6);
68635 + if (pending & INTR_EN_1G_MAC7)
68636 + FM_M_CALL_1G_MAC_ISR(7);
68637 + if (pending & INTR_EN_10G_MAC0)
68638 + FM_M_CALL_10G_MAC_ISR(0);
68639 + if (pending & INTR_EN_10G_MAC1)
68640 + FM_M_CALL_10G_MAC_ISR(1);
68641 +
68642 + /* IM port events may belong to different partitions */
68643 + if (pending & INTR_EN_REV0)
68644 + {
68645 + event = fman_get_controller_event(fpm_rg, 0);
68646 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68647 + /*TODO IPC ISR For Fman Ctrl */
68648 + ASSERT_COND(0);
68649 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68650 + else
68651 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68652 +
68653 + }
68654 + if (pending & INTR_EN_REV1)
68655 + {
68656 + event = fman_get_controller_event(fpm_rg, 1);
68657 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68658 + /*TODO IPC ISR For Fman Ctrl */
68659 + ASSERT_COND(0);
68660 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68661 + else
68662 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68663 + }
68664 + if (pending & INTR_EN_REV2)
68665 + {
68666 + event = fman_get_controller_event(fpm_rg, 2);
68667 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68668 + /*TODO IPC ISR For Fman Ctrl */
68669 + ASSERT_COND(0);
68670 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68671 + else
68672 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68673 + }
68674 + if (pending & INTR_EN_REV3)
68675 + {
68676 + event = fman_get_controller_event(fpm_rg, 3);
68677 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68678 + /*TODO IPC ISR For Fman Ctrl */
68679 + ASSERT_COND(0);
68680 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68681 + else
68682 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68683 + }
68684 +#ifdef FM_MACSEC_SUPPORT
68685 + if (pending & INTR_EN_MACSEC_MAC0)
68686 + {
68687 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68688 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68689 + else
68690 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68691 + }
68692 +#endif /* FM_MACSEC_SUPPORT */
68693 +}
68694 +
68695 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68696 +{
68697 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68698 + { \
68699 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68700 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68701 + else \
68702 + 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);\
68703 + }
68704 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68705 + { \
68706 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68707 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68708 + else \
68709 + 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);\
68710 + }
68711 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68712 + uint32_t pending;
68713 + struct fman_fpm_regs *fpm_rg;
68714 +
68715 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68716 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68717 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68718 +
68719 + fpm_rg = p_Fm->p_FmFpmRegs;
68720 +
68721 + /* error interrupts */
68722 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68723 + if (!pending)
68724 + return ERROR_CODE(E_EMPTY);
68725 +
68726 + if (pending & ERR_INTR_EN_BMI)
68727 + BmiErrEvent(p_Fm);
68728 + if (pending & ERR_INTR_EN_QMI)
68729 + QmiErrEvent(p_Fm);
68730 + if (pending & ERR_INTR_EN_FPM)
68731 + FpmErrEvent(p_Fm);
68732 + if (pending & ERR_INTR_EN_DMA)
68733 + DmaErrEvent(p_Fm);
68734 + if (pending & ERR_INTR_EN_IRAM)
68735 + IramErrIntr(p_Fm);
68736 + if (pending & ERR_INTR_EN_MURAM)
68737 + MuramErrIntr(p_Fm);
68738 + if (pending & ERR_INTR_EN_PRS)
68739 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68740 + if (pending & ERR_INTR_EN_PLCR)
68741 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68742 + if (pending & ERR_INTR_EN_KG)
68743 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68744 +
68745 + /* MAC events may belong to different partitions */
68746 + if (pending & ERR_INTR_EN_1G_MAC0)
68747 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68748 + if (pending & ERR_INTR_EN_1G_MAC1)
68749 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68750 + if (pending & ERR_INTR_EN_1G_MAC2)
68751 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68752 + if (pending & ERR_INTR_EN_1G_MAC3)
68753 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68754 + if (pending & ERR_INTR_EN_1G_MAC4)
68755 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68756 + if (pending & ERR_INTR_EN_1G_MAC5)
68757 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68758 + if (pending & ERR_INTR_EN_1G_MAC6)
68759 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68760 + if (pending & ERR_INTR_EN_1G_MAC7)
68761 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68762 + if (pending & ERR_INTR_EN_10G_MAC0)
68763 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68764 + if (pending & ERR_INTR_EN_10G_MAC1)
68765 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68766 +
68767 +#ifdef FM_MACSEC_SUPPORT
68768 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68769 + {
68770 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68771 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68772 + else
68773 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68774 + }
68775 +#endif /* FM_MACSEC_SUPPORT */
68776 +
68777 + return E_OK;
68778 +}
68779 +
68780 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68781 +{
68782 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68783 + int i;
68784 + uint8_t sum;
68785 + uint8_t hardwarePortId;
68786 + uint8_t weights[64];
68787 + uint8_t weight, maxPercent = 0;
68788 + struct fman_bmi_regs *bmi_rg;
68789 +
68790 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68791 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68792 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68793 +
68794 + bmi_rg = p_Fm->p_FmBmiRegs;
68795 +
68796 + memset(weights, 0, (sizeof(uint8_t) * 64));
68797 +
68798 + /* check that all ports add up to 100% */
68799 + sum = 0;
68800 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68801 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68802 + if (sum != 100)
68803 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68804 +
68805 + /* find highest percent */
68806 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68807 + {
68808 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68809 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68810 + }
68811 +
68812 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68813 +
68814 + /* calculate weight for each port */
68815 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68816 + {
68817 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68818 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68819 + is not reached, we round up so that:
68820 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68821 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68822 + ...
68823 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68824 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68825 + weight++;
68826 +
68827 + /* find the location of this port within the register */
68828 + hardwarePortId =
68829 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68830 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68831 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68832 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68833 +
68834 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68835 + weights[hardwarePortId] = weight;
68836 + }
68837 +
68838 + fman_set_ports_bandwidth(bmi_rg, weights);
68839 +
68840 + return E_OK;
68841 +}
68842 +
68843 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68844 +{
68845 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68846 + struct fman_fpm_regs *fpm_rg;
68847 +
68848 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68849 +
68850 + fpm_rg = p_Fm->p_FmFpmRegs;
68851 +
68852 + if (p_Fm->guestId != NCSW_MASTER_ID)
68853 + {
68854 + t_FmIpcMsg msg;
68855 + t_Error err;
68856 +
68857 + memset(&msg, 0, sizeof(msg));
68858 + msg.msgId = FM_ENABLE_RAM_ECC;
68859 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68860 + (uint8_t*)&msg,
68861 + sizeof(msg.msgId),
68862 + NULL,
68863 + NULL,
68864 + NULL,
68865 + NULL);
68866 + if (err != E_OK)
68867 + RETURN_ERROR(MINOR, err, NO_MSG);
68868 + return E_OK;
68869 + }
68870 +
68871 + if (!p_Fm->p_FmStateStruct->internalCall)
68872 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68873 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68874 +
68875 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
68876 + return E_OK;
68877 + else
68878 + {
68879 + fman_enable_rams_ecc(fpm_rg);
68880 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
68881 + }
68882 +
68883 + return E_OK;
68884 +}
68885 +
68886 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
68887 +{
68888 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68889 + bool explicitDisable = FALSE;
68890 + struct fman_fpm_regs *fpm_rg;
68891 +
68892 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68893 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68894 +
68895 + fpm_rg = p_Fm->p_FmFpmRegs;
68896 +
68897 + if (p_Fm->guestId != NCSW_MASTER_ID)
68898 + {
68899 + t_Error err;
68900 + t_FmIpcMsg msg;
68901 +
68902 + memset(&msg, 0, sizeof(msg));
68903 + msg.msgId = FM_DISABLE_RAM_ECC;
68904 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68905 + (uint8_t*)&msg,
68906 + sizeof(msg.msgId),
68907 + NULL,
68908 + NULL,
68909 + NULL,
68910 + NULL)) != E_OK)
68911 + RETURN_ERROR(MINOR, err, NO_MSG);
68912 + return E_OK;
68913 + }
68914 +
68915 + if (!p_Fm->p_FmStateStruct->internalCall)
68916 + explicitDisable = TRUE;
68917 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68918 +
68919 + /* if rams are already disabled, or if rams were explicitly enabled and are
68920 + currently called indirectly (not explicitly), ignore this call. */
68921 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
68922 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
68923 + return E_OK;
68924 + else
68925 + {
68926 + if (p_Fm->p_FmStateStruct->explicitEnable)
68927 + /* This is the case were both explicit are TRUE.
68928 + Turn off this flag for cases were following ramsEnable
68929 + routines are called */
68930 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
68931 +
68932 + fman_enable_rams_ecc(fpm_rg);
68933 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
68934 + }
68935 +
68936 + return E_OK;
68937 +}
68938 +
68939 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68940 +{
68941 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68942 + uint32_t bitMask = 0;
68943 + enum fman_exceptions fslException;
68944 + struct fman_rg fman_rg;
68945 +
68946 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68947 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68948 +
68949 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68950 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68951 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68952 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68953 +
68954 + GET_EXCEPTION_FLAG(bitMask, exception);
68955 + if (bitMask)
68956 + {
68957 + if (enable)
68958 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
68959 + else
68960 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68961 +
68962 + fslException = FmanExceptionTrans(exception);
68963 +
68964 + return (t_Error)fman_set_exception(&fman_rg,
68965 + fslException,
68966 + enable);
68967 + }
68968 + else
68969 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68970 +
68971 + return E_OK;
68972 +}
68973 +
68974 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
68975 +{
68976 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68977 +
68978 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
68979 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
68980 +
68981 + return E_OK;
68982 +}
68983 +
68984 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
68985 +{
68986 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68987 + t_FMIramRegs *p_Iram;
68988 + uint32_t revInfo;
68989 +
68990 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68991 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
68992 +
68993 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68994 + p_Fm->h_IpcSessions[0])
68995 + {
68996 + t_Error err;
68997 + t_FmIpcMsg msg;
68998 + t_FmIpcReply reply;
68999 + uint32_t replyLength;
69000 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
69001 +
69002 + memset(&msg, 0, sizeof(msg));
69003 + memset(&reply, 0, sizeof(reply));
69004 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
69005 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
69006 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69007 + (uint8_t*)&msg,
69008 + sizeof(msg.msgId),
69009 + (uint8_t*)&reply,
69010 + &replyLength,
69011 + NULL,
69012 + NULL)) != E_OK)
69013 + RETURN_ERROR(MINOR, err, NO_MSG);
69014 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
69015 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69016 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
69017 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
69018 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
69019 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
69020 + return (t_Error)(reply.error);
69021 + }
69022 + else if (p_Fm->guestId != NCSW_MASTER_ID)
69023 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
69024 + ("running in guest-mode without IPC!"));
69025 +
69026 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
69027 + WRITE_UINT32(p_Iram->iadd, 0x4);
69028 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
69029 + revInfo = GET_UINT32(p_Iram->idata);
69030 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
69031 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
69032 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
69033 +
69034 + return E_OK;
69035 +}
69036 +
69037 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
69038 +{
69039 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69040 + t_Error err;
69041 + uint32_t counterValue;
69042 + struct fman_rg fman_rg;
69043 + enum fman_counters fsl_counter;
69044 +
69045 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
69046 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
69047 +
69048 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69049 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69050 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69051 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69052 +
69053 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69054 + !p_Fm->baseAddr &&
69055 + p_Fm->h_IpcSessions[0])
69056 + {
69057 + t_FmIpcMsg msg;
69058 + t_FmIpcReply reply;
69059 + uint32_t replyLength, outCounter;
69060 +
69061 + memset(&msg, 0, sizeof(msg));
69062 + memset(&reply, 0, sizeof(reply));
69063 + msg.msgId = FM_GET_COUNTER;
69064 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
69065 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
69066 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69067 + (uint8_t*)&msg,
69068 + sizeof(msg.msgId) +sizeof(counterValue),
69069 + (uint8_t*)&reply,
69070 + &replyLength,
69071 + NULL,
69072 + NULL);
69073 + if (err != E_OK)
69074 + {
69075 + REPORT_ERROR(MAJOR, err, NO_MSG);
69076 + return 0;
69077 + }
69078 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
69079 + {
69080 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69081 + return 0;
69082 + }
69083 +
69084 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
69085 + return outCounter;
69086 + }
69087 + else if (!p_Fm->baseAddr)
69088 + {
69089 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
69090 + return 0;
69091 + }
69092 +
69093 + /* When applicable (when there is an 'enable counters' bit,
69094 + check that counters are enabled */
69095 + switch (counter)
69096 + {
69097 + case (e_FM_COUNTERS_DEQ_1):
69098 + case (e_FM_COUNTERS_DEQ_2):
69099 + case (e_FM_COUNTERS_DEQ_3):
69100 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
69101 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
69102 + {
69103 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
69104 + return 0;
69105 + }
69106 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
69107 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
69108 + case (e_FM_COUNTERS_DEQ_0):
69109 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
69110 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
69111 + case (e_FM_COUNTERS_DEQ_FROM_FD):
69112 + case (e_FM_COUNTERS_DEQ_CONFIRM):
69113 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
69114 + {
69115 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
69116 + return 0;
69117 + }
69118 + break;
69119 + default:
69120 + break;
69121 + }
69122 +
69123 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69124 + return fman_get_counter(&fman_rg, fsl_counter);
69125 +}
69126 +
69127 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
69128 +{
69129 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69130 + struct fman_rg fman_rg;
69131 + enum fman_counters fsl_counter;
69132 +
69133 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69134 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69135 +
69136 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69137 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69138 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69139 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69140 +
69141 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69142 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
69143 +}
69144 +
69145 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
69146 +{
69147 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69148 + struct fman_dma_regs *dma_rg;
69149 +
69150 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69151 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69152 +
69153 + dma_rg = p_Fm->p_FmDmaRegs;
69154 +
69155 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
69156 +}
69157 +
69158 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
69159 +{
69160 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69161 + struct fman_dma_regs *dma_rg;
69162 +
69163 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69164 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69165 +
69166 + dma_rg = p_Fm->p_FmDmaRegs;
69167 +
69168 + fman_set_dma_ext_bus_pri(dma_rg, pri);
69169 +}
69170 +
69171 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
69172 +{
69173 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69174 + uint32_t dmaStatus;
69175 + struct fman_dma_regs *dma_rg;
69176 +
69177 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69178 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69179 +
69180 + dma_rg = p_Fm->p_FmDmaRegs;
69181 +
69182 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69183 + !p_Fm->baseAddr &&
69184 + p_Fm->h_IpcSessions[0])
69185 + {
69186 + t_FmIpcDmaStatus ipcDmaStatus;
69187 + t_FmIpcMsg msg;
69188 + t_FmIpcReply reply;
69189 + t_Error err;
69190 + uint32_t replyLength;
69191 +
69192 + memset(&msg, 0, sizeof(msg));
69193 + memset(&reply, 0, sizeof(reply));
69194 + msg.msgId = FM_DMA_STAT;
69195 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
69196 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69197 + (uint8_t*)&msg,
69198 + sizeof(msg.msgId),
69199 + (uint8_t*)&reply,
69200 + &replyLength,
69201 + NULL,
69202 + NULL);
69203 + if (err != E_OK)
69204 + {
69205 + REPORT_ERROR(MINOR, err, NO_MSG);
69206 + return;
69207 + }
69208 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
69209 + {
69210 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69211 + return;
69212 + }
69213 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
69214 +
69215 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
69216 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
69217 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
69218 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
69219 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
69220 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
69221 + return;
69222 + }
69223 + else if (!p_Fm->baseAddr)
69224 + {
69225 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
69226 + ("Either IPC or 'baseAddress' is required!"));
69227 + return;
69228 + }
69229 +
69230 + dmaStatus = fman_get_dma_status(dma_rg);
69231 +
69232 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
69233 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
69234 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69235 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
69236 + else
69237 + {
69238 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
69239 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
69240 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
69241 + }
69242 +}
69243 +
69244 +void FM_Resume(t_Handle h_Fm)
69245 +{
69246 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69247 + struct fman_fpm_regs *fpm_rg;
69248 +
69249 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69250 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69251 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69252 +
69253 + fpm_rg = p_Fm->p_FmFpmRegs;
69254 +
69255 + fman_resume(fpm_rg);
69256 +}
69257 +
69258 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
69259 + fmSpecialOperations_t spOper,
69260 + uint8_t *p_SpOperCoding)
69261 +{
69262 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69263 + t_FmCtrlCodeRevisionInfo revInfo;
69264 + t_Error err;
69265 +
69266 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69267 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69268 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
69269 +
69270 + if (!spOper)
69271 + {
69272 + *p_SpOperCoding = 0;
69273 + return E_OK;
69274 + }
69275 +
69276 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
69277 + {
69278 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
69279 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
69280 + }
69281 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69282 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69283 +
69284 + switch (spOper)
69285 + {
69286 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69287 + *p_SpOperCoding = 9;
69288 + break;
69289 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69290 + *p_SpOperCoding = 10;
69291 + break;
69292 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69293 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69294 + *p_SpOperCoding = 5;
69295 + break;
69296 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69297 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69298 + *p_SpOperCoding = 6;
69299 + break;
69300 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69301 + *p_SpOperCoding = 3;
69302 + break;
69303 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69304 + *p_SpOperCoding = 1;
69305 + break;
69306 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69307 + *p_SpOperCoding = 12;
69308 + break;
69309 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69310 + *p_SpOperCoding = 4;
69311 + break;
69312 + case (FM_SP_OP_IPSEC):
69313 + *p_SpOperCoding = 2;
69314 + break;
69315 + case (FM_SP_OP_DCL4C):
69316 + *p_SpOperCoding = 7;
69317 + break;
69318 + case (FM_SP_OP_CLEAR_RPD):
69319 + *p_SpOperCoding = 8;
69320 + break;
69321 + default:
69322 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69323 + }
69324 +
69325 + return E_OK;
69326 +}
69327 +
69328 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69329 +{
69330 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69331 + t_FmTrbRegs *p_MonRegs;
69332 + uint8_t i;
69333 +
69334 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69335 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69336 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69337 +
69338 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69339 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69340 +
69341 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69342 + {
69343 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69344 +
69345 + /* Reset control registers */
69346 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69347 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69348 +
69349 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69350 + counter #2 counts all stalls in risc - other stall*/
69351 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69352 +
69353 + /* Enable monitoring */
69354 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69355 + }
69356 +
69357 + return E_OK;
69358 +}
69359 +
69360 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69361 +{
69362 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69363 + t_FmTrbRegs *p_MonRegs;
69364 + uint8_t i;
69365 +
69366 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69367 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69368 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69369 +
69370 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69371 + {
69372 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69373 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69374 + }
69375 +
69376 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69377 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69378 +
69379 + return E_OK;
69380 +}
69381 +
69382 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69383 +{
69384 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69385 + t_FmTrbRegs *p_MonRegs;
69386 + uint64_t clkCnt, utilValue, effValue;
69387 +
69388 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69389 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69390 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69391 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69392 +
69393 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69394 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69395 +
69396 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69397 +
69398 + clkCnt = (uint64_t)
69399 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69400 +
69401 + utilValue = (uint64_t)
69402 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69403 +
69404 + effValue = (uint64_t)
69405 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69406 +
69407 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69408 + if (clkCnt != utilValue)
69409 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69410 + else
69411 + p_Mon->percentCnt[1] = 0;
69412 +
69413 + return E_OK;
69414 +}
69415 +
69416 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69417 +{
69418 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69419 +
69420 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69421 +
69422 + return (p_Fm->h_FmMuram);
69423 +}
69424 +
69425 +/****************************************************/
69426 +/* Hidden-DEBUG Only API */
69427 +/****************************************************/
69428 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69429 +{
69430 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69431 + enum fman_exceptions fslException;
69432 + struct fman_rg fman_rg;
69433 +
69434 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69435 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69436 +
69437 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69438 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69439 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69440 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69441 +
69442 + switch (exception)
69443 + {
69444 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69445 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69446 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69447 + break;
69448 + case e_FM_EX_QMI_SINGLE_ECC:
69449 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69450 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69451 +
69452 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69453 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69454 + break;
69455 + case e_FM_EX_QMI_DOUBLE_ECC:
69456 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69457 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69458 + break;
69459 + case e_FM_EX_BMI_LIST_RAM_ECC:
69460 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69461 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69462 + break;
69463 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69464 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69465 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69466 + break;
69467 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69468 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69469 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69470 + break;
69471 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69472 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69473 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69474 + break;
69475 + default:
69476 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69477 + }
69478 +
69479 + fslException = FmanExceptionTrans(exception);
69480 + fman_force_intr (&fman_rg, fslException);
69481 +
69482 + return E_OK;
69483 +}
69484 +
69485 +t_Handle FmGetPcd(t_Handle h_Fm)
69486 +{
69487 + return ((t_Fm*)h_Fm)->h_Pcd;
69488 +}
69489 +#if (DPAA_VERSION >= 11)
69490 +extern void *g_MemacRegs;
69491 +void fm_clk_down(void);
69492 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69493 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69494 +{
69495 + int macId;
69496 + uint32_t event, rcr;
69497 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69498 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69499 + rcr |= 0x04000000;
69500 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69501 +
69502 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69503 + do
69504 + {
69505 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69506 + } while ((event & 0x00000020) == 0);
69507 + fm_clk_down();
69508 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69509 + rcr &= ~0x04000000;
69510 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69511 +}
69512 +#endif
69513 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69514 new file mode 100644
69515 index 00000000..0bded75d
69516 --- /dev/null
69517 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69518 @@ -0,0 +1,648 @@
69519 +/*
69520 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69521 + *
69522 + * Redistribution and use in source and binary forms, with or without
69523 + * modification, are permitted provided that the following conditions are met:
69524 + * * Redistributions of source code must retain the above copyright
69525 + * notice, this list of conditions and the following disclaimer.
69526 + * * Redistributions in binary form must reproduce the above copyright
69527 + * notice, this list of conditions and the following disclaimer in the
69528 + * documentation and/or other materials provided with the distribution.
69529 + * * Neither the name of Freescale Semiconductor nor the
69530 + * names of its contributors may be used to endorse or promote products
69531 + * derived from this software without specific prior written permission.
69532 + *
69533 + *
69534 + * ALTERNATIVELY, this software may be distributed under the terms of the
69535 + * GNU General Public License ("GPL") as published by the Free Software
69536 + * Foundation, either version 2 of that License or (at your option) any
69537 + * later version.
69538 + *
69539 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69540 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69541 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69542 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69543 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69544 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69545 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69546 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69547 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69548 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69549 + */
69550 +
69551 +
69552 +/******************************************************************************
69553 + @File fm.h
69554 +
69555 + @Description FM internal structures and definitions.
69556 +*//***************************************************************************/
69557 +#ifndef __FM_H
69558 +#define __FM_H
69559 +
69560 +#include "error_ext.h"
69561 +#include "std_ext.h"
69562 +#include "fm_ext.h"
69563 +#include "fm_ipc.h"
69564 +
69565 +#include "fsl_fman.h"
69566 +
69567 +#define __ERR_MODULE__ MODULE_FM
69568 +
69569 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69570 +#define FM_MAX_NUM_OF_GUESTS 100
69571 +
69572 +/**************************************************************************//**
69573 + @Description Exceptions
69574 +*//***************************************************************************/
69575 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69576 +#define FM_EX_DMA_READ_ECC 0x40000000
69577 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69578 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69579 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69580 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69581 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69582 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69583 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69584 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69585 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69586 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69587 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69588 +#define FM_EX_IRAM_ECC 0x00040000
69589 +#define FM_EX_MURAM_ECC 0x00020000
69590 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69591 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69592 +
69593 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69594 +
69595 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69596 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69597 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69598 +
69599 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69600 +switch (exception){ \
69601 + case e_FM_EX_DMA_BUS_ERROR: \
69602 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69603 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69604 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69605 + case e_FM_EX_DMA_READ_ECC: \
69606 + bitMask = FM_EX_DMA_READ_ECC; break; \
69607 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69608 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69609 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69610 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69611 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69612 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69613 + case e_FM_EX_FPM_SINGLE_ECC: \
69614 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69615 + case e_FM_EX_FPM_DOUBLE_ECC: \
69616 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69617 + case e_FM_EX_QMI_SINGLE_ECC: \
69618 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69619 + case e_FM_EX_QMI_DOUBLE_ECC: \
69620 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69621 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69622 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69623 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69624 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69625 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69626 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69627 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69628 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69629 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69630 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69631 + case e_FM_EX_IRAM_ECC: \
69632 + bitMask = FM_EX_IRAM_ECC; break; \
69633 + case e_FM_EX_MURAM_ECC: \
69634 + bitMask = FM_EX_MURAM_ECC; break; \
69635 + default: bitMask = 0;break; \
69636 +}
69637 +
69638 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69639 + switch (_mod) { \
69640 + case e_FM_MOD_PRS: \
69641 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69642 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69643 + break; \
69644 + case e_FM_MOD_KG: \
69645 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69646 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69647 + break; \
69648 + case e_FM_MOD_PLCR: \
69649 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69650 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69651 + break; \
69652 + case e_FM_MOD_TMR: \
69653 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69654 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69655 + break; \
69656 + case e_FM_MOD_10G_MAC: \
69657 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69658 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69659 + break; \
69660 + case e_FM_MOD_1G_MAC: \
69661 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69662 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69663 + break; \
69664 + case e_FM_MOD_MACSEC: \
69665 + switch (_id){ \
69666 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69667 + break; \
69668 + } \
69669 + break; \
69670 + case e_FM_MOD_FMAN_CTRL: \
69671 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69672 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69673 + break; \
69674 + default: _event = e_FM_EV_DUMMY_LAST; \
69675 + break; \
69676 + }
69677 +
69678 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69679 + switch (_cache_override){ \
69680 + case e_FM_DMA_NO_CACHE_OR: \
69681 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69682 + case e_FM_DMA_NO_STASH_DATA: \
69683 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69684 + case e_FM_DMA_MAY_STASH_DATA: \
69685 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69686 + case e_FM_DMA_STASH_DATA: \
69687 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69688 + default: \
69689 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69690 + }
69691 +
69692 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69693 + switch (_aid_mode){ \
69694 + case e_FM_DMA_AID_OUT_PORT_ID: \
69695 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69696 + case e_FM_DMA_AID_OUT_TNUM: \
69697 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69698 + default: \
69699 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69700 + }
69701 +
69702 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69703 + switch (_dma_dbg_cnt){ \
69704 + case e_FM_DMA_DBG_NO_CNT: \
69705 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69706 + case e_FM_DMA_DBG_CNT_DONE: \
69707 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69708 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69709 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69710 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69711 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69712 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69713 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69714 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69715 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69716 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69717 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69718 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69719 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69720 + default: \
69721 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69722 + }
69723 +
69724 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69725 + switch (_dma_emer){ \
69726 + case e_FM_DMA_EM_EBS: \
69727 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69728 + case e_FM_DMA_EM_SOS: \
69729 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69730 + default: \
69731 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69732 + }
69733 +
69734 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69735 + switch (_dma_err){ \
69736 + case e_FM_DMA_ERR_CATASTROPHIC: \
69737 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69738 + case e_FM_DMA_ERR_REPORT: \
69739 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69740 + default: \
69741 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69742 + }
69743 +
69744 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69745 + switch (_catastrophic_err){ \
69746 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69747 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69748 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69749 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69750 + default: \
69751 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69752 + }
69753 +
69754 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69755 + switch (_counters){ \
69756 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69757 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69758 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69759 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69760 + case e_FM_COUNTERS_DEQ_0: \
69761 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69762 + case e_FM_COUNTERS_DEQ_1: \
69763 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69764 + case e_FM_COUNTERS_DEQ_2: \
69765 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69766 + case e_FM_COUNTERS_DEQ_3: \
69767 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69768 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69769 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69770 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69771 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69772 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69773 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69774 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69775 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69776 + default: \
69777 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69778 + }
69779 +
69780 +/**************************************************************************//**
69781 + @Description defaults
69782 +*//***************************************************************************/
69783 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69784 + FM_EX_DMA_READ_ECC |\
69785 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69786 + FM_EX_DMA_FM_WRITE_ECC |\
69787 + FM_EX_FPM_STALL_ON_TASKS |\
69788 + FM_EX_FPM_SINGLE_ECC |\
69789 + FM_EX_FPM_DOUBLE_ECC |\
69790 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69791 + FM_EX_BMI_LIST_RAM_ECC |\
69792 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69793 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69794 + FM_EX_IRAM_ECC |\
69795 + FM_EX_MURAM_ECC |\
69796 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69797 + FM_EX_QMI_DOUBLE_ECC |\
69798 + FM_EX_QMI_SINGLE_ECC)
69799 +
69800 +#define DEFAULT_eccEnable FALSE
69801 +#ifdef FM_PEDANTIC_DMA
69802 +#define DEFAULT_aidOverride TRUE
69803 +#else
69804 +#define DEFAULT_aidOverride FALSE
69805 +#endif /* FM_PEDANTIC_DMA */
69806 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69807 +#define DEFAULT_dmaStopOnBusError FALSE
69808 +#define DEFAULT_stopAtBusError FALSE
69809 +#define DEFAULT_axiDbgNumOfBeats 1
69810 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69811 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69812 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69813 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69814 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69815 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69816 +#define DEFAULT_resetOnInit FALSE
69817 +#define DEFAULT_resetOnInitOverrideCallback NULL
69818 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69819 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69820 +#define DEFAULT_externalEccRamsEnable FALSE
69821 +#define DEFAULT_VerifyUcode FALSE
69822 +
69823 +#if (DPAA_VERSION < 11)
69824 +#define DEFAULT_totalFifoSize(major, minor) \
69825 + (((major == 2) || (major == 5)) ? \
69826 + (100*KILOBYTE) : ((major == 4) ? \
69827 + (49*KILOBYTE) : (122*KILOBYTE)))
69828 +#define DEFAULT_totalNumOfTasks(major, minor) \
69829 + BMI_MAX_NUM_OF_TASKS
69830 +
69831 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69832 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69833 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69834 +#define DEFAULT_dmaCamNumOfEntries 32
69835 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69836 +#define DEFAULT_dmaEnEmergency FALSE
69837 +#define DEFAULT_dmaSosEmergency 0
69838 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69839 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69840 +#define DEFAULT_dmaEmergencySwitchCounter 0
69841 +
69842 +#define DEFAULT_dispLimit 0
69843 +#define DEFAULT_prsDispTh 16
69844 +#define DEFAULT_plcrDispTh 16
69845 +#define DEFAULT_kgDispTh 16
69846 +#define DEFAULT_bmiDispTh 16
69847 +#define DEFAULT_qmiEnqDispTh 16
69848 +#define DEFAULT_qmiDeqDispTh 16
69849 +#define DEFAULT_fmCtl1DispTh 16
69850 +#define DEFAULT_fmCtl2DispTh 16
69851 +
69852 +#else /* (DPAA_VERSION < 11) */
69853 +/* Defaults are registers' reset values */
69854 +#define DEFAULT_totalFifoSize(major, minor) \
69855 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69856 + (156*KILOBYTE) : (295*KILOBYTE))
69857 +
69858 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69859 +#define DEFAULT_totalNumOfTasks(major, minor) \
69860 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69861 +
69862 +#define DEFAULT_dmaCommQLow 0x2A
69863 +#define DEFAULT_dmaCommQHigh 0x3F
69864 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69865 +#define DEFAULT_dmaCamNumOfEntries 64
69866 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69867 +#define DEFAULT_dmaEnEmergency FALSE
69868 +#define DEFAULT_dmaSosEmergency 0
69869 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69870 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69871 +#define DEFAULT_dmaEmergencySwitchCounter 0
69872 +
69873 +#define DEFAULT_dispLimit 0
69874 +#define DEFAULT_prsDispTh 16
69875 +#define DEFAULT_plcrDispTh 16
69876 +#define DEFAULT_kgDispTh 16
69877 +#define DEFAULT_bmiDispTh 16
69878 +#define DEFAULT_qmiEnqDispTh 16
69879 +#define DEFAULT_qmiDeqDispTh 16
69880 +#define DEFAULT_fmCtl1DispTh 16
69881 +#define DEFAULT_fmCtl2DispTh 16
69882 +#endif /* (DPAA_VERSION < 11) */
69883 +
69884 +#define FM_TIMESTAMP_1_USEC_BIT 8
69885 +
69886 +/**************************************************************************//**
69887 + @Collection Defines used for enabling/disabling FM interrupts
69888 + @{
69889 +*//***************************************************************************/
69890 +#define ERR_INTR_EN_DMA 0x00010000
69891 +#define ERR_INTR_EN_FPM 0x80000000
69892 +#define ERR_INTR_EN_BMI 0x00800000
69893 +#define ERR_INTR_EN_QMI 0x00400000
69894 +#define ERR_INTR_EN_PRS 0x00200000
69895 +#define ERR_INTR_EN_KG 0x00100000
69896 +#define ERR_INTR_EN_PLCR 0x00080000
69897 +#define ERR_INTR_EN_MURAM 0x00040000
69898 +#define ERR_INTR_EN_IRAM 0x00020000
69899 +#define ERR_INTR_EN_10G_MAC0 0x00008000
69900 +#define ERR_INTR_EN_10G_MAC1 0x00000040
69901 +#define ERR_INTR_EN_1G_MAC0 0x00004000
69902 +#define ERR_INTR_EN_1G_MAC1 0x00002000
69903 +#define ERR_INTR_EN_1G_MAC2 0x00001000
69904 +#define ERR_INTR_EN_1G_MAC3 0x00000800
69905 +#define ERR_INTR_EN_1G_MAC4 0x00000400
69906 +#define ERR_INTR_EN_1G_MAC5 0x00000200
69907 +#define ERR_INTR_EN_1G_MAC6 0x00000100
69908 +#define ERR_INTR_EN_1G_MAC7 0x00000080
69909 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
69910 +
69911 +#define INTR_EN_QMI 0x40000000
69912 +#define INTR_EN_PRS 0x20000000
69913 +#define INTR_EN_WAKEUP 0x10000000
69914 +#define INTR_EN_PLCR 0x08000000
69915 +#define INTR_EN_1G_MAC0 0x00080000
69916 +#define INTR_EN_1G_MAC1 0x00040000
69917 +#define INTR_EN_1G_MAC2 0x00020000
69918 +#define INTR_EN_1G_MAC3 0x00010000
69919 +#define INTR_EN_1G_MAC4 0x00000040
69920 +#define INTR_EN_1G_MAC5 0x00000020
69921 +#define INTR_EN_1G_MAC6 0x00000008
69922 +#define INTR_EN_1G_MAC7 0x00000002
69923 +#define INTR_EN_10G_MAC0 0x00200000
69924 +#define INTR_EN_10G_MAC1 0x00100000
69925 +#define INTR_EN_REV0 0x00008000
69926 +#define INTR_EN_REV1 0x00004000
69927 +#define INTR_EN_REV2 0x00002000
69928 +#define INTR_EN_REV3 0x00001000
69929 +#define INTR_EN_BRK 0x00000080
69930 +#define INTR_EN_TMR 0x01000000
69931 +#define INTR_EN_MACSEC_MAC0 0x00000001
69932 +/* @} */
69933 +
69934 +/**************************************************************************//**
69935 + @Description Memory Mapped Registers
69936 +*//***************************************************************************/
69937 +
69938 +#if defined(__MWERKS__) && !defined(__GNUC__)
69939 +#pragma pack(push,1)
69940 +#endif /* defined(__MWERKS__) && ... */
69941 +
69942 +typedef struct
69943 +{
69944 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
69945 + volatile uint32_t idata; /**< FM IRAM instruction data register */
69946 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
69947 + volatile uint32_t iready; /**< FM IRAM ready register */
69948 + volatile uint32_t res[0x1FFFC];
69949 +} t_FMIramRegs;
69950 +
69951 +/* Trace buffer registers -
69952 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
69953 +typedef struct t_FmTrbRegs
69954 +{
69955 + volatile uint32_t tcrh;
69956 + volatile uint32_t tcrl;
69957 + volatile uint32_t tesr;
69958 + volatile uint32_t tecr0h;
69959 + volatile uint32_t tecr0l;
69960 + volatile uint32_t terf0h;
69961 + volatile uint32_t terf0l;
69962 + volatile uint32_t tecr1h;
69963 + volatile uint32_t tecr1l;
69964 + volatile uint32_t terf1h;
69965 + volatile uint32_t terf1l;
69966 + volatile uint32_t tpcch;
69967 + volatile uint32_t tpccl;
69968 + volatile uint32_t tpc1h;
69969 + volatile uint32_t tpc1l;
69970 + volatile uint32_t tpc2h;
69971 + volatile uint32_t tpc2l;
69972 + volatile uint32_t twdimr;
69973 + volatile uint32_t twicvr;
69974 + volatile uint32_t tar;
69975 + volatile uint32_t tdr;
69976 + volatile uint32_t tsnum1;
69977 + volatile uint32_t tsnum2;
69978 + volatile uint32_t tsnum3;
69979 + volatile uint32_t tsnum4;
69980 +} t_FmTrbRegs;
69981 +
69982 +#if defined(__MWERKS__) && !defined(__GNUC__)
69983 +#pragma pack(pop)
69984 +#endif /* defined(__MWERKS__) && ... */
69985 +
69986 +/**************************************************************************//**
69987 + @Description General defines
69988 +*//***************************************************************************/
69989 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
69990 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
69991 +
69992 +/**************************************************************************//**
69993 + @Description FPM defines
69994 +*//***************************************************************************/
69995 +/* masks */
69996 +#define FPM_BRKC_RDBG 0x00000200
69997 +#define FPM_BRKC_SLP 0x00000800
69998 +/**************************************************************************//**
69999 + @Description BMI defines
70000 +*//***************************************************************************/
70001 +/* masks */
70002 +#define BMI_INIT_START 0x80000000
70003 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
70004 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
70005 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
70006 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
70007 +/**************************************************************************//**
70008 + @Description QMI defines
70009 +*//***************************************************************************/
70010 +/* masks */
70011 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
70012 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
70013 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
70014 +
70015 +/**************************************************************************//**
70016 + @Description IRAM defines
70017 +*//***************************************************************************/
70018 +/* masks */
70019 +#define IRAM_IADD_AIE 0x80000000
70020 +#define IRAM_READY 0x80000000
70021 +
70022 +/**************************************************************************//**
70023 + @Description TRB defines
70024 +*//***************************************************************************/
70025 +/* masks */
70026 +#define TRB_TCRH_RESET 0x04000000
70027 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
70028 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
70029 +#define TRB_TCRL_RESET 0x20000000
70030 +#define TRB_TCRL_UTIL 0x00000460
70031 +typedef struct {
70032 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
70033 + t_Handle h_SrcHandle;
70034 +} t_FmanCtrlIntrSrc;
70035 +
70036 +
70037 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
70038 +
70039 +typedef struct
70040 +{
70041 +/***************************/
70042 +/* Master/Guest parameters */
70043 +/***************************/
70044 + uint8_t fmId;
70045 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
70046 + uint16_t fmClkFreq;
70047 + uint16_t fmMacClkFreq;
70048 + t_FmRevisionInfo revInfo;
70049 +/**************************/
70050 +/* Master Only parameters */
70051 +/**************************/
70052 + bool enabledTimeStamp;
70053 + uint8_t count1MicroBit;
70054 + uint8_t totalNumOfTasks;
70055 + uint32_t totalFifoSize;
70056 + uint8_t maxNumOfOpenDmas;
70057 + uint8_t accumulatedNumOfTasks;
70058 + uint32_t accumulatedFifoSize;
70059 + uint8_t accumulatedNumOfOpenDmas;
70060 + uint8_t accumulatedNumOfDeqTnums;
70061 +#ifdef FM_LOW_END_RESTRICTION
70062 + bool lowEndRestriction;
70063 +#endif /* FM_LOW_END_RESTRICTION */
70064 + uint32_t exceptions;
70065 + int irq;
70066 + int errIrq;
70067 + bool ramsEccEnable;
70068 + bool explicitEnable;
70069 + bool internalCall;
70070 + uint8_t ramsEccOwners;
70071 + uint32_t extraFifoPoolSize;
70072 + uint8_t extraTasksPoolSize;
70073 + uint8_t extraOpenDmasPoolSize;
70074 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
70075 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70076 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70077 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
70078 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70079 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70080 +} t_FmStateStruct;
70081 +
70082 +#if (DPAA_VERSION >= 11)
70083 +typedef struct t_FmMapParam {
70084 + uint16_t profilesBase;
70085 + uint16_t numOfProfiles;
70086 + t_Handle h_FmPort;
70087 +} t_FmMapParam;
70088 +
70089 +typedef struct t_FmAllocMng {
70090 + bool allocated;
70091 + uint8_t ownerId; /* guestId for KG in multi-partition only,
70092 + portId for PLCR in any environment */
70093 +} t_FmAllocMng;
70094 +
70095 +typedef struct t_FmPcdSpEntry {
70096 + bool valid;
70097 + t_FmAllocMng profilesMng;
70098 +} t_FmPcdSpEntry;
70099 +
70100 +typedef struct t_FmSp {
70101 + void *p_FmPcdStoragePrflRegs;
70102 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
70103 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
70104 +} t_FmSp;
70105 +#endif /* (DPAA_VERSION >= 11) */
70106 +
70107 +typedef struct t_Fm
70108 +{
70109 +/***************************/
70110 +/* Master/Guest parameters */
70111 +/***************************/
70112 +/* locals for recovery */
70113 + uintptr_t baseAddr;
70114 +
70115 +/* un-needed for recovery */
70116 + t_Handle h_Pcd;
70117 + char fmModuleName[MODULE_NAME_SIZE];
70118 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
70119 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
70120 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
70121 + uint8_t guestId;
70122 +/**************************/
70123 +/* Master Only parameters */
70124 +/**************************/
70125 +/* locals for recovery */
70126 + struct fman_fpm_regs *p_FmFpmRegs;
70127 + struct fman_bmi_regs *p_FmBmiRegs;
70128 + struct fman_qmi_regs *p_FmQmiRegs;
70129 + struct fman_dma_regs *p_FmDmaRegs;
70130 + struct fman_regs *p_FmRegs;
70131 + t_FmExceptionsCallback *f_Exception;
70132 + t_FmBusErrorCallback *f_BusError;
70133 + t_Handle h_App; /* Application handle */
70134 + t_Handle h_Spinlock;
70135 + bool recoveryMode;
70136 + t_FmStateStruct *p_FmStateStruct;
70137 + uint16_t tnumAgingPeriod;
70138 +#if (DPAA_VERSION >= 11)
70139 + t_FmSp *p_FmSp;
70140 + uint8_t partNumOfVSPs;
70141 + uint8_t partVSPBase;
70142 + uintptr_t vspBaseAddr;
70143 +#endif /* (DPAA_VERSION >= 11) */
70144 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70145 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70146 +
70147 +/* un-needed for recovery */
70148 + struct fman_cfg *p_FmDriverParam;
70149 + t_Handle h_FmMuram;
70150 + uint64_t fmMuramPhysBaseAddr;
70151 + bool independentMode;
70152 + bool hcPortInitialized;
70153 + uintptr_t camBaseAddr; /* save for freeing */
70154 + uintptr_t resAddr;
70155 + uintptr_t fifoBaseAddr; /* save for freeing */
70156 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
70157 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
70158 + t_FmFirmwareParams firmware;
70159 + bool fwVerify;
70160 + bool resetOnInit;
70161 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
70162 + uint32_t userSetExceptions;
70163 +} t_Fm;
70164 +
70165 +
70166 +#endif /* __FM_H */
70167 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70168 new file mode 100644
70169 index 00000000..7ce36a76
70170 --- /dev/null
70171 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70172 @@ -0,0 +1,465 @@
70173 +/*
70174 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70175 + *
70176 + * Redistribution and use in source and binary forms, with or without
70177 + * modification, are permitted provided that the following conditions are met:
70178 + * * Redistributions of source code must retain the above copyright
70179 + * notice, this list of conditions and the following disclaimer.
70180 + * * Redistributions in binary form must reproduce the above copyright
70181 + * notice, this list of conditions and the following disclaimer in the
70182 + * documentation and/or other materials provided with the distribution.
70183 + * * Neither the name of Freescale Semiconductor nor the
70184 + * names of its contributors may be used to endorse or promote products
70185 + * derived from this software without specific prior written permission.
70186 + *
70187 + *
70188 + * ALTERNATIVELY, this software may be distributed under the terms of the
70189 + * GNU General Public License ("GPL") as published by the Free Software
70190 + * Foundation, either version 2 of that License or (at your option) any
70191 + * later version.
70192 + *
70193 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70194 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70195 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70196 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70197 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70198 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70199 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70200 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70201 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70202 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70203 + */
70204 +
70205 +
70206 +/**************************************************************************//**
70207 + @File fm_ipc.h
70208 +
70209 + @Description FM Inter-Partition prototypes, structures and definitions.
70210 +*//***************************************************************************/
70211 +#ifndef __FM_IPC_H
70212 +#define __FM_IPC_H
70213 +
70214 +#include "error_ext.h"
70215 +#include "std_ext.h"
70216 +
70217 +
70218 +/**************************************************************************//**
70219 + @Group FM_grp Frame Manager API
70220 +
70221 + @Description FM API functions, definitions and enums
70222 +
70223 + @{
70224 +*//***************************************************************************/
70225 +
70226 +/**************************************************************************//**
70227 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
70228 +
70229 + @Description FM Inter-Partition messaging unit API definitions and enums.
70230 +
70231 + @{
70232 +*//***************************************************************************/
70233 +
70234 +#if defined(__MWERKS__) && !defined(__GNUC__)
70235 +#pragma pack(push,1)
70236 +#endif /* defined(__MWERKS__) && ... */
70237 +
70238 +/**************************************************************************//**
70239 + @Description enum for defining MAC types
70240 +*//***************************************************************************/
70241 +
70242 +/**************************************************************************//**
70243 + @Description A structure of parameters for specifying a MAC.
70244 +*//***************************************************************************/
70245 +typedef _Packed struct
70246 +{
70247 + uint8_t id;
70248 + uint32_t enumType;
70249 +} _PackedType t_FmIpcMacParams;
70250 +
70251 +/**************************************************************************//**
70252 + @Description A structure of parameters for specifying a MAC.
70253 +*//***************************************************************************/
70254 +typedef _Packed struct
70255 +{
70256 + t_FmIpcMacParams macParams;
70257 + uint16_t maxFrameLength;
70258 +} _PackedType t_FmIpcMacMaxFrameParams;
70259 +
70260 +/**************************************************************************//**
70261 + @Description FM physical Address
70262 +*//***************************************************************************/
70263 +typedef _Packed struct t_FmIpcPhysAddr
70264 +{
70265 + volatile uint8_t high;
70266 + volatile uint32_t low;
70267 +} _PackedType t_FmIpcPhysAddr;
70268 +
70269 +
70270 +typedef _Packed struct t_FmIpcPortOutInitParams {
70271 + uint8_t numOfTasks; /**< OUT */
70272 + uint8_t numOfExtraTasks; /**< OUT */
70273 + uint8_t numOfOpenDmas; /**< OUT */
70274 + uint8_t numOfExtraOpenDmas; /**< OUT */
70275 + uint32_t sizeOfFifo; /**< OUT */
70276 + uint32_t extraSizeOfFifo; /**< OUT */
70277 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
70278 +} _PackedType t_FmIpcPortOutInitParams;
70279 +
70280 +/**************************************************************************//**
70281 + @Description Structure for IPC communication during FM_PORT_Init.
70282 +*//***************************************************************************/
70283 +typedef _Packed struct t_FmIpcPortInInitParams {
70284 + uint8_t hardwarePortId; /**< IN. port Id */
70285 + uint32_t enumPortType; /**< IN. Port type */
70286 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
70287 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70288 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70289 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70290 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70291 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70292 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70293 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70294 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70295 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70296 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70297 + LIODN base for this port, to be
70298 + used together with LIODN offset. */
70299 +} _PackedType t_FmIpcPortInInitParams;
70300 +
70301 +
70302 +/**************************************************************************//**
70303 + @Description Structure for IPC communication between port and FM
70304 + regarding tasks and open DMA resources management.
70305 +*//***************************************************************************/
70306 +typedef _Packed struct t_FmIpcPortRsrcParams {
70307 + uint8_t hardwarePortId; /**< IN. port Id */
70308 + uint32_t val; /**< IN. Port's requested resource */
70309 + uint32_t extra; /**< IN. Port's requested resource */
70310 + uint8_t boolInitialConfig;
70311 +} _PackedType t_FmIpcPortRsrcParams;
70312 +
70313 +
70314 +/**************************************************************************//**
70315 + @Description Structure for IPC communication between port and FM
70316 + regarding tasks and open DMA resources management.
70317 +*//***************************************************************************/
70318 +typedef _Packed struct t_FmIpcPortFifoParams {
70319 + t_FmIpcPortRsrcParams rsrcParams;
70320 + uint32_t enumPortType;
70321 + uint8_t boolIndependentMode;
70322 + uint8_t deqPipelineDepth;
70323 + uint8_t numOfPools;
70324 + uint16_t secondLargestBufSize;
70325 + uint16_t largestBufSize;
70326 + uint8_t boolInitialConfig;
70327 +} _PackedType t_FmIpcPortFifoParams;
70328 +
70329 +/**************************************************************************//**
70330 + @Description Structure for port-FM communication during FM_PORT_Free.
70331 +*//***************************************************************************/
70332 +typedef _Packed struct t_FmIpcPortFreeParams {
70333 + uint8_t hardwarePortId; /**< IN. port Id */
70334 + uint32_t enumPortType; /**< IN. Port type */
70335 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70336 +} _PackedType t_FmIpcPortFreeParams;
70337 +
70338 +/**************************************************************************//**
70339 + @Description Structure for defining DMA status
70340 +*//***************************************************************************/
70341 +typedef _Packed struct t_FmIpcDmaStatus {
70342 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70343 + uint8_t boolBusError; /**< Bus error occurred */
70344 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70345 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70346 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70347 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70348 +} _PackedType t_FmIpcDmaStatus;
70349 +
70350 +typedef _Packed struct t_FmIpcRegisterIntr
70351 +{
70352 + uint8_t guestId; /* IN */
70353 + uint32_t event; /* IN */
70354 +} _PackedType t_FmIpcRegisterIntr;
70355 +
70356 +typedef _Packed struct t_FmIpcIsr
70357 +{
70358 + uint8_t boolErr; /* IN */
70359 + uint32_t pendingReg; /* IN */
70360 +} _PackedType t_FmIpcIsr;
70361 +
70362 +/**************************************************************************//**
70363 + @Description structure for returning FM parameters
70364 +*//***************************************************************************/
70365 +typedef _Packed struct t_FmIpcParams {
70366 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70367 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70368 + uint8_t majorRev; /**< OUT: FM Major revision */
70369 + uint8_t minorRev; /**< OUT: FM Minor revision */
70370 +} _PackedType t_FmIpcParams;
70371 +
70372 +
70373 +/**************************************************************************//**
70374 + @Description structure for returning Fman Ctrl Code revision information
70375 +*//***************************************************************************/
70376 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70377 + uint16_t packageRev; /**< OUT: Package revision */
70378 + uint8_t majorRev; /**< OUT: Major revision */
70379 + uint8_t minorRev; /**< OUT: Minor revision */
70380 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70381 +
70382 +/**************************************************************************//**
70383 + @Description Structure for defining Fm number of Fman controlers
70384 +*//***************************************************************************/
70385 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70386 + uint8_t hardwarePortId; /**< IN. port Id */
70387 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70388 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70389 +} t_FmIpcPortNumOfFmanCtrls;
70390 +
70391 +/**************************************************************************//**
70392 + @Description structure for setting Fman contriller events
70393 +*//***************************************************************************/
70394 +typedef _Packed struct t_FmIpcFmanEvents {
70395 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70396 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70397 +} _PackedType t_FmIpcFmanEvents;
70398 +
70399 +typedef _Packed struct t_FmIpcResourceAllocParams {
70400 + uint8_t guestId;
70401 + uint16_t base;
70402 + uint16_t num;
70403 +}_PackedType t_FmIpcResourceAllocParams;
70404 +
70405 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70406 + uint8_t hardwarePortId;
70407 + uint8_t baseStorageProfile;
70408 + uint8_t log2NumOfProfiles;
70409 +}_PackedType t_FmIpcVspSetPortWindow;
70410 +
70411 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70412 + uint32_t congestionGroupId;
70413 + uint8_t priorityBitMap;
70414 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70415 +
70416 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70417 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70418 +#define FM_IPC_MAX_MSG_SIZE 30
70419 +
70420 +typedef _Packed struct t_FmIpcMsg
70421 +{
70422 + uint32_t msgId;
70423 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70424 +} _PackedType t_FmIpcMsg;
70425 +
70426 +typedef _Packed struct t_FmIpcReply
70427 +{
70428 + uint32_t error;
70429 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70430 +} _PackedType t_FmIpcReply;
70431 +
70432 +#if defined(__MWERKS__) && !defined(__GNUC__)
70433 +#pragma pack(pop)
70434 +#endif /* defined(__MWERKS__) && ... */
70435 +
70436 +
70437 +/***************************************************************************/
70438 +/************************ FRONT-END-TO-BACK-END*****************************/
70439 +/***************************************************************************/
70440 +
70441 +/**************************************************************************//**
70442 + @Function FM_GET_TIMESTAMP_SCALE
70443 +
70444 + @Description Used by FM front-end.
70445 +
70446 + @Param[out] uint32_t Pointer
70447 +*//***************************************************************************/
70448 +#define FM_GET_TIMESTAMP_SCALE 1
70449 +
70450 +/**************************************************************************//**
70451 + @Function FM_GET_COUNTER
70452 +
70453 + @Description Used by FM front-end.
70454 +
70455 + @Param[in/out] t_FmIpcGetCounter Pointer
70456 +*//***************************************************************************/
70457 +#define FM_GET_COUNTER 2
70458 +
70459 +/**************************************************************************//**
70460 + @Function FM_GET_SET_PORT_PARAMS
70461 +
70462 + @Description Used by FM front-end for the PORT module in order to set and get
70463 + parameters in/from master FM module on FM PORT initialization time.
70464 +
70465 + @Param[in/out] t_FmIcPortInitParams Pointer
70466 +*//***************************************************************************/
70467 +#define FM_GET_SET_PORT_PARAMS 4
70468 +
70469 +/**************************************************************************//**
70470 + @Function FM_FREE_PORT
70471 +
70472 + @Description Used by FM front-end for the PORT module when a port is freed
70473 + to free all FM PORT resources.
70474 +
70475 + @Param[in] uint8_t Pointer
70476 +*//***************************************************************************/
70477 +#define FM_FREE_PORT 5
70478 +
70479 +/**************************************************************************//**
70480 + @Function FM_RESET_MAC
70481 +
70482 + @Description Used by front-end for the MAC module to reset the MAC registers
70483 +
70484 + @Param[in] t_FmIpcMacParams Pointer .
70485 +*//***************************************************************************/
70486 +#define FM_RESET_MAC 6
70487 +
70488 +/**************************************************************************//**
70489 + @Function FM_RESUME_STALLED_PORT
70490 +
70491 + @Description Used by FM front-end for the PORT module in order to
70492 + release a stalled FM Port.
70493 +
70494 + @Param[in] uint8_t Pointer
70495 +*//***************************************************************************/
70496 +#define FM_RESUME_STALLED_PORT 7
70497 +
70498 +/**************************************************************************//**
70499 + @Function FM_IS_PORT_STALLED
70500 +
70501 + @Description Used by FM front-end for the PORT module in order to check whether
70502 + an FM port is stalled.
70503 +
70504 + @Param[in/out] t_FmIcPortIsStalled Pointer
70505 +*//***************************************************************************/
70506 +#define FM_IS_PORT_STALLED 8
70507 +
70508 +/**************************************************************************//**
70509 + @Function FM_GET_PARAMS
70510 +
70511 + @Description Used by FM front-end for the PORT module in order to dump
70512 + return FM parameters.
70513 +
70514 + @Param[in] uint8_t Pointer
70515 +*//***************************************************************************/
70516 +#define FM_GET_PARAMS 10
70517 +
70518 +/**************************************************************************//**
70519 + @Function FM_REGISTER_INTR
70520 +
70521 + @Description Used by FM front-end to register an interrupt handler to
70522 + be called upon interrupt for guest.
70523 +
70524 + @Param[out] t_FmIpcRegisterIntr Pointer
70525 +*//***************************************************************************/
70526 +#define FM_REGISTER_INTR 11
70527 +
70528 +/**************************************************************************//**
70529 + @Function FM_DMA_STAT
70530 +
70531 + @Description Used by FM front-end to read the FM DMA status.
70532 +
70533 + @Param[out] t_FmIpcDmaStatus Pointer
70534 +*//***************************************************************************/
70535 +#define FM_DMA_STAT 13
70536 +
70537 +/**************************************************************************//**
70538 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70539 +
70540 + @Description Used by FM front-end to allocate event register.
70541 +
70542 + @Param[out] Event register id Pointer
70543 +*//***************************************************************************/
70544 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70545 +
70546 +/**************************************************************************//**
70547 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70548 +
70549 + @Description Used by FM front-end to free locate event register.
70550 +
70551 + @Param[in] uint8_t Pointer - Event register id
70552 +*//***************************************************************************/
70553 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70554 +
70555 +/**************************************************************************//**
70556 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70557 +
70558 + @Description Used by FM front-end to enable events in the FPM
70559 + Fman controller event register.
70560 +
70561 + @Param[in] t_FmIpcFmanEvents Pointer
70562 +*//***************************************************************************/
70563 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70564 +
70565 +/**************************************************************************//**
70566 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70567 +
70568 + @Description Used by FM front-end to enable events in the FPM
70569 + Fman controller event register.
70570 +
70571 + @Param[in/out] t_FmIpcFmanEvents Pointer
70572 +*//***************************************************************************/
70573 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70574 +
70575 +/**************************************************************************//**
70576 + @Function FM_SET_MAC_MAX_FRAME
70577 +
70578 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70579 + back-end.
70580 +
70581 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70582 +*//***************************************************************************/
70583 +#define FM_SET_MAC_MAX_FRAME 18
70584 +
70585 +/**************************************************************************//**
70586 + @Function FM_GET_PHYS_MURAM_BASE
70587 +
70588 + @Description Used by FM front-end in order to get MURAM base address
70589 +
70590 + @Param[in/out] t_FmIpcPhysAddr Pointer
70591 +*//***************************************************************************/
70592 +#define FM_GET_PHYS_MURAM_BASE 19
70593 +
70594 +/**************************************************************************//**
70595 + @Function FM_MASTER_IS_ALIVE
70596 +
70597 + @Description Used by FM front-end in order to verify Master is up
70598 +
70599 + @Param[in/out] bool
70600 +*//***************************************************************************/
70601 +#define FM_MASTER_IS_ALIVE 20
70602 +
70603 +#define FM_ENABLE_RAM_ECC 21
70604 +#define FM_DISABLE_RAM_ECC 22
70605 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70606 +#define FM_SET_SIZE_OF_FIFO 24
70607 +#define FM_SET_NUM_OF_TASKS 25
70608 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70609 +#define FM_VSP_ALLOC 27
70610 +#define FM_VSP_FREE 28
70611 +#define FM_VSP_SET_PORT_WINDOW 29
70612 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70613 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70614 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70615 +#define FM_10G_TX_ECC_WA 100
70616 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70617 +
70618 +/***************************************************************************/
70619 +/************************ BACK-END-TO-FRONT-END*****************************/
70620 +/***************************************************************************/
70621 +
70622 +/**************************************************************************//**
70623 + @Function FM_GUEST_ISR
70624 +
70625 + @Description Used by FM back-end to report an interrupt to the front-end.
70626 +
70627 + @Param[out] t_FmIpcIsr Pointer
70628 +*//***************************************************************************/
70629 +#define FM_GUEST_ISR 1
70630 +
70631 +
70632 +
70633 +/** @} */ /* end of FM_IPC_grp group */
70634 +/** @} */ /* end of FM_grp group */
70635 +
70636 +
70637 +#endif /* __FM_IPC_H */
70638 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70639 new file mode 100644
70640 index 00000000..0bc67cb7
70641 --- /dev/null
70642 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70643 @@ -0,0 +1,174 @@
70644 +/*
70645 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70646 + *
70647 + * Redistribution and use in source and binary forms, with or without
70648 + * modification, are permitted provided that the following conditions are met:
70649 + * * Redistributions of source code must retain the above copyright
70650 + * notice, this list of conditions and the following disclaimer.
70651 + * * Redistributions in binary form must reproduce the above copyright
70652 + * notice, this list of conditions and the following disclaimer in the
70653 + * documentation and/or other materials provided with the distribution.
70654 + * * Neither the name of Freescale Semiconductor nor the
70655 + * names of its contributors may be used to endorse or promote products
70656 + * derived from this software without specific prior written permission.
70657 + *
70658 + *
70659 + * ALTERNATIVELY, this software may be distributed under the terms of the
70660 + * GNU General Public License ("GPL") as published by the Free Software
70661 + * Foundation, either version 2 of that License or (at your option) any
70662 + * later version.
70663 + *
70664 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70665 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70666 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70667 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70668 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70669 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70670 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70671 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70672 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70673 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70674 + */
70675 +
70676 +
70677 +/******************************************************************************
70678 + @File FM_muram.c
70679 +
70680 + @Description FM MURAM ...
70681 +*//***************************************************************************/
70682 +#include "error_ext.h"
70683 +#include "std_ext.h"
70684 +#include "mm_ext.h"
70685 +#include "string_ext.h"
70686 +#include "sprint_ext.h"
70687 +#include "fm_muram_ext.h"
70688 +#include "fm_common.h"
70689 +
70690 +#define __ERR_MODULE__ MODULE_FM_MURAM
70691 +
70692 +
70693 +typedef struct
70694 +{
70695 + t_Handle h_Mem;
70696 + uintptr_t baseAddr;
70697 + uint32_t size;
70698 +} t_FmMuram;
70699 +
70700 +
70701 +void FmMuramClear(t_Handle h_FmMuram)
70702 +{
70703 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70704 +
70705 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70706 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70707 +}
70708 +
70709 +
70710 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70711 +{
70712 + t_Handle h_Mem;
70713 + t_FmMuram *p_FmMuram;
70714 +
70715 + if (!baseAddress)
70716 + {
70717 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70718 + return NULL;
70719 + }
70720 +
70721 + if (baseAddress%4)
70722 + {
70723 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70724 + return NULL;
70725 + }
70726 +
70727 + /* Allocate FM MURAM structure */
70728 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70729 + if (!p_FmMuram)
70730 + {
70731 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70732 + return NULL;
70733 + }
70734 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70735 +
70736 +
70737 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70738 + {
70739 + XX_Free(p_FmMuram);
70740 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70741 + return NULL;
70742 + }
70743 +
70744 + /* Initialize FM MURAM parameters which will be kept by the driver */
70745 + p_FmMuram->baseAddr = baseAddress;
70746 + p_FmMuram->size = size;
70747 + p_FmMuram->h_Mem = h_Mem;
70748 +
70749 + return p_FmMuram;
70750 +}
70751 +
70752 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70753 +{
70754 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70755 +
70756 + if (p_FmMuram->h_Mem)
70757 + MM_Free(p_FmMuram->h_Mem);
70758 +
70759 + XX_Free(h_FmMuram);
70760 +
70761 + return E_OK;
70762 +}
70763 +
70764 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70765 +{
70766 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70767 + uintptr_t addr;
70768 +
70769 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70770 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70771 +
70772 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70773 +
70774 + if (addr == ILLEGAL_BASE)
70775 + return NULL;
70776 +
70777 + return UINT_TO_PTR(addr);
70778 +}
70779 +
70780 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70781 +{
70782 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70783 + uintptr_t addr;
70784 +
70785 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70786 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70787 +
70788 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70789 +
70790 + if (addr == ILLEGAL_BASE)
70791 + return NULL;
70792 +
70793 + return UINT_TO_PTR(addr);
70794 +}
70795 +
70796 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70797 +{
70798 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70799 +
70800 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70801 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70802 +
70803 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70804 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70805 +
70806 + return E_OK;
70807 +}
70808 +
70809 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70810 +{
70811 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70812 +
70813 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70814 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70815 +
70816 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70817 +}
70818 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70819 new file mode 100755
70820 index 00000000..a41ecd04
70821 --- /dev/null
70822 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70823 @@ -0,0 +1,1398 @@
70824 +/*
70825 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70826 + *
70827 + * Redistribution and use in source and binary forms, with or without
70828 + * modification, are permitted provided that the following conditions are met:
70829 + * * Redistributions of source code must retain the above copyright
70830 + * notice, this list of conditions and the following disclaimer.
70831 + * * Redistributions in binary form must reproduce the above copyright
70832 + * notice, this list of conditions and the following disclaimer in the
70833 + * documentation and/or other materials provided with the distribution.
70834 + * * Neither the name of Freescale Semiconductor nor the
70835 + * names of its contributors may be used to endorse or promote products
70836 + * derived from this software without specific prior written permission.
70837 + *
70838 + *
70839 + * ALTERNATIVELY, this software may be distributed under the terms of the
70840 + * GNU General Public License ("GPL") as published by the Free Software
70841 + * Foundation, either version 2 of that License or (at your option) any
70842 + * later version.
70843 + *
70844 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70845 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70846 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70847 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70848 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70849 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70850 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70851 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70852 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70853 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70854 + */
70855 +
70856 +
70857 +#include <linux/math64.h>
70858 +#include "fsl_fman.h"
70859 +#include "dpaa_integration_ext.h"
70860 +
70861 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70862 +{
70863 + uint32_t event, mask, force;
70864 +
70865 + event = ioread32be(&bmi_rg->fmbm_ievr);
70866 + mask = ioread32be(&bmi_rg->fmbm_ier);
70867 + event &= mask;
70868 + /* clear the forced events */
70869 + force = ioread32be(&bmi_rg->fmbm_ifr);
70870 + if (force & event)
70871 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70872 + /* clear the acknowledged events */
70873 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70874 + return event;
70875 +}
70876 +
70877 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
70878 +{
70879 + uint32_t event, mask, force;
70880 +
70881 + event = ioread32be(&qmi_rg->fmqm_eie);
70882 + mask = ioread32be(&qmi_rg->fmqm_eien);
70883 + event &= mask;
70884 +
70885 + /* clear the forced events */
70886 + force = ioread32be(&qmi_rg->fmqm_eif);
70887 + if (force & event)
70888 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
70889 + /* clear the acknowledged events */
70890 + iowrite32be(event, &qmi_rg->fmqm_eie);
70891 + return event;
70892 +}
70893 +
70894 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
70895 +{
70896 + return ioread32be(&dma_rg->fmdmtcid);
70897 +}
70898 +
70899 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
70900 +{
70901 + uint64_t addr;
70902 +
70903 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
70904 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
70905 +
70906 + return addr;
70907 +}
70908 +
70909 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
70910 +{
70911 + uint32_t status, mask;
70912 +
70913 + status = ioread32be(&dma_rg->fmdmsr);
70914 + mask = ioread32be(&dma_rg->fmdmmr);
70915 +
70916 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
70917 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
70918 + status &= ~DMA_STATUS_BUS_ERR;
70919 +
70920 + /* clear relevant bits if mask has no DMA_MODE_ECC */
70921 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
70922 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
70923 + DMA_STATUS_READ_ECC |
70924 + DMA_STATUS_SYSTEM_WRITE_ECC |
70925 + DMA_STATUS_FM_WRITE_ECC);
70926 +
70927 + /* clear set events */
70928 + iowrite32be(status, &dma_rg->fmdmsr);
70929 +
70930 + return status;
70931 +}
70932 +
70933 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
70934 +{
70935 + uint32_t event;
70936 +
70937 + event = ioread32be(&fpm_rg->fmfp_ee);
70938 + /* clear the all occurred events */
70939 + iowrite32be(event, &fpm_rg->fmfp_ee);
70940 + return event;
70941 +}
70942 +
70943 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
70944 +{
70945 + uint32_t event, mask;
70946 +
70947 + event = ioread32be(&fpm_rg->fm_rcr);
70948 + mask = ioread32be(&fpm_rg->fm_rie);
70949 +
70950 + /* clear MURAM event bit (do not clear IRAM event) */
70951 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
70952 +
70953 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
70954 + return event;
70955 + else
70956 + return 0;
70957 +}
70958 +
70959 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
70960 +{
70961 + uint32_t event, mask;
70962 +
70963 + event = ioread32be(&fpm_rg->fm_rcr) ;
70964 + mask = ioread32be(&fpm_rg->fm_rie);
70965 + /* clear IRAM event bit (do not clear MURAM event) */
70966 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
70967 + &fpm_rg->fm_rcr);
70968 +
70969 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
70970 + return event;
70971 + else
70972 + return 0;
70973 +}
70974 +
70975 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
70976 +{
70977 + uint32_t event, mask, force;
70978 +
70979 + event = ioread32be(&qmi_rg->fmqm_ie);
70980 + mask = ioread32be(&qmi_rg->fmqm_ien);
70981 + event &= mask;
70982 + /* clear the forced events */
70983 + force = ioread32be(&qmi_rg->fmqm_if);
70984 + if (force & event)
70985 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
70986 + /* clear the acknowledged events */
70987 + iowrite32be(event, &qmi_rg->fmqm_ie);
70988 + return event;
70989 +}
70990 +
70991 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
70992 + uint8_t count1ubit,
70993 + uint16_t fm_clk_freq)
70994 +{
70995 + uint32_t tmp;
70996 + uint64_t frac;
70997 + uint32_t intgr;
70998 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
70999 +
71000 + /* configure timestamp so that bit 8 will count 1 microsecond
71001 + * Find effective count rate at TIMESTAMP least significant bits:
71002 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
71003 + * Find frequency ratio between effective count rate and the clock:
71004 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
71005 + * 256/600 = 0.4266666... */
71006 +
71007 + intgr = ts_freq / fm_clk_freq;
71008 + /* we multiply by 2^16 to keep the fraction of the division
71009 + * we do not div back, since we write this value as a fraction
71010 + * see spec */
71011 +
71012 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
71013 + /* we check remainder of the division in order to round up if not int */
71014 + if (do_div(frac, fm_clk_freq))
71015 + frac++;
71016 +
71017 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
71018 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
71019 +
71020 + /* enable timestamp with original clock */
71021 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
71022 +}
71023 +
71024 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
71025 +{
71026 + return ioread32be(&fpm_rg->fm_epi);
71027 +}
71028 +
71029 +
71030 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
71031 +{
71032 + int timeout = 100;
71033 +
71034 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
71035 +
71036 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
71037 + udelay(10);
71038 +
71039 + if (!timeout)
71040 + return -EBUSY;
71041 + return 0;
71042 +}
71043 +
71044 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
71045 + uint8_t event_reg_id,
71046 + uint32_t enable_events)
71047 +{
71048 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
71049 +}
71050 +
71051 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
71052 +{
71053 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
71054 +}
71055 +
71056 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
71057 + uint8_t port_id,
71058 + uint8_t num_fman_ctrls,
71059 + uint32_t or_fman_ctrl)
71060 +{
71061 + uint32_t tmp = 0;
71062 +
71063 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71064 + /*TODO - maybe to put CTL# according to another criteria*/
71065 + if (num_fman_ctrls == 2)
71066 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
71067 + /* order restoration */
71068 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
71069 +
71070 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71071 +}
71072 +
71073 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
71074 + uint8_t port_id,
71075 + bool independent_mode,
71076 + bool is_rx_port)
71077 +{
71078 + uint32_t tmp = 0;
71079 +
71080 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71081 + if (independent_mode) {
71082 + if (is_rx_port)
71083 + tmp |= (FPM_PRT_FM_CTL1 <<
71084 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
71085 + else
71086 + tmp |= (FPM_PRT_FM_CTL2 <<
71087 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
71088 + } else {
71089 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
71090 +
71091 + /* order restoration */
71092 + if (port_id % 2)
71093 + tmp |= (FPM_PRT_FM_CTL1 <<
71094 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71095 + else
71096 + tmp |= (FPM_PRT_FM_CTL2 <<
71097 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71098 + }
71099 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71100 +}
71101 +
71102 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
71103 +{
71104 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
71105 +}
71106 +
71107 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
71108 +{
71109 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
71110 +}
71111 +
71112 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71113 +{
71114 + uint32_t tmp_reg;
71115 +
71116 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71117 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
71118 + tmp_reg |= ((uint32_t)val << 8);
71119 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71120 +}
71121 +
71122 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71123 +{
71124 + uint32_t tmp_reg;
71125 +
71126 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71127 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
71128 + tmp_reg |= (uint32_t)val;
71129 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71130 +}
71131 +
71132 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
71133 +{
71134 + iowrite32be(0, &fpm_rg->fmfp_mxd);
71135 +}
71136 +
71137 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
71138 + uint16_t liodn_base,
71139 + uint16_t liodn_ofst)
71140 +{
71141 + uint32_t tmp;
71142 +
71143 + if ((port_id > 63) || (port_id < 1))
71144 + return;
71145 +
71146 + /* set LIODN base for this port */
71147 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
71148 + if (port_id % 2) {
71149 + tmp &= ~FM_LIODN_BASE_MASK;
71150 + tmp |= (uint32_t)liodn_base;
71151 + } else {
71152 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
71153 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
71154 + }
71155 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
71156 + iowrite32be((uint32_t)liodn_ofst,
71157 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
71158 +}
71159 +
71160 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71161 +{
71162 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
71163 +}
71164 +
71165 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71166 +{
71167 + uint32_t tmp;
71168 +
71169 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
71170 + FPM_PRC_REALSE_STALLED);
71171 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71172 +}
71173 +
71174 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
71175 +{
71176 + uint32_t msk, timeout = 100;
71177 +
71178 + /* Get the relevant bit mask */
71179 + if (is_10g) {
71180 + switch (mac_id) {
71181 + case(0):
71182 + msk = FPM_RSTC_10G0_RESET;
71183 + break;
71184 + case(1):
71185 + msk = FPM_RSTC_10G1_RESET;
71186 + break;
71187 + default:
71188 + return -EINVAL;
71189 + }
71190 + } else {
71191 + switch (mac_id) {
71192 + case(0):
71193 + msk = FPM_RSTC_1G0_RESET;
71194 + break;
71195 + case(1):
71196 + msk = FPM_RSTC_1G1_RESET;
71197 + break;
71198 + case(2):
71199 + msk = FPM_RSTC_1G2_RESET;
71200 + break;
71201 + case(3):
71202 + msk = FPM_RSTC_1G3_RESET;
71203 + break;
71204 + case(4):
71205 + msk = FPM_RSTC_1G4_RESET;
71206 + break;
71207 + case (5):
71208 + msk = FPM_RSTC_1G5_RESET;
71209 + break;
71210 + case (6):
71211 + msk = FPM_RSTC_1G6_RESET;
71212 + break;
71213 + case (7):
71214 + msk = FPM_RSTC_1G7_RESET;
71215 + break;
71216 + default:
71217 + return -EINVAL;
71218 + }
71219 + }
71220 + /* reset */
71221 + iowrite32be(msk, &fpm_rg->fm_rstc);
71222 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
71223 + udelay(10);
71224 +
71225 + if (!timeout)
71226 + return -EBUSY;
71227 + return 0;
71228 +}
71229 +
71230 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71231 +{
71232 + uint32_t tmp_reg;
71233 +
71234 + if ((port_id > 63) || (port_id < 1))
71235 + return 0;
71236 +
71237 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
71238 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
71239 +}
71240 +
71241 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
71242 +{
71243 + uint32_t reg, res;
71244 +
71245 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
71246 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
71247 + return res * FMAN_BMI_FIFO_UNITS;
71248 +}
71249 +
71250 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
71251 + uint8_t port_id)
71252 +{
71253 + uint32_t tmp_reg;
71254 +
71255 + if ((port_id > 63) || (port_id < 1))
71256 + return 0;
71257 +
71258 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
71259 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
71260 + BMI_EXTRA_FIFO_SIZE_SHIFT);
71261 +}
71262 +
71263 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
71264 + uint8_t port_id,
71265 + uint32_t sz_fifo,
71266 + uint32_t extra_sz_fifo)
71267 +{
71268 + uint32_t tmp;
71269 +
71270 + if ((port_id > 63) || (port_id < 1))
71271 + return;
71272 +
71273 + /* calculate reg */
71274 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
71275 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
71276 + BMI_EXTRA_FIFO_SIZE_SHIFT));
71277 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
71278 +}
71279 +
71280 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71281 +{
71282 + uint32_t tmp;
71283 +
71284 + if ((port_id > 63) || (port_id < 1))
71285 + return 0;
71286 +
71287 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71288 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
71289 + BMI_NUM_OF_TASKS_SHIFT) + 1);
71290 +}
71291 +
71292 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71293 +{
71294 + uint32_t tmp;
71295 +
71296 + if ((port_id > 63) || (port_id < 1))
71297 + return 0;
71298 +
71299 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71300 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71301 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71302 +}
71303 +
71304 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71305 + uint8_t port_id,
71306 + uint8_t num_tasks,
71307 + uint8_t num_extra_tasks)
71308 +{
71309 + uint32_t tmp;
71310 +
71311 + if ((port_id > 63) || (port_id < 1))
71312 + return;
71313 +
71314 + /* calculate reg */
71315 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71316 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71317 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71318 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71319 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71320 +}
71321 +
71322 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71323 +{
71324 + uint32_t tmp;
71325 +
71326 + if ((port_id > 63) || (port_id < 1))
71327 + return 0;
71328 +
71329 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71330 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71331 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71332 +}
71333 +
71334 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71335 +{
71336 + uint32_t tmp;
71337 +
71338 + if ((port_id > 63) || (port_id < 1))
71339 + return 0;
71340 +
71341 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71342 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71343 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71344 +}
71345 +
71346 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71347 + uint8_t port_id,
71348 + uint8_t num_open_dmas,
71349 + uint8_t num_extra_open_dmas,
71350 + uint8_t total_num_dmas)
71351 +{
71352 + uint32_t tmp = 0;
71353 +
71354 + if ((port_id > 63) || (port_id < 1))
71355 + return;
71356 +
71357 + /* calculate reg */
71358 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71359 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71360 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71361 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71362 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71363 +
71364 + /* update total num of DMA's with committed number of open DMAS,
71365 + * and max uncommitted pool. */
71366 + if (total_num_dmas)
71367 + {
71368 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71369 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71370 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71371 + }
71372 +}
71373 +
71374 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71375 + uint8_t port_id,
71376 + uint8_t base_storage_profile,
71377 + uint8_t log2_num_of_profiles)
71378 +{
71379 + uint32_t tmp = 0;
71380 + if ((port_id > 63) || (port_id < 1))
71381 + return;
71382 +
71383 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71384 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71385 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71386 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71387 +}
71388 +
71389 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71390 + uint32_t congestion_group_id,
71391 + uint8_t priority_bit_map,
71392 + uint32_t reg_num)
71393 +{
71394 + uint32_t offset, tmp = 0;
71395 +
71396 + offset = (congestion_group_id%4)*8;
71397 +
71398 + tmp = ioread32be(&cpg_rg[reg_num]);
71399 + tmp &= ~(0xFF<<offset);
71400 + tmp |= (uint32_t)priority_bit_map << offset;
71401 +
71402 + iowrite32be(tmp,&cpg_rg[reg_num]);
71403 +}
71404 +
71405 +/*****************************************************************************/
71406 +/* API Init unit functions */
71407 +/*****************************************************************************/
71408 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71409 +{
71410 + memset(cfg, 0, sizeof(struct fman_cfg));
71411 +
71412 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71413 + cfg->dma_err = DEFAULT_DMA_ERR;
71414 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71415 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71416 + cfg->en_iram_test_mode = FALSE;
71417 + cfg->en_muram_test_mode = FALSE;
71418 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71419 +
71420 + if (!is_master)
71421 + return;
71422 +
71423 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71424 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71425 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71426 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71427 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71428 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71429 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71430 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71431 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71432 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71433 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71434 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71435 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71436 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71437 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71438 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71439 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71440 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71441 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71442 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71443 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71444 +
71445 + cfg->pedantic_dma = FALSE;
71446 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71447 + cfg->dma_stop_on_bus_error = FALSE;
71448 + cfg->qmi_deq_option_support = FALSE;
71449 +}
71450 +
71451 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71452 +{
71453 + uint32_t tmp_reg;
71454 +
71455 + /* read the values from the registers as they are initialized by the HW with
71456 + * the required values.
71457 + */
71458 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71459 + cfg->total_fifo_size =
71460 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71461 +
71462 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71463 + cfg->total_num_of_tasks =
71464 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71465 +
71466 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71467 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71468 +
71469 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71470 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71471 +
71472 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71473 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71474 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71475 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71476 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71477 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71478 +
71479 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71480 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71481 +
71482 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71483 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71484 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71485 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71486 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71487 +
71488 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71489 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71490 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71491 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71492 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71493 +
71494 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71495 + cfg->dma_sos_emergency = tmp_reg;
71496 +
71497 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71498 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71499 +
71500 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71501 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71502 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71503 +}
71504 +
71505 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71506 +{
71507 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71508 +}
71509 +
71510 +/**************************************************************************//**
71511 + @Function FM_Init
71512 +
71513 + @Description Initializes the FM module
71514 +
71515 + @Param[in] h_Fm - FM module descriptor
71516 +
71517 + @Return E_OK on success; Error code otherwise.
71518 +*//***************************************************************************/
71519 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71520 +{
71521 + uint32_t tmp_reg;
71522 +
71523 + /**********************/
71524 + /* Init DMA Registers */
71525 + /**********************/
71526 + /* clear status reg events */
71527 + /* oren - check!!! */
71528 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71529 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71530 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71531 + &dma_rg->fmdmsr);
71532 +
71533 + /* configure mode register */
71534 + tmp_reg = 0;
71535 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71536 + if (cfg->dma_aid_override)
71537 + tmp_reg |= DMA_MODE_AID_OR;
71538 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71539 + tmp_reg |= DMA_MODE_BER;
71540 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71541 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71542 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71543 + tmp_reg |= DMA_MODE_ECC;
71544 + if (cfg->dma_stop_on_bus_error)
71545 + tmp_reg |= DMA_MODE_SBER;
71546 + if(cfg->dma_axi_dbg_num_of_beats)
71547 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71548 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71549 +
71550 + if (cfg->dma_en_emergency) {
71551 + tmp_reg |= cfg->dma_emergency_bus_select;
71552 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71553 + if (cfg->dma_en_emergency_smoother)
71554 + iowrite32be(cfg->dma_emergency_switch_counter,
71555 + &dma_rg->fmdmemsr);
71556 + }
71557 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71558 + DMA_MODE_CEN_SHIFT;
71559 + tmp_reg |= DMA_MODE_SECURE_PROT;
71560 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71561 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71562 +
71563 + if (cfg->pedantic_dma)
71564 + tmp_reg |= DMA_MODE_EMER_READ;
71565 +
71566 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71567 +
71568 + /* configure thresholds register */
71569 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71570 + DMA_THRESH_COMMQ_SHIFT) |
71571 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71572 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71573 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71574 +
71575 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71576 +
71577 + /* configure hysteresis register */
71578 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71579 + DMA_THRESH_COMMQ_SHIFT) |
71580 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71581 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71582 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71583 +
71584 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71585 +
71586 + /* configure emergency threshold */
71587 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71588 +
71589 + /* configure Watchdog */
71590 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71591 + &dma_rg->fmdmwcr);
71592 +
71593 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71594 +
71595 + return 0;
71596 +}
71597 +
71598 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71599 +{
71600 + uint32_t tmp_reg;
71601 + int i;
71602 +
71603 + /**********************/
71604 + /* Init FPM Registers */
71605 + /**********************/
71606 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71607 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71608 +
71609 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71610 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71611 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71612 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71613 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71614 +
71615 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71616 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71617 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71618 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71619 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71620 +
71621 + /* define exceptions and error behavior */
71622 + tmp_reg = 0;
71623 + /* Clear events */
71624 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71625 + FPM_EV_MASK_SINGLE_ECC);
71626 + /* enable interrupts */
71627 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71628 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71629 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71630 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71631 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71632 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71633 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71634 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71635 + if (!cfg->halt_on_external_activ)
71636 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71637 + if (!cfg->halt_on_unrecov_ecc_err)
71638 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71639 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71640 +
71641 + /* clear all fmCtls event registers */
71642 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71643 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71644 +
71645 + /* RAM ECC - enable and clear events*/
71646 + /* first we need to clear all parser memory,
71647 + * as it is uninitialized and may cause ECC errors */
71648 + /* event bits */
71649 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71650 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71651 + if (cfg->external_ecc_rams_enable)
71652 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71653 +
71654 + /* enable test mode */
71655 + if (cfg->en_muram_test_mode)
71656 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71657 + if (cfg->en_iram_test_mode)
71658 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71659 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71660 +
71661 + tmp_reg = 0;
71662 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71663 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71664 + fman_enable_rams_ecc(fpm_rg);
71665 + }
71666 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71667 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71668 + fman_enable_rams_ecc(fpm_rg);
71669 + }
71670 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71671 +
71672 + return 0;
71673 +}
71674 +
71675 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71676 +{
71677 + uint32_t tmp_reg;
71678 +
71679 + /**********************/
71680 + /* Init BMI Registers */
71681 + /**********************/
71682 +
71683 + /* define common resources */
71684 + tmp_reg = cfg->fifo_base_addr;
71685 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71686 +
71687 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71688 + BMI_CFG1_FIFO_SIZE_SHIFT);
71689 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71690 +
71691 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71692 + BMI_CFG2_TASKS_SHIFT);
71693 + /* num of DMA's will be dynamically updated when each port is set */
71694 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71695 +
71696 + /* define unmaskable exceptions, enable and clear events */
71697 + tmp_reg = 0;
71698 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71699 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71700 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71701 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71702 + &bmi_rg->fmbm_ievr);
71703 +
71704 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71705 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71706 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71707 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71708 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71709 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71710 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71711 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71712 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71713 +
71714 + return 0;
71715 +}
71716 +
71717 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71718 +{
71719 + uint32_t tmp_reg;
71720 + uint16_t period_in_fm_clocks;
71721 + uint8_t remainder;
71722 + /**********************/
71723 + /* Init QMI Registers */
71724 + /**********************/
71725 + /* Clear error interrupt events */
71726 +
71727 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71728 + &qmi_rg->fmqm_eie);
71729 + tmp_reg = 0;
71730 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71731 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71732 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71733 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71734 + /* enable events */
71735 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71736 +
71737 + if (cfg->tnum_aging_period) {
71738 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71739 + period_in_fm_clocks = (uint16_t)
71740 + (cfg->tnum_aging_period * cfg->clk_freq);
71741 + /* period_in_fm_clocks must be a 64 multiply */
71742 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71743 + if (remainder)
71744 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71745 + else{
71746 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71747 + if (!tmp_reg)
71748 + tmp_reg = 1;
71749 + }
71750 + tmp_reg <<= QMI_TAPC_TAP;
71751 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71752 + }
71753 + tmp_reg = 0;
71754 + /* Clear interrupt events */
71755 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71756 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71757 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71758 + /* enable events */
71759 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71760 +
71761 + return 0;
71762 +}
71763 +
71764 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71765 +{
71766 + uint32_t cfg_reg = 0;
71767 +
71768 + /**********************/
71769 + /* Enable all modules */
71770 + /**********************/
71771 + /* clear & enable global counters - calculate reg and save for later,
71772 + because it's the same reg for QMI enable */
71773 + cfg_reg = QMI_CFG_EN_COUNTERS;
71774 + if (cfg->qmi_deq_option_support)
71775 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71776 + (uint32_t)cfg->qmi_def_tnums_thresh);
71777 +
71778 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71779 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71780 + &fman_rg->qmi_rg->fmqm_gc);
71781 +
71782 + return 0;
71783 +}
71784 +
71785 +void fman_free_resources(struct fman_rg *fman_rg)
71786 +{
71787 + /* disable BMI and QMI */
71788 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71789 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71790 +
71791 + /* release BMI resources */
71792 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71793 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71794 +
71795 + /* disable ECC */
71796 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71797 +}
71798 +
71799 +/****************************************************/
71800 +/* API Run-time Control uint functions */
71801 +/****************************************************/
71802 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71803 +{
71804 + return ioread32be(&fpm_rg->fm_npi);
71805 +}
71806 +
71807 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71808 +{
71809 + uint32_t event;
71810 +
71811 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71812 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71813 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71814 +
71815 + return event;
71816 +}
71817 +
71818 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71819 +{
71820 + return ioread32be(&fpm_rg->fm_epi);
71821 +}
71822 +
71823 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71824 +{
71825 + int i;
71826 + uint8_t shift;
71827 + uint32_t tmp = 0;
71828 +
71829 + for (i = 0; i < 64; i++) {
71830 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71831 + /* Add this port to tmp_reg */
71832 + /* (each 8 ports result in one register)*/
71833 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71834 + tmp |= ((weights[i] - 1) << shift);
71835 + }
71836 + if (i % 8 == 7) { /* last in this set */
71837 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71838 + tmp = 0;
71839 + }
71840 + }
71841 +}
71842 +
71843 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71844 +{
71845 + uint32_t tmp;
71846 +
71847 + tmp = ioread32be(&fpm_rg->fm_rcr);
71848 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71849 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71850 + &fpm_rg->fm_rcr);
71851 + else
71852 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71853 + FPM_RAM_IRAM_ECC_EN,
71854 + &fpm_rg->fm_rcr);
71855 +}
71856 +
71857 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71858 +{
71859 + uint32_t tmp;
71860 +
71861 + tmp = ioread32be(&fpm_rg->fm_rcr);
71862 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71863 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71864 + &fpm_rg->fm_rcr);
71865 + else
71866 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71867 + &fpm_rg->fm_rcr);
71868 +}
71869 +
71870 +int fman_set_exception(struct fman_rg *fman_rg,
71871 + enum fman_exceptions exception,
71872 + bool enable)
71873 +{
71874 + uint32_t tmp;
71875 +
71876 + switch (exception) {
71877 + case(E_FMAN_EX_DMA_BUS_ERROR):
71878 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71879 + if (enable)
71880 + tmp |= DMA_MODE_BER;
71881 + else
71882 + tmp &= ~DMA_MODE_BER;
71883 + /* disable bus error */
71884 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71885 + break;
71886 + case(E_FMAN_EX_DMA_READ_ECC):
71887 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
71888 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
71889 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71890 + if (enable)
71891 + tmp |= DMA_MODE_ECC;
71892 + else
71893 + tmp &= ~DMA_MODE_ECC;
71894 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71895 + break;
71896 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
71897 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71898 + if (enable)
71899 + tmp |= FPM_EV_MASK_STALL_EN;
71900 + else
71901 + tmp &= ~FPM_EV_MASK_STALL_EN;
71902 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71903 + break;
71904 + case(E_FMAN_EX_FPM_SINGLE_ECC):
71905 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71906 + if (enable)
71907 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
71908 + else
71909 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
71910 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71911 + break;
71912 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
71913 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71914 + if (enable)
71915 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
71916 + else
71917 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
71918 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71919 + break;
71920 + case(E_FMAN_EX_QMI_SINGLE_ECC):
71921 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
71922 + if (enable)
71923 + tmp |= QMI_INTR_EN_SINGLE_ECC;
71924 + else
71925 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
71926 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
71927 + break;
71928 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
71929 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71930 + if (enable)
71931 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71932 + else
71933 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
71934 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71935 + break;
71936 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
71937 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71938 + if (enable)
71939 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71940 + else
71941 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71942 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71943 + break;
71944 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
71945 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71946 + if (enable)
71947 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71948 + else
71949 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
71950 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71951 + break;
71952 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
71953 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71954 + if (enable)
71955 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71956 + else
71957 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71958 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71959 + break;
71960 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
71961 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71962 + if (enable)
71963 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71964 + else
71965 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71966 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71967 + break;
71968 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
71969 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71970 + if (enable)
71971 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71972 + else
71973 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71974 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71975 + break;
71976 + case(E_FMAN_EX_IRAM_ECC):
71977 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71978 + if (enable) {
71979 + /* enable ECC if not enabled */
71980 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71981 + /* enable ECC interrupts */
71982 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
71983 + } else {
71984 + /* ECC mechanism may be disabled,
71985 + * depending on driver status */
71986 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71987 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
71988 + }
71989 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71990 + break;
71991 + case(E_FMAN_EX_MURAM_ECC):
71992 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71993 + if (enable) {
71994 + /* enable ECC if not enabled */
71995 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71996 + /* enable ECC interrupts */
71997 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
71998 + } else {
71999 + /* ECC mechanism may be disabled,
72000 + * depending on driver status */
72001 + fman_disable_rams_ecc(fman_rg->fpm_rg);
72002 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
72003 + }
72004 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
72005 + break;
72006 + default:
72007 + return -EINVAL;
72008 + }
72009 + return 0;
72010 +}
72011 +
72012 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
72013 + uint8_t *major,
72014 + uint8_t *minor)
72015 +{
72016 + uint32_t tmp;
72017 +
72018 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
72019 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
72020 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
72021 +
72022 +}
72023 +
72024 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
72025 + enum fman_counters reg_name)
72026 +{
72027 + uint32_t ret_val;
72028 +
72029 + switch (reg_name) {
72030 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72031 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
72032 + break;
72033 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72034 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
72035 + break;
72036 + case(E_FMAN_COUNTERS_DEQ_0):
72037 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
72038 + break;
72039 + case(E_FMAN_COUNTERS_DEQ_1):
72040 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
72041 + break;
72042 + case(E_FMAN_COUNTERS_DEQ_2):
72043 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
72044 + break;
72045 + case(E_FMAN_COUNTERS_DEQ_3):
72046 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
72047 + break;
72048 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72049 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
72050 + break;
72051 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72052 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
72053 + break;
72054 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72055 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
72056 + break;
72057 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72058 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
72059 + break;
72060 + default:
72061 + ret_val = 0;
72062 + }
72063 + return ret_val;
72064 +}
72065 +
72066 +int fman_modify_counter(struct fman_rg *fman_rg,
72067 + enum fman_counters reg_name,
72068 + uint32_t val)
72069 +{
72070 + /* When applicable (when there is an 'enable counters' bit,
72071 + * check that counters are enabled */
72072 + switch (reg_name) {
72073 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72074 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72075 + case(E_FMAN_COUNTERS_DEQ_0):
72076 + case(E_FMAN_COUNTERS_DEQ_1):
72077 + case(E_FMAN_COUNTERS_DEQ_2):
72078 + case(E_FMAN_COUNTERS_DEQ_3):
72079 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72080 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72081 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72082 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72083 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
72084 + QMI_CFG_EN_COUNTERS))
72085 + return -EINVAL;
72086 + break;
72087 + default:
72088 + break;
72089 + }
72090 + /* Set counter */
72091 + switch (reg_name) {
72092 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72093 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
72094 + break;
72095 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72096 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
72097 + break;
72098 + case(E_FMAN_COUNTERS_DEQ_0):
72099 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
72100 + break;
72101 + case(E_FMAN_COUNTERS_DEQ_1):
72102 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
72103 + break;
72104 + case(E_FMAN_COUNTERS_DEQ_2):
72105 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
72106 + break;
72107 + case(E_FMAN_COUNTERS_DEQ_3):
72108 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
72109 + break;
72110 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72111 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
72112 + break;
72113 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72114 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
72115 + break;
72116 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72117 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
72118 + break;
72119 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72120 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
72121 + break;
72122 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
72123 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
72124 + break;
72125 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
72126 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
72127 + break;
72128 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
72129 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
72130 + break;
72131 + default:
72132 + break;
72133 + }
72134 + return 0;
72135 +}
72136 +
72137 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
72138 + bool is_write,
72139 + bool enable)
72140 +{
72141 + uint32_t msk;
72142 +
72143 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
72144 +
72145 + if (enable)
72146 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
72147 + &dma_rg->fmdmmr);
72148 + else /* disable */
72149 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
72150 + &dma_rg->fmdmmr);
72151 +}
72152 +
72153 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
72154 +{
72155 + uint32_t tmp;
72156 +
72157 + tmp = ioread32be(&dma_rg->fmdmmr) |
72158 + (pri << DMA_MODE_BUS_PRI_SHIFT);
72159 +
72160 + iowrite32be(tmp, &dma_rg->fmdmmr);
72161 +}
72162 +
72163 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
72164 +{
72165 + return ioread32be(&dma_rg->fmdmsr);
72166 +}
72167 +
72168 +void fman_force_intr(struct fman_rg *fman_rg,
72169 + enum fman_exceptions exception)
72170 +{
72171 + switch (exception) {
72172 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
72173 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
72174 + &fman_rg->qmi_rg->fmqm_eif);
72175 + break;
72176 + case E_FMAN_EX_QMI_SINGLE_ECC:
72177 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
72178 + &fman_rg->qmi_rg->fmqm_if);
72179 + break;
72180 + case E_FMAN_EX_QMI_DOUBLE_ECC:
72181 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
72182 + &fman_rg->qmi_rg->fmqm_eif);
72183 + break;
72184 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
72185 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
72186 + &fman_rg->bmi_rg->fmbm_ifr);
72187 + break;
72188 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
72189 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
72190 + &fman_rg->bmi_rg->fmbm_ifr);
72191 + break;
72192 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
72193 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
72194 + &fman_rg->bmi_rg->fmbm_ifr);
72195 + break;
72196 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
72197 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
72198 + &fman_rg->bmi_rg->fmbm_ifr);
72199 + break;
72200 + default:
72201 + break;
72202 + }
72203 +}
72204 +
72205 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
72206 +{
72207 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
72208 +}
72209 +void fman_resume(struct fman_fpm_regs *fpm_rg)
72210 +{
72211 + uint32_t tmp;
72212 +
72213 + tmp = ioread32be(&fpm_rg->fmfp_ee);
72214 + /* clear tmp_reg event bits in order not to clear standing events */
72215 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
72216 + FPM_EV_MASK_STALL |
72217 + FPM_EV_MASK_SINGLE_ECC);
72218 + tmp |= FPM_EV_MASK_RELEASE_FM;
72219 +
72220 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
72221 +}
72222 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72223 new file mode 100644
72224 index 00000000..204840c9
72225 --- /dev/null
72226 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72227 @@ -0,0 +1,1214 @@
72228 +/*
72229 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72230 + *
72231 + * Redistribution and use in source and binary forms, with or without
72232 + * modification, are permitted provided that the following conditions are met:
72233 + * * Redistributions of source code must retain the above copyright
72234 + * notice, this list of conditions and the following disclaimer.
72235 + * * Redistributions in binary form must reproduce the above copyright
72236 + * notice, this list of conditions and the following disclaimer in the
72237 + * documentation and/or other materials provided with the distribution.
72238 + * * Neither the name of Freescale Semiconductor nor the
72239 + * names of its contributors may be used to endorse or promote products
72240 + * derived from this software without specific prior written permission.
72241 + *
72242 + *
72243 + * ALTERNATIVELY, this software may be distributed under the terms of the
72244 + * GNU General Public License ("GPL") as published by the Free Software
72245 + * Foundation, either version 2 of that License or (at your option) any
72246 + * later version.
72247 + *
72248 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72249 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72250 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72251 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72252 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72253 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72254 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72255 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72256 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72257 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72258 + */
72259 +
72260 +
72261 +/******************************************************************************
72262 + @File fm_common.h
72263 +
72264 + @Description FM internal structures and definitions.
72265 +*//***************************************************************************/
72266 +#ifndef __FM_COMMON_H
72267 +#define __FM_COMMON_H
72268 +
72269 +#include "error_ext.h"
72270 +#include "std_ext.h"
72271 +#include "fm_pcd_ext.h"
72272 +#include "fm_ext.h"
72273 +#include "fm_port_ext.h"
72274 +
72275 +
72276 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
72277 +
72278 +#define CLS_PLAN_NUM_PER_GRP 8
72279 +
72280 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
72281 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
72282 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
72283 +
72284 +
72285 +
72286 +/**************************************************************************//**
72287 + @Description Modules registers offsets
72288 +*//***************************************************************************/
72289 +#define FM_MM_MURAM 0x00000000
72290 +#define FM_MM_BMI 0x00080000
72291 +#define FM_MM_QMI 0x00080400
72292 +#define FM_MM_PRS 0x000c7000
72293 +#define FM_MM_KG 0x000C1000
72294 +#define FM_MM_DMA 0x000C2000
72295 +#define FM_MM_FPM 0x000C3000
72296 +#define FM_MM_PLCR 0x000C0000
72297 +#define FM_MM_IMEM 0x000C4000
72298 +#define FM_MM_CGP 0x000DB000
72299 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72300 +#if (DPAA_VERSION >= 11)
72301 +#define FM_MM_SP 0x000dc000
72302 +#endif /* (DPAA_VERSION >= 11) */
72303 +
72304 +
72305 +/**************************************************************************//**
72306 + @Description Enum for inter-module interrupts registration
72307 +*//***************************************************************************/
72308 +typedef enum e_FmEventModules{
72309 + e_FM_MOD_PRS, /**< Parser event */
72310 + e_FM_MOD_KG, /**< Keygen event */
72311 + e_FM_MOD_PLCR, /**< Policer event */
72312 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72313 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72314 + e_FM_MOD_TMR, /**< Timer event */
72315 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72316 + e_FM_MOD_MACSEC,
72317 + e_FM_MOD_DUMMY_LAST
72318 +} e_FmEventModules;
72319 +
72320 +/**************************************************************************//**
72321 + @Description Enum for interrupts types
72322 +*//***************************************************************************/
72323 +typedef enum e_FmIntrType {
72324 + e_FM_INTR_TYPE_ERR,
72325 + e_FM_INTR_TYPE_NORMAL
72326 +} e_FmIntrType;
72327 +
72328 +/**************************************************************************//**
72329 + @Description Enum for inter-module interrupts registration
72330 +*//***************************************************************************/
72331 +typedef enum e_FmInterModuleEvent
72332 +{
72333 + e_FM_EV_PRS = 0, /**< Parser event */
72334 + e_FM_EV_ERR_PRS, /**< Parser error event */
72335 + e_FM_EV_KG, /**< Keygen event */
72336 + e_FM_EV_ERR_KG, /**< Keygen error event */
72337 + e_FM_EV_PLCR, /**< Policer event */
72338 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72339 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72340 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72341 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72342 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72343 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72344 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72345 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72346 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72347 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72348 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72349 + e_FM_EV_ERR_MACSEC_MAC0,
72350 + e_FM_EV_TMR, /**< Timer event */
72351 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72352 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72353 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72354 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72355 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72356 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72357 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72358 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72359 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72360 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72361 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72362 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72363 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72364 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72365 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72366 + e_FM_EV_DUMMY_LAST
72367 +} e_FmInterModuleEvent;
72368 +
72369 +
72370 +#if defined(__MWERKS__) && !defined(__GNUC__)
72371 +#pragma pack(push,1)
72372 +#endif /* defined(__MWERKS__) && ... */
72373 +
72374 +/**************************************************************************//**
72375 + @Description PCD KG scheme registers
72376 +*//***************************************************************************/
72377 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72378 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72379 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72380 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72381 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72382 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72383 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72384 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72385 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72386 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72387 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72388 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72389 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72390 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72391 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72392 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72393 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72394 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72395 +} _PackedType t_FmPcdPlcrProfileRegs;
72396 +
72397 +
72398 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72399 + volatile uint32_t portIdAndCapwapReassmTbl;
72400 + volatile uint32_t fqidForTimeOutFrames;
72401 + volatile uint32_t timeoutRequestTime;
72402 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72403 +
72404 +/**************************************************************************//**
72405 + @Description PCD CTRL Parameters Page
72406 +*//***************************************************************************/
72407 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72408 + volatile uint8_t reserved0[16];
72409 + volatile uint32_t iprIpv4Nia;
72410 + volatile uint32_t iprIpv6Nia;
72411 + volatile uint8_t reserved1[24];
72412 + volatile uint32_t ipfOptionsCounter;
72413 + volatile uint8_t reserved2[12];
72414 + volatile uint32_t misc;
72415 + volatile uint32_t errorsDiscardMask;
72416 + volatile uint32_t discardMask;
72417 + volatile uint8_t reserved3[4];
72418 + volatile uint32_t postBmiFetchNia;
72419 + volatile uint8_t reserved4[172];
72420 +} _PackedType t_FmPcdCtrlParamsPage;
72421 +
72422 +
72423 +
72424 +#if defined(__MWERKS__) && !defined(__GNUC__)
72425 +#pragma pack(pop)
72426 +#endif /* defined(__MWERKS__) && ... */
72427 +
72428 +
72429 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72430 +typedef uint32_t t_FmFmanCtrl;
72431 +
72432 +#define FPM_PORT_FM_CTL1 0x00000001
72433 +#define FPM_PORT_FM_CTL2 0x00000002
72434 +
72435 +
72436 +
72437 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72438 + uint32_t numOfBuffers;
72439 + uint8_t bufferPoolId;
72440 +} t_FmPcdCcFragScratchPoolCmdParams;
72441 +
72442 +typedef struct t_FmPcdCcReassmTimeoutParams {
72443 + bool activate;
72444 + uint8_t tsbs;
72445 + uint32_t iprcpt;
72446 +} t_FmPcdCcReassmTimeoutParams;
72447 +
72448 +typedef struct {
72449 + uint8_t baseEntry;
72450 + uint16_t numOfClsPlanEntries;
72451 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72452 +} t_FmPcdKgInterModuleClsPlanSet;
72453 +
72454 +/**************************************************************************//**
72455 + @Description Structure for binding a port to keygen schemes.
72456 +*//***************************************************************************/
72457 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72458 + uint8_t hardwarePortId;
72459 + uint8_t netEnvId;
72460 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72461 + uint8_t numOfSchemes;
72462 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72463 +} t_FmPcdKgInterModuleBindPortToSchemes;
72464 +
72465 +typedef struct {
72466 + uint32_t nextCcNodeInfo;
72467 + t_List node;
72468 +} t_CcNodeInfo;
72469 +
72470 +typedef struct
72471 +{
72472 + t_Handle h_CcNode;
72473 + uint16_t index;
72474 + t_List node;
72475 +}t_CcNodeInformation;
72476 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72477 +
72478 +typedef enum e_ModifyState
72479 +{
72480 + e_MODIFY_STATE_ADD = 0,
72481 + e_MODIFY_STATE_REMOVE,
72482 + e_MODIFY_STATE_CHANGE
72483 +} e_ModifyState;
72484 +
72485 +typedef struct
72486 +{
72487 + t_Handle h_Manip;
72488 + t_List node;
72489 +}t_ManipInfo;
72490 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72491 +
72492 +typedef struct {
72493 + uint32_t type;
72494 + uint8_t prOffset;
72495 + uint16_t dataOffset;
72496 + uint8_t internalBufferOffset;
72497 + uint8_t numOfTasks;
72498 + uint8_t numOfExtraTasks;
72499 + uint8_t hardwarePortId;
72500 + t_FmRevisionInfo revInfo;
72501 + uint32_t nia;
72502 + uint32_t discardMask;
72503 +} t_GetCcParams;
72504 +
72505 +typedef struct {
72506 + uint32_t type;
72507 + int psoSize;
72508 + uint32_t nia;
72509 + t_FmFmanCtrl orFmanCtrl;
72510 + bool overwrite;
72511 + uint8_t ofpDpde;
72512 +} t_SetCcParams;
72513 +
72514 +typedef struct {
72515 + t_GetCcParams getCcParams;
72516 + t_SetCcParams setCcParams;
72517 +} t_FmPortGetSetCcParams;
72518 +
72519 +typedef struct {
72520 + uint32_t type;
72521 + bool sleep;
72522 +} t_FmSetParams;
72523 +
72524 +typedef struct {
72525 + uint32_t type;
72526 + uint32_t fmqm_gs;
72527 + uint32_t fm_npi;
72528 + uint32_t fm_cld;
72529 + uint32_t fmfp_extc;
72530 +} t_FmGetParams;
72531 +
72532 +typedef struct {
72533 + t_FmSetParams setParams;
72534 + t_FmGetParams getParams;
72535 +} t_FmGetSetParams;
72536 +
72537 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72538 +
72539 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72540 +{
72541 + uint32_t intFlags;
72542 + if (h_Spinlock)
72543 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72544 + else
72545 + intFlags = XX_DisableAllIntr();
72546 +
72547 + if (*p_Flag)
72548 + {
72549 + if (h_Spinlock)
72550 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72551 + else
72552 + XX_RestoreAllIntr(intFlags);
72553 + return FALSE;
72554 + }
72555 + *p_Flag = TRUE;
72556 +
72557 + if (h_Spinlock)
72558 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72559 + else
72560 + XX_RestoreAllIntr(intFlags);
72561 +
72562 + return TRUE;
72563 +}
72564 +
72565 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72566 +
72567 +/**************************************************************************//**
72568 + @Collection Defines used for manipulation CC and BMI
72569 + @{
72570 +*//***************************************************************************/
72571 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72572 +#define OFFSET_OF_PR 0x40000000
72573 +#define MANIP_EXTRA_SPACE 0x20000000
72574 +#define NUM_OF_TASKS 0x10000000
72575 +#define OFFSET_OF_DATA 0x08000000
72576 +#define HW_PORT_ID 0x04000000
72577 +#define FM_REV 0x02000000
72578 +#define GET_NIA_FPNE 0x01000000
72579 +#define GET_NIA_PNDN 0x00800000
72580 +#define NUM_OF_EXTRA_TASKS 0x00400000
72581 +#define DISCARD_MASK 0x00200000
72582 +
72583 +#define UPDATE_NIA_PNEN 0x80000000
72584 +#define UPDATE_PSO 0x40000000
72585 +#define UPDATE_NIA_PNDN 0x20000000
72586 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72587 +#define UPDATE_OFP_DPTE 0x08000000
72588 +#define UPDATE_NIA_FENE 0x04000000
72589 +#define UPDATE_NIA_CMNE 0x02000000
72590 +#define UPDATE_NIA_FPNE 0x01000000
72591 +/* @} */
72592 +
72593 +/**************************************************************************//**
72594 + @Collection Defines used for manipulation CC and CC
72595 + @{
72596 +*//***************************************************************************/
72597 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72598 +#define UPDATE_CC_WITH_TREE 0x40000000
72599 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72600 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72601 +#define UPDATE_KG_OPT_MODE 0x08000000
72602 +#define UPDATE_KG_NIA 0x04000000
72603 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72604 +/* @} */
72605 +
72606 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72607 +#define UPDATE_FPM_EXTC 0x40000000
72608 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72609 +#define GET_FMQM_GS 0x10000000
72610 +#define GET_FM_NPI 0x08000000
72611 +#define GET_FMFP_EXTC 0x04000000
72612 +#define CLEAR_IRAM_READY 0x02000000
72613 +#define UPDATE_FM_CLD 0x01000000
72614 +#define GET_FM_CLD 0x00800000
72615 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72616 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72617 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72618 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72619 + FM_MAX_NUM_OF_10G_TX_PORTS)
72620 +
72621 +#define MODULE_NAME_SIZE 30
72622 +#define DUMMY_PORT_ID 0
72623 +
72624 +#define FM_LIODN_OFFSET_MASK 0x3FF
72625 +
72626 +/**************************************************************************//**
72627 + @Description NIA Description
72628 +*//***************************************************************************/
72629 +#define NIA_ENG_MASK 0x007C0000
72630 +#define NIA_AC_MASK 0x0003ffff
72631 +
72632 +#define NIA_ORDER_RESTOR 0x00800000
72633 +#define NIA_ENG_FM_CTL 0x00000000
72634 +#define NIA_ENG_PRS 0x00440000
72635 +#define NIA_ENG_KG 0x00480000
72636 +#define NIA_ENG_PLCR 0x004C0000
72637 +#define NIA_ENG_BMI 0x00500000
72638 +#define NIA_ENG_QMI_ENQ 0x00540000
72639 +#define NIA_ENG_QMI_DEQ 0x00580000
72640 +
72641 +#define NIA_FM_CTL_AC_CC 0x00000006
72642 +#define NIA_FM_CTL_AC_HC 0x0000000C
72643 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72644 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72645 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72646 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72647 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72648 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72649 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72650 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72651 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72652 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72653 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72654 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72655 +/* V3 only */
72656 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72657 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72658 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72659 +
72660 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72661 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72662 +#define NIA_BMI_AC_RELEASE 0x000000C0
72663 +#define NIA_BMI_AC_DISCARD 0x000000C1
72664 +#define NIA_BMI_AC_TX 0x00000274
72665 +#define NIA_BMI_AC_FETCH 0x00000208
72666 +#define NIA_BMI_AC_MASK 0x000003FF
72667 +
72668 +#define NIA_KG_DIRECT 0x00000100
72669 +#define NIA_KG_CC_EN 0x00000200
72670 +#define NIA_PLCR_ABSOLUTE 0x00008000
72671 +
72672 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72673 +
72674 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72675 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72676 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72677 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72678 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72679 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72680 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72681 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72682 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72683 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72684 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72685 +#else
72686 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72687 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72688 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72689 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72690 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72691 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72692 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72693 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72694 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72695 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72696 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72697 +
72698 +/**************************************************************************//**
72699 + @Description CTRL Parameters Page defines
72700 +*//***************************************************************************/
72701 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72702 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72703 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72704 +
72705 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72706 +
72707 +/**************************************************************************//**
72708 + @Description Port Id defines
72709 +*//***************************************************************************/
72710 +#if (DPAA_VERSION == 10)
72711 +#define BASE_OH_PORTID 1
72712 +#else
72713 +#define BASE_OH_PORTID 2
72714 +#endif /* (DPAA_VERSION == 10) */
72715 +#define BASE_1G_RX_PORTID 8
72716 +#define BASE_10G_RX_PORTID 0x10
72717 +#define BASE_1G_TX_PORTID 0x28
72718 +#define BASE_10G_TX_PORTID 0x30
72719 +
72720 +#define FM_PCD_PORT_OH_BASE_INDX 0
72721 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72722 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72723 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72724 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72725 +
72726 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72727 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72728 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72729 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72730 +#else
72731 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72732 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72733 +#endif
72734 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72735 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72736 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72737 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72738 +#else
72739 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72740 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72741 +#endif
72742 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72743 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72744 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72745 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72746 +#else
72747 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72748 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72749 +#endif
72750 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72751 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72752 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72753 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72754 +#else
72755 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72756 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72757 +#endif
72758 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72759 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72760 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72761 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72762 +#else
72763 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72764 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72765 +#endif
72766 +
72767 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72768 +
72769 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72770 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72771 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72772 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72773 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72774 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72775 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72776 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72777 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72778 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72779 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72780 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72781 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72782 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72783 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72784 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72785 + else { \
72786 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72787 + ASSERT_COND(TRUE); \
72788 + } \
72789 +}
72790 +
72791 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72792 +do { \
72793 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72794 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72795 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72796 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72797 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72798 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72799 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72800 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72801 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72802 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72803 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72804 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72805 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72806 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72807 + else ASSERT_COND(FALSE); \
72808 +} while (0)
72809 +
72810 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72811 +do { \
72812 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72813 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72814 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72815 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72816 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72817 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72818 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72819 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72820 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72821 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72822 + else ASSERT_COND(FALSE); \
72823 +} while (0)
72824 +
72825 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72826 +#define BMI_FIFO_UNITS 0x100
72827 +
72828 +typedef struct {
72829 + void (*f_Isr) (t_Handle h_Arg);
72830 + t_Handle h_SrcHandle;
72831 + uint8_t guestId;
72832 +} t_FmIntrSrc;
72833 +
72834 +#define ILLEGAL_HDR_NUM 0xFF
72835 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72836 +
72837 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72838 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72839 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72840 +
72841 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72842 +{
72843 + switch (hdr)
72844 + { case (HEADER_TYPE_ETH): return 0;
72845 + case (HEADER_TYPE_LLC_SNAP): return 1;
72846 + case (HEADER_TYPE_VLAN): return 2;
72847 + case (HEADER_TYPE_PPPoE): return 3;
72848 + case (HEADER_TYPE_PPP): return 3;
72849 + case (HEADER_TYPE_MPLS): return 4;
72850 + case (HEADER_TYPE_IPv4): return 5;
72851 + case (HEADER_TYPE_IPv6): return 6;
72852 + case (HEADER_TYPE_GRE): return 7;
72853 + case (HEADER_TYPE_MINENCAP): return 8;
72854 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72855 + case (HEADER_TYPE_TCP): return 10;
72856 + case (HEADER_TYPE_UDP): return 11;
72857 + case (HEADER_TYPE_IPSEC_AH):
72858 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72859 + case (HEADER_TYPE_SCTP): return 13;
72860 + case (HEADER_TYPE_DCCP): return 14;
72861 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72862 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72863 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72864 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72865 + default:
72866 + return ILLEGAL_HDR_NUM;
72867 + }
72868 +}
72869 +
72870 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72871 +
72872 +
72873 +/**************************************************************************//**
72874 + @Description A structure for initializing a keygen classification plan group
72875 +*//***************************************************************************/
72876 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
72877 + uint8_t netEnvId; /* IN */
72878 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
72879 + uint8_t clsPlanGrpId; /* OUT */
72880 + bool emptyClsPlanGrp; /* OUT */
72881 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72882 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72883 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72884 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72885 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72886 +} t_FmPcdKgInterModuleClsPlanGrpParams;
72887 +
72888 +typedef struct t_FmPcdLock {
72889 + t_Handle h_Spinlock;
72890 + volatile bool flag;
72891 + t_List node;
72892 +} t_FmPcdLock;
72893 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
72894 +
72895 +
72896 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
72897 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72898 +
72899 +
72900 +/***********************************************************************/
72901 +/* Common API for FM-PCD module */
72902 +/***********************************************************************/
72903 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
72904 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
72905 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
72906 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
72907 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72908 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72909 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
72910 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
72911 +uint32_t FmPcdLock(t_Handle h_FmPcd);
72912 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
72913 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
72914 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
72915 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72916 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72917 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
72918 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
72919 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
72920 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
72921 +t_Handle FmGetPcd(t_Handle h_Fm);
72922 +/***********************************************************************/
72923 +/* Common API for FM-PCD KG module */
72924 +/***********************************************************************/
72925 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72926 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72927 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
72928 +
72929 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
72930 +#if (DPAA_VERSION >= 11)
72931 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
72932 +#endif /* (DPAA_VERSION >= 11) */
72933 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
72934 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
72935 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
72936 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
72937 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
72938 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
72939 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
72940 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
72941 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
72942 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
72943 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
72944 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
72945 +
72946 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72947 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72948 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
72949 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
72950 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
72951 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
72952 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
72953 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
72954 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
72955 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
72956 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
72957 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
72958 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
72959 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
72960 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
72961 +
72962 +/***********************************************************************/
72963 +/* Common API for FM-PCD parser module */
72964 +/***********************************************************************/
72965 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
72966 +
72967 +/***********************************************************************/
72968 +/* Common API for FM-PCD policer module */
72969 +/***********************************************************************/
72970 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
72971 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72972 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72973 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
72974 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72975 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
72976 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
72977 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
72978 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
72979 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
72980 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
72981 + e_FmPcdProfileTypeSelection profileType,
72982 + t_Handle h_FmPort,
72983 + uint16_t relativeProfile,
72984 + uint16_t *p_AbsoluteId);
72985 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72986 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72987 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
72988 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72989 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72990 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
72991 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
72992 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
72993 +
72994 +/***********************************************************************/
72995 +/* Common API for FM-PCD CC module */
72996 +/***********************************************************************/
72997 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
72998 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
72999 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
73000 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
73001 +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);
73002 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
73003 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73004 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73005 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
73006 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
73007 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
73008 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73009 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73010 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
73011 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
73012 +
73013 +/***********************************************************************/
73014 +/* Common API for FM-PCD Manip module */
73015 +/***********************************************************************/
73016 +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);
73017 +
73018 +/***********************************************************************/
73019 +/* Common API for FM-Port module */
73020 +/***********************************************************************/
73021 +#if (DPAA_VERSION >= 11)
73022 +typedef enum e_FmPortGprFuncType
73023 +{
73024 + e_FM_PORT_GPR_EMPTY = 0,
73025 + e_FM_PORT_GPR_MURAM_PAGE
73026 +} e_FmPortGprFuncType;
73027 +
73028 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
73029 +#endif /* DPAA_VERSION >= 11) */
73030 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
73031 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
73032 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
73033 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
73034 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
73035 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
73036 +
73037 +
73038 +#if (DPAA_VERSION >= 11)
73039 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
73040 +#endif /* (DPAA_VERSION >= 11) */
73041 +
73042 +/**************************************************************************//**
73043 + @Function FmRegisterIntr
73044 +
73045 + @Description Used to register an inter-module event handler to be processed by FM
73046 +
73047 + @Param[in] h_Fm A handle to an FM Module.
73048 + @Param[in] mod The module that causes the event
73049 + @Param[in] modId Module id - if more than 1 instansiation of this
73050 + mode exists,0 otherwise.
73051 + @Param[in] intrType Interrupt type (error/normal) selection.
73052 + @Param[in] f_Isr The interrupt service routine.
73053 + @Param[in] h_Arg Argument to be passed to f_Isr.
73054 +
73055 + @Return None.
73056 +*//***************************************************************************/
73057 +void FmRegisterIntr(t_Handle h_Fm,
73058 + e_FmEventModules mod,
73059 + uint8_t modId,
73060 + e_FmIntrType intrType,
73061 + void (*f_Isr) (t_Handle h_Arg),
73062 + t_Handle h_Arg);
73063 +
73064 +/**************************************************************************//**
73065 + @Function FmUnregisterIntr
73066 +
73067 + @Description Used to un-register an inter-module event handler that was processed by FM
73068 +
73069 + @Param[in] h_Fm A handle to an FM Module.
73070 + @Param[in] mod The module that causes the event
73071 + @Param[in] modId Module id - if more than 1 instansiation of this
73072 + mode exists,0 otherwise.
73073 + @Param[in] intrType Interrupt type (error/normal) selection.
73074 +
73075 + @Return None.
73076 +*//***************************************************************************/
73077 +void FmUnregisterIntr(t_Handle h_Fm,
73078 + e_FmEventModules mod,
73079 + uint8_t modId,
73080 + e_FmIntrType intrType);
73081 +
73082 +/**************************************************************************//**
73083 + @Function FmRegisterFmCtlIntr
73084 +
73085 + @Description Used to register to one of the fmCtl events in the FM module
73086 +
73087 + @Param[in] h_Fm A handle to an FM Module.
73088 + @Param[in] eventRegId FmCtl event id (0-7).
73089 + @Param[in] f_Isr The interrupt service routine.
73090 +
73091 + @Return E_OK on success; Error code otherwise.
73092 +
73093 + @Cautions Allowed only following FM_Init().
73094 +*//***************************************************************************/
73095 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
73096 +
73097 +
73098 +/**************************************************************************//**
73099 + @Description enum for defining MAC types
73100 +*//***************************************************************************/
73101 +typedef enum e_FmMacType {
73102 + e_FM_MAC_10G = 0, /**< 10G MAC */
73103 + e_FM_MAC_1G /**< 1G MAC */
73104 +} e_FmMacType;
73105 +
73106 +/**************************************************************************//**
73107 + @Description Structure for port-FM communication during FM_PORT_Init.
73108 + Fields commented 'IN' are passed by the port module to be used
73109 + by the FM module.
73110 + Fields commented 'OUT' will be filled by FM before returning to port.
73111 + Some fields are optional (depending on configuration) and
73112 + will be analized by the port and FM modules accordingly.
73113 +*//***************************************************************************/
73114 +typedef struct t_FmInterModulePortInitParams {
73115 + uint8_t hardwarePortId; /**< IN. port Id */
73116 + e_FmPortType portType; /**< IN. Port type */
73117 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
73118 + uint16_t liodnOffset; /**< IN. Port's requested resource */
73119 + uint8_t numOfTasks; /**< IN. Port's requested resource */
73120 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
73121 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
73122 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
73123 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
73124 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
73125 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73126 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
73127 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
73128 + LIODN base for this port, to be
73129 + used together with LIODN offset. */
73130 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
73131 +} t_FmInterModulePortInitParams;
73132 +
73133 +/**************************************************************************//**
73134 + @Description Structure for port-FM communication during FM_PORT_Free.
73135 +*//***************************************************************************/
73136 +typedef struct t_FmInterModulePortFreeParams {
73137 + uint8_t hardwarePortId; /**< IN. port Id */
73138 + e_FmPortType portType; /**< IN. Port type */
73139 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73140 +} t_FmInterModulePortFreeParams;
73141 +
73142 +/**************************************************************************//**
73143 + @Function FmGetPcdPrsBaseAddr
73144 +
73145 + @Description Get the base address of the Parser from the FM module
73146 +
73147 + @Param[in] h_Fm A handle to an FM Module.
73148 +
73149 + @Return Base address.
73150 +*//***************************************************************************/
73151 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
73152 +
73153 +/**************************************************************************//**
73154 + @Function FmGetPcdKgBaseAddr
73155 +
73156 + @Description Get the base address of the Keygen from the FM module
73157 +
73158 + @Param[in] h_Fm A handle to an FM Module.
73159 +
73160 + @Return Base address.
73161 +*//***************************************************************************/
73162 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
73163 +
73164 +/**************************************************************************//**
73165 + @Function FmGetPcdPlcrBaseAddr
73166 +
73167 + @Description Get the base address of the Policer from the FM module
73168 +
73169 + @Param[in] h_Fm A handle to an FM Module.
73170 +
73171 + @Return Base address.
73172 +*//***************************************************************************/
73173 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
73174 +
73175 +/**************************************************************************//**
73176 + @Function FmGetMuramHandle
73177 +
73178 + @Description Get the handle of the MURAM from the FM module
73179 +
73180 + @Param[in] h_Fm A handle to an FM Module.
73181 +
73182 + @Return MURAM module handle.
73183 +*//***************************************************************************/
73184 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
73185 +
73186 +/**************************************************************************//**
73187 + @Function FmGetPhysicalMuramBase
73188 +
73189 + @Description Get the physical base address of the MURAM from the FM module
73190 +
73191 + @Param[in] h_Fm A handle to an FM Module.
73192 + @Param[in] fmPhysAddr Physical MURAM base
73193 +
73194 + @Return Physical base address.
73195 +*//***************************************************************************/
73196 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
73197 +
73198 +/**************************************************************************//**
73199 + @Function FmGetTimeStampScale
73200 +
73201 + @Description Used internally by other modules in order to get the timeStamp
73202 + period as requested by the application.
73203 +
73204 + This function returns bit number that is incremented every 1 usec.
73205 + To calculate timestamp period in nsec, use
73206 + 1000 / (1 << FmGetTimeStampScale()).
73207 +
73208 + @Param[in] h_Fm A handle to an FM Module.
73209 +
73210 + @Return Bit that counts 1 usec.
73211 +
73212 + @Cautions Allowed only following FM_Init().
73213 +*//***************************************************************************/
73214 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
73215 +
73216 +/**************************************************************************//**
73217 + @Function FmResumeStalledPort
73218 +
73219 + @Description Used internally by FM port to release a stalled port.
73220 +
73221 + @Param[in] h_Fm A handle to an FM Module.
73222 + @Param[in] hardwarePortId HW port id.
73223 +
73224 + @Return E_OK on success; Error code otherwise.
73225 +
73226 + @Cautions Allowed only following FM_Init().
73227 +*//***************************************************************************/
73228 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
73229 +
73230 +/**************************************************************************//**
73231 + @Function FmIsPortStalled
73232 +
73233 + @Description Used internally by FM port to read the port's status.
73234 +
73235 + @Param[in] h_Fm A handle to an FM Module.
73236 + @Param[in] hardwarePortId HW port id.
73237 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
73238 +
73239 + @Return E_OK on success; Error code otherwise.
73240 +
73241 + @Cautions Allowed only following FM_Init().
73242 +*//***************************************************************************/
73243 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
73244 +
73245 +/**************************************************************************//**
73246 + @Function FmResetMac
73247 +
73248 + @Description Used by MAC driver to reset the MAC registers
73249 +
73250 + @Param[in] h_Fm A handle to an FM Module.
73251 + @Param[in] type MAC type.
73252 + @Param[in] macId MAC id - according to type.
73253 +
73254 + @Return E_OK on success; Error code otherwise.
73255 +
73256 + @Cautions Allowed only following FM_Init().
73257 +*//***************************************************************************/
73258 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
73259 +
73260 +/**************************************************************************//**
73261 + @Function FmGetClockFreq
73262 +
73263 + @Description Used by MAC driver to get the FM clock frequency
73264 +
73265 + @Param[in] h_Fm A handle to an FM Module.
73266 +
73267 + @Return clock-freq on success; 0 otherwise.
73268 +
73269 + @Cautions Allowed only following FM_Init().
73270 +*//***************************************************************************/
73271 +uint16_t FmGetClockFreq(t_Handle h_Fm);
73272 +
73273 +/**************************************************************************//**
73274 + @Function FmGetMacClockFreq
73275 +
73276 + @Description Used by MAC driver to get the MAC clock frequency
73277 +
73278 + @Param[in] h_Fm A handle to an FM Module.
73279 +
73280 + @Return clock-freq on success; 0 otherwise.
73281 +
73282 + @Cautions Allowed only following FM_Init().
73283 +*//***************************************************************************/
73284 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
73285 +
73286 +/**************************************************************************//**
73287 + @Function FmGetId
73288 +
73289 + @Description Used by PCD driver to read rhe FM id
73290 +
73291 + @Param[in] h_Fm A handle to an FM Module.
73292 +
73293 + @Return E_OK on success; Error code otherwise.
73294 +
73295 + @Cautions Allowed only following FM_Init().
73296 +*//***************************************************************************/
73297 +uint8_t FmGetId(t_Handle h_Fm);
73298 +
73299 +/**************************************************************************//**
73300 + @Function FmReset
73301 +
73302 + @Description Used to reset the FM
73303 +
73304 + @Param[in] h_Fm A handle to an FM Module.
73305 +
73306 + @Return E_OK on success; Error code otherwise.
73307 +*//***************************************************************************/
73308 +t_Error FmReset(t_Handle h_Fm);
73309 +
73310 +/**************************************************************************//**
73311 + @Function FmGetSetPortParams
73312 +
73313 + @Description Used by FM-PORT driver to pass and receive parameters between
73314 + PORT and FM modules.
73315 +
73316 + @Param[in] h_Fm A handle to an FM Module.
73317 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73318 +
73319 + @Return E_OK on success; Error code otherwise.
73320 +
73321 + @Cautions Allowed only following FM_Init().
73322 +*//***************************************************************************/
73323 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73324 +
73325 +/**************************************************************************//**
73326 + @Function FmFreePortParams
73327 +
73328 + @Description Used by FM-PORT driver to free port's resources within the FM.
73329 +
73330 + @Param[in] h_Fm A handle to an FM Module.
73331 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73332 +
73333 + @Return None.
73334 +
73335 + @Cautions Allowed only following FM_Init().
73336 +*//***************************************************************************/
73337 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73338 +
73339 +/**************************************************************************//**
73340 + @Function FmSetNumOfRiscsPerPort
73341 +
73342 + @Description Used by FM-PORT driver to pass parameter between
73343 + PORT and FM modules for working with number of RISC..
73344 +
73345 + @Param[in] h_Fm A handle to an FM Module.
73346 + @Param[in] hardwarePortId hardware port Id.
73347 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73348 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73349 +
73350 + @Return None.
73351 +
73352 + @Cautions Allowed only following FM_Init().
73353 +*//***************************************************************************/
73354 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73355 +
73356 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73357 +/**************************************************************************//*
73358 + @Function FmDumpPortRegs
73359 +
73360 + @Description Dumps FM port registers which are part of FM common registers
73361 +
73362 + @Param[in] h_Fm A handle to an FM Module.
73363 + @Param[in] hardwarePortId HW port id.
73364 +
73365 + @Return E_OK on success; Error code otherwise.
73366 +
73367 + @Cautions Allowed only FM_Init().
73368 +*//***************************************************************************/
73369 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73370 +#endif /* (defined(DEBUG_ERRORS) && ... */
73371 +
73372 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73373 +void FmUnregisterPcd(t_Handle h_Fm);
73374 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73375 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73376 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73377 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73378 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73379 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73380 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73381 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73382 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73383 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73384 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73385 +bool FmIsMaster(t_Handle h_Fm);
73386 +uint8_t FmGetGuestId(t_Handle h_Fm);
73387 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73388 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73389 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73390 +
73391 +
73392 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73393 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73394 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73395 +
73396 +void FmMuramClear(t_Handle h_FmMuram);
73397 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73398 + uint8_t hardwarePortId,
73399 + uint8_t *p_NumOfOpenDmas,
73400 + uint8_t *p_NumOfExtraOpenDmas,
73401 + bool initialConfig);
73402 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73403 + uint8_t hardwarePortId,
73404 + uint8_t *p_NumOfTasks,
73405 + uint8_t *p_NumOfExtraTasks,
73406 + bool initialConfig);
73407 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73408 + uint8_t hardwarePortId,
73409 + uint32_t *p_SizeOfFifo,
73410 + uint32_t *p_ExtraSizeOfFifo,
73411 + bool initialConfig);
73412 +
73413 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73414 + uint32_t congestionGroupId,
73415 + uint8_t priorityBitMap);
73416 +
73417 +#if (DPAA_VERSION >= 11)
73418 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73419 + e_FmPortType portType,
73420 + uint8_t portId,
73421 + uint8_t numOfStorageProfiles);
73422 +
73423 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73424 + e_FmPortType portType,
73425 + uint8_t portId);
73426 +
73427 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73428 + e_FmPortType portType,
73429 + uint8_t portId,
73430 + uint16_t relativeProfile,
73431 + uint16_t *p_AbsoluteId);
73432 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73433 + e_FmPortType portType,
73434 + uint8_t portId,
73435 + uint16_t relativeProfile);
73436 +
73437 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73438 +#endif /* (DPAA_VERSION >= 11) */
73439 +
73440 +
73441 +#endif /* __FM_COMMON_H */
73442 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73443 new file mode 100644
73444 index 00000000..492aa8a3
73445 --- /dev/null
73446 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73447 @@ -0,0 +1,93 @@
73448 +/*
73449 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73450 + *
73451 + * Redistribution and use in source and binary forms, with or without
73452 + * modification, are permitted provided that the following conditions are met:
73453 + * * Redistributions of source code must retain the above copyright
73454 + * notice, this list of conditions and the following disclaimer.
73455 + * * Redistributions in binary form must reproduce the above copyright
73456 + * notice, this list of conditions and the following disclaimer in the
73457 + * documentation and/or other materials provided with the distribution.
73458 + * * Neither the name of Freescale Semiconductor nor the
73459 + * names of its contributors may be used to endorse or promote products
73460 + * derived from this software without specific prior written permission.
73461 + *
73462 + *
73463 + * ALTERNATIVELY, this software may be distributed under the terms of the
73464 + * GNU General Public License ("GPL") as published by the Free Software
73465 + * Foundation, either version 2 of that License or (at your option) any
73466 + * later version.
73467 + *
73468 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73469 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73470 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73471 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73472 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73473 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73474 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73475 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73476 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73477 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73478 + */
73479 +
73480 +
73481 +#ifndef __FM_HC_H
73482 +#define __FM_HC_H
73483 +
73484 +#include "std_ext.h"
73485 +#include "error_ext.h"
73486 +#include "fsl_fman_kg.h"
73487 +
73488 +#define __ERR_MODULE__ MODULE_FM_PCD
73489 +
73490 +
73491 +typedef struct t_FmHcParams {
73492 + t_Handle h_Fm;
73493 + t_Handle h_FmPcd;
73494 + t_FmPcdHcParams params;
73495 +} t_FmHcParams;
73496 +
73497 +
73498 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73499 +void FmHcFree(t_Handle h_FmHc);
73500 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73501 + uint8_t memId);
73502 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73503 +
73504 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73505 +
73506 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73507 + t_Handle h_Scheme,
73508 + struct fman_kg_scheme_regs *p_SchemeRegs,
73509 + bool updateCounter);
73510 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73511 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73512 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73513 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73514 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73515 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73516 +
73517 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73518 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73519 +
73520 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73521 +
73522 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73523 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73524 +
73525 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73526 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73527 +
73528 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73529 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73530 +
73531 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73532 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73533 +
73534 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73535 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73536 +
73537 +
73538 +
73539 +
73540 +#endif /* __FM_HC_H */
73541 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73542 new file mode 100644
73543 index 00000000..f9dd384b
73544 --- /dev/null
73545 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73546 @@ -0,0 +1,117 @@
73547 +/*
73548 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73549 + *
73550 + * Redistribution and use in source and binary forms, with or without
73551 + * modification, are permitted provided that the following conditions are met:
73552 + * * Redistributions of source code must retain the above copyright
73553 + * notice, this list of conditions and the following disclaimer.
73554 + * * Redistributions in binary form must reproduce the above copyright
73555 + * notice, this list of conditions and the following disclaimer in the
73556 + * documentation and/or other materials provided with the distribution.
73557 + * * Neither the name of Freescale Semiconductor nor the
73558 + * names of its contributors may be used to endorse or promote products
73559 + * derived from this software without specific prior written permission.
73560 + *
73561 + *
73562 + * ALTERNATIVELY, this software may be distributed under the terms of the
73563 + * GNU General Public License ("GPL") as published by the Free Software
73564 + * Foundation, either version 2 of that License or (at your option) any
73565 + * later version.
73566 + *
73567 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73568 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73569 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73570 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73571 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73572 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73573 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73574 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73575 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73576 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73577 + */
73578 +
73579 +
73580 +/******************************************************************************
73581 + @File fm_sp_common.h
73582 +
73583 + @Description FM SP ...
73584 +*//***************************************************************************/
73585 +#ifndef __FM_SP_COMMON_H
73586 +#define __FM_SP_COMMON_H
73587 +
73588 +#include "std_ext.h"
73589 +#include "error_ext.h"
73590 +#include "list_ext.h"
73591 +
73592 +#include "fm_ext.h"
73593 +#include "fm_pcd_ext.h"
73594 +#include "fsl_fman.h"
73595 +
73596 +/**************************************************************************//**
73597 + @Description defaults
73598 +*//***************************************************************************/
73599 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73600 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73601 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73602 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73603 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73604 +
73605 +/**************************************************************************//**
73606 + @Description structure for defining internal context copying
73607 +*//***************************************************************************/
73608 +typedef struct
73609 +{
73610 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73611 + context is copied to (Rx) or taken from (Tx, Op). */
73612 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73613 + (Rx) or to copy to (Tx, Op). */
73614 + uint16_t size; /**< Internal offset size to be copied */
73615 +} t_FmSpIntContextDataCopy;
73616 +
73617 +/**************************************************************************//**
73618 + @Description struct for defining external buffer margins
73619 +*//***************************************************************************/
73620 +typedef struct {
73621 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73622 + of the external buffer (must be divisible by 16) */
73623 + uint16_t endMargins; /**< number of bytes to be left at the end
73624 + of the external buffer(must be divisible by 16) */
73625 +} t_FmSpBufMargins;
73626 +
73627 +typedef struct {
73628 + uint32_t dataOffset;
73629 + uint32_t prsResultOffset;
73630 + uint32_t timeStampOffset;
73631 + uint32_t hashResultOffset;
73632 + uint32_t pcdInfoOffset;
73633 + uint32_t manipOffset;
73634 +} t_FmSpBufferOffsets;
73635 +
73636 +
73637 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73638 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73639 + t_FmSpBufMargins *p_FmPortBufMargins,
73640 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73641 + uint8_t *internalBufferOffset);
73642 +
73643 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73644 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73645 + t_FmBackupBmPools *p_FmBackupBmPools,
73646 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73647 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73648 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73649 +
73650 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73651 + uint8_t hardwarePortId,
73652 + uint16_t numOfStorageProfiles,
73653 + uint16_t *base,
73654 + uint8_t *log2Num);
73655 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73656 + t_Handle h_FmPort,
73657 + uint16_t relativeProfile,
73658 + uint16_t *p_AbsoluteId);
73659 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73660 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73661 +
73662 +
73663 +#endif /* __FM_SP_COMMON_H */
73664 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73665 new file mode 100644
73666 index 00000000..d03a519c
73667 --- /dev/null
73668 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73669 @@ -0,0 +1,12 @@
73670 +#
73671 +# Makefile for the Freescale Ethernet controllers
73672 +#
73673 +ccflags-y += -DVERSION=\"\"
73674 +#
73675 +#Include netcomm SW specific definitions
73676 +
73677 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73678 +
73679 +obj-y += fsl-ncsw-etc.o
73680 +
73681 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73682 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/error.c b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73683 new file mode 100644
73684 index 00000000..fead7f50
73685 --- /dev/null
73686 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73687 @@ -0,0 +1,95 @@
73688 +/*
73689 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73690 + *
73691 + * Redistribution and use in source and binary forms, with or without
73692 + * modification, are permitted provided that the following conditions are met:
73693 + * * Redistributions of source code must retain the above copyright
73694 + * notice, this list of conditions and the following disclaimer.
73695 + * * Redistributions in binary form must reproduce the above copyright
73696 + * notice, this list of conditions and the following disclaimer in the
73697 + * documentation and/or other materials provided with the distribution.
73698 + * * Neither the name of Freescale Semiconductor nor the
73699 + * names of its contributors may be used to endorse or promote products
73700 + * derived from this software without specific prior written permission.
73701 + *
73702 + *
73703 + * ALTERNATIVELY, this software may be distributed under the terms of the
73704 + * GNU General Public License ("GPL") as published by the Free Software
73705 + * Foundation, either version 2 of that License or (at your option) any
73706 + * later version.
73707 + *
73708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73718 + */
73719 +
73720 +
73721 +/*
73722 +
73723 + @File error.c
73724 +
73725 + @Description General errors and events reporting utilities.
73726 +*//***************************************************************************/
73727 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73728 +#include "error_ext.h"
73729 +
73730 +
73731 +const char *dbgLevelStrings[] =
73732 +{
73733 + "CRITICAL"
73734 + ,"MAJOR"
73735 + ,"MINOR"
73736 + ,"WARNING"
73737 + ,"INFO"
73738 + ,"TRACE"
73739 +};
73740 +
73741 +
73742 +char * ErrTypeStrings (e_ErrorType err)
73743 +{
73744 + switch (err)
73745 + {
73746 + case (E_OK): return "OK";
73747 + case (E_WRITE_FAILED): return "Write Access Failed";
73748 + case (E_NO_DEVICE): return "No Device";
73749 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73750 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73751 + case (E_INVALID_ADDRESS): return "Invalid Address";
73752 + case (E_BUSY): return "Resource Is Busy";
73753 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73754 + case (E_INVALID_OPERATION): return "Invalid Operation";
73755 + case (E_INVALID_VALUE): return "Invalid Value";
73756 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73757 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73758 + case (E_INVALID_STATE): return "Invalid State";
73759 + case (E_INVALID_HANDLE): return "Invalid Handle";
73760 + case (E_INVALID_ID): return "Invalid ID";
73761 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73762 + case (E_INVALID_SELECTION): return "Invalid Selection";
73763 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73764 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73765 + case (E_INVALID_CLOCK): return "Invalid Clock";
73766 + case (E_CONFLICT): return "Conflict In Settings";
73767 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73768 + case (E_NOT_FOUND): return "Resource Not Found";
73769 + case (E_FULL): return "Resource Is Full";
73770 + case (E_EMPTY): return "Resource Is Empty";
73771 + case (E_ALREADY_FREE): return "Resource Already Free";
73772 + case (E_READ_FAILED): return "Read Access Failed";
73773 + case (E_INVALID_FRAME): return "Invalid Frame";
73774 + case (E_SEND_FAILED): return "Send Operation Failed";
73775 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73776 + case (E_TIMEOUT): return "Operation Timed Out";
73777 + default:
73778 + break;
73779 + }
73780 + return NULL;
73781 +}
73782 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73783 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/list.c b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73784 new file mode 100644
73785 index 00000000..2d044be2
73786 --- /dev/null
73787 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73788 @@ -0,0 +1,71 @@
73789 +/*
73790 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73791 + *
73792 + * Redistribution and use in source and binary forms, with or without
73793 + * modification, are permitted provided that the following conditions are met:
73794 + * * Redistributions of source code must retain the above copyright
73795 + * notice, this list of conditions and the following disclaimer.
73796 + * * Redistributions in binary form must reproduce the above copyright
73797 + * notice, this list of conditions and the following disclaimer in the
73798 + * documentation and/or other materials provided with the distribution.
73799 + * * Neither the name of Freescale Semiconductor nor the
73800 + * names of its contributors may be used to endorse or promote products
73801 + * derived from this software without specific prior written permission.
73802 + *
73803 + *
73804 + * ALTERNATIVELY, this software may be distributed under the terms of the
73805 + * GNU General Public License ("GPL") as published by the Free Software
73806 + * Foundation, either version 2 of that License or (at your option) any
73807 + * later version.
73808 + *
73809 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73810 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73811 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73812 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73813 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73814 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73815 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73816 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73817 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73818 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73819 + */
73820 +
73821 +
73822 +/**************************************************************************//**
73823 +
73824 + @File list.c
73825 +
73826 + @Description Implementation of list.
73827 +*//***************************************************************************/
73828 +#include "std_ext.h"
73829 +#include "list_ext.h"
73830 +
73831 +
73832 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73833 +{
73834 + t_List *p_First = LIST_FIRST(p_NewList);
73835 +
73836 + if (p_First != p_NewList)
73837 + {
73838 + t_List *p_Last = LIST_LAST(p_NewList);
73839 + t_List *p_Cur = LIST_NEXT(p_Head);
73840 +
73841 + LIST_PREV(p_First) = p_Head;
73842 + LIST_FIRST(p_Head) = p_First;
73843 + LIST_NEXT(p_Last) = p_Cur;
73844 + LIST_LAST(p_Cur) = p_Last;
73845 + }
73846 +}
73847 +
73848 +
73849 +int LIST_NumOfObjs(t_List *p_List)
73850 +{
73851 + t_List *p_Tmp;
73852 + int numOfObjs = 0;
73853 +
73854 + if (!LIST_IsEmpty(p_List))
73855 + LIST_FOR_EACH(p_Tmp, p_List)
73856 + numOfObjs++;
73857 +
73858 + return numOfObjs;
73859 +}
73860 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73861 new file mode 100644
73862 index 00000000..fa203ec7
73863 --- /dev/null
73864 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73865 @@ -0,0 +1,620 @@
73866 +/*
73867 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73868 + *
73869 + * Redistribution and use in source and binary forms, with or without
73870 + * modification, are permitted provided that the following conditions are met:
73871 + * * Redistributions of source code must retain the above copyright
73872 + * notice, this list of conditions and the following disclaimer.
73873 + * * Redistributions in binary form must reproduce the above copyright
73874 + * notice, this list of conditions and the following disclaimer in the
73875 + * documentation and/or other materials provided with the distribution.
73876 + * * Neither the name of Freescale Semiconductor nor the
73877 + * names of its contributors may be used to endorse or promote products
73878 + * derived from this software without specific prior written permission.
73879 + *
73880 + *
73881 + * ALTERNATIVELY, this software may be distributed under the terms of the
73882 + * GNU General Public License ("GPL") as published by the Free Software
73883 + * Foundation, either version 2 of that License or (at your option) any
73884 + * later version.
73885 + *
73886 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73887 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73888 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73889 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73890 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73891 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73892 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73893 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73894 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73895 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73896 + */
73897 +
73898 +
73899 +
73900 +#include "std_ext.h"
73901 +#include "xx_ext.h"
73902 +#include "memcpy_ext.h"
73903 +
73904 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
73905 +{
73906 + int i;
73907 +
73908 + for(i = 0; i < size; ++i)
73909 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
73910 +
73911 + return pDst;
73912 +}
73913 +
73914 +void * MemSet8(void* pDst, int c, uint32_t size)
73915 +{
73916 + int i;
73917 +
73918 + for(i = 0; i < size; ++i)
73919 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
73920 +
73921 + return pDst;
73922 +}
73923 +
73924 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
73925 +{
73926 + uint32_t leftAlign;
73927 + uint32_t rightAlign;
73928 + uint32_t lastWord;
73929 + uint32_t currWord;
73930 + uint32_t *p_Src32;
73931 + uint32_t *p_Dst32;
73932 + uint8_t *p_Src8;
73933 + uint8_t *p_Dst8;
73934 +
73935 + p_Src8 = (uint8_t*)(pSrc);
73936 + p_Dst8 = (uint8_t*)(pDst);
73937 + /* first copy byte by byte till the source first alignment
73938 + * this step is necessary to ensure we do not even try to access
73939 + * data which is before the source buffer, hence it is not ours.
73940 + */
73941 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73942 + {
73943 + *p_Dst8++ = *p_Src8++;
73944 + size--;
73945 + }
73946 +
73947 + /* align destination (possibly disaligning source)*/
73948 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73949 + {
73950 + *p_Dst8++ = *p_Src8++;
73951 + size--;
73952 + }
73953 +
73954 + /* dest is aligned and source is not necessarily aligned */
73955 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73956 + rightAlign = 32 - leftAlign;
73957 +
73958 +
73959 + if (leftAlign == 0)
73960 + {
73961 + /* source is also aligned */
73962 + p_Src32 = (uint32_t*)(p_Src8);
73963 + p_Dst32 = (uint32_t*)(p_Dst8);
73964 + while (size >> 2) /* size >= 4 */
73965 + {
73966 + *p_Dst32++ = *p_Src32++;
73967 + size -= 4;
73968 + }
73969 + p_Src8 = (uint8_t*)(p_Src32);
73970 + p_Dst8 = (uint8_t*)(p_Dst32);
73971 + }
73972 + else
73973 + {
73974 + /* source is not aligned (destination is aligned)*/
73975 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73976 + p_Dst32 = (uint32_t*)(p_Dst8);
73977 + lastWord = *p_Src32++;
73978 + while(size >> 3) /* size >= 8 */
73979 + {
73980 + currWord = *p_Src32;
73981 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
73982 + lastWord = currWord;
73983 + p_Src32++;
73984 + p_Dst32++;
73985 + size -= 4;
73986 + }
73987 + p_Dst8 = (uint8_t*)(p_Dst32);
73988 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73989 + }
73990 +
73991 + /* complete the left overs */
73992 + while (size--)
73993 + *p_Dst8++ = *p_Src8++;
73994 +
73995 + return pDst;
73996 +}
73997 +
73998 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73999 +{
74000 + uint32_t leftAlign;
74001 + uint32_t rightAlign;
74002 + uint32_t lastWord;
74003 + uint32_t currWord;
74004 + uint32_t *p_Src32;
74005 + uint32_t *p_Dst32;
74006 + uint8_t *p_Src8;
74007 + uint8_t *p_Dst8;
74008 +
74009 + p_Src8 = (uint8_t*)(pSrc);
74010 + p_Dst8 = (uint8_t*)(pDst);
74011 + /* first copy byte by byte till the source first alignment
74012 + * this step is necessary to ensure we do not even try to access
74013 + * data which is before the source buffer, hence it is not ours.
74014 + */
74015 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74016 + {
74017 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74018 + p_Dst8++;p_Src8++;
74019 + size--;
74020 + }
74021 +
74022 + /* align destination (possibly disaligning source)*/
74023 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74024 + {
74025 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74026 + p_Dst8++;p_Src8++;
74027 + size--;
74028 + }
74029 +
74030 + /* dest is aligned and source is not necessarily aligned */
74031 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74032 + rightAlign = 32 - leftAlign;
74033 +
74034 + if (leftAlign == 0)
74035 + {
74036 + /* source is also aligned */
74037 + p_Src32 = (uint32_t*)(p_Src8);
74038 + p_Dst32 = (uint32_t*)(p_Dst8);
74039 + while (size >> 2) /* size >= 4 */
74040 + {
74041 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
74042 + p_Dst32++;p_Src32++;
74043 + size -= 4;
74044 + }
74045 + p_Src8 = (uint8_t*)(p_Src32);
74046 + p_Dst8 = (uint8_t*)(p_Dst32);
74047 + }
74048 + else
74049 + {
74050 + /* source is not aligned (destination is aligned)*/
74051 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74052 + p_Dst32 = (uint32_t*)(p_Dst8);
74053 + lastWord = GET_UINT32(*p_Src32);
74054 + p_Src32++;
74055 + while(size >> 3) /* size >= 8 */
74056 + {
74057 + currWord = GET_UINT32(*p_Src32);
74058 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74059 + lastWord = currWord;
74060 + p_Src32++;p_Dst32++;
74061 + size -= 4;
74062 + }
74063 + p_Dst8 = (uint8_t*)(p_Dst32);
74064 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74065 + }
74066 +
74067 + /* complete the left overs */
74068 + while (size--)
74069 + {
74070 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74071 + p_Dst8++;p_Src8++;
74072 + }
74073 +
74074 + return pDst;
74075 +}
74076 +
74077 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
74078 +{
74079 + uint32_t leftAlign;
74080 + uint32_t rightAlign;
74081 + uint32_t lastWord;
74082 + uint32_t currWord;
74083 + uint32_t *p_Src32;
74084 + uint32_t *p_Dst32;
74085 + uint8_t *p_Src8;
74086 + uint8_t *p_Dst8;
74087 +
74088 + p_Src8 = (uint8_t*)(pSrc);
74089 + p_Dst8 = (uint8_t*)(pDst);
74090 + /* first copy byte by byte till the source first alignment
74091 + * this step is necessary to ensure we do not even try to access
74092 + * data which is before the source buffer, hence it is not ours.
74093 + */
74094 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74095 + {
74096 + WRITE_UINT8(*p_Dst8, *p_Src8);
74097 + p_Dst8++;p_Src8++;
74098 + size--;
74099 + }
74100 +
74101 + /* align destination (possibly disaligning source)*/
74102 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74103 + {
74104 + WRITE_UINT8(*p_Dst8, *p_Src8);
74105 + p_Dst8++;p_Src8++;
74106 + size--;
74107 + }
74108 +
74109 + /* dest is aligned and source is not necessarily aligned */
74110 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74111 + rightAlign = 32 - leftAlign;
74112 +
74113 + if (leftAlign == 0)
74114 + {
74115 + /* source is also aligned */
74116 + p_Src32 = (uint32_t*)(p_Src8);
74117 + p_Dst32 = (uint32_t*)(p_Dst8);
74118 + while (size >> 2) /* size >= 4 */
74119 + {
74120 + WRITE_UINT32(*p_Dst32, *p_Src32);
74121 + p_Dst32++;p_Src32++;
74122 + size -= 4;
74123 + }
74124 + p_Src8 = (uint8_t*)(p_Src32);
74125 + p_Dst8 = (uint8_t*)(p_Dst32);
74126 + }
74127 + else
74128 + {
74129 + /* source is not aligned (destination is aligned)*/
74130 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74131 + p_Dst32 = (uint32_t*)(p_Dst8);
74132 + lastWord = *p_Src32++;
74133 + while(size >> 3) /* size >= 8 */
74134 + {
74135 + currWord = *p_Src32;
74136 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74137 + lastWord = currWord;
74138 + p_Src32++;p_Dst32++;
74139 + size -= 4;
74140 + }
74141 + p_Dst8 = (uint8_t*)(p_Dst32);
74142 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74143 + }
74144 +
74145 + /* complete the left overs */
74146 + while (size--)
74147 + {
74148 + WRITE_UINT8(*p_Dst8, *p_Src8);
74149 + p_Dst8++;p_Src8++;
74150 + }
74151 +
74152 + return pDst;
74153 +}
74154 +
74155 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
74156 +{
74157 + uint32_t leftAlign;
74158 + uint32_t rightAlign;
74159 + uint32_t lastWord;
74160 + uint32_t currWord;
74161 + uint32_t *p_Src32;
74162 + uint32_t *p_Dst32;
74163 + uint8_t *p_Src8;
74164 + uint8_t *p_Dst8;
74165 +
74166 + p_Src8 = (uint8_t*)(pSrc);
74167 + p_Dst8 = (uint8_t*)(pDst);
74168 + /* first copy byte by byte till the source first alignment
74169 + * this step is necessary to ensure we do not even try to access
74170 + * data which is before the source buffer, hence it is not ours.
74171 + */
74172 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74173 + {
74174 + *p_Dst8 = GET_UINT8(*p_Src8);
74175 + p_Dst8++;p_Src8++;
74176 + size--;
74177 + }
74178 +
74179 + /* align destination (possibly disaligning source)*/
74180 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74181 + {
74182 + *p_Dst8 = GET_UINT8(*p_Src8);
74183 + p_Dst8++;p_Src8++;
74184 + size--;
74185 + }
74186 +
74187 + /* dest is aligned and source is not necessarily aligned */
74188 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74189 + rightAlign = 32 - leftAlign;
74190 +
74191 + if (leftAlign == 0)
74192 + {
74193 + /* source is also aligned */
74194 + p_Src32 = (uint32_t*)(p_Src8);
74195 + p_Dst32 = (uint32_t*)(p_Dst8);
74196 + while (size >> 2) /* size >= 4 */
74197 + {
74198 + *p_Dst32 = GET_UINT32(*p_Src32);
74199 + p_Dst32++;p_Src32++;
74200 + size -= 4;
74201 + }
74202 + p_Src8 = (uint8_t*)(p_Src32);
74203 + p_Dst8 = (uint8_t*)(p_Dst32);
74204 + }
74205 + else
74206 + {
74207 + /* source is not aligned (destination is aligned)*/
74208 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74209 + p_Dst32 = (uint32_t*)(p_Dst8);
74210 + lastWord = GET_UINT32(*p_Src32);
74211 + p_Src32++;
74212 + while(size >> 3) /* size >= 8 */
74213 + {
74214 + currWord = GET_UINT32(*p_Src32);
74215 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74216 + lastWord = currWord;
74217 + p_Src32++;p_Dst32++;
74218 + size -= 4;
74219 + }
74220 + p_Dst8 = (uint8_t*)(p_Dst32);
74221 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74222 + }
74223 +
74224 + /* complete the left overs */
74225 + while (size--)
74226 + {
74227 + *p_Dst8 = GET_UINT8(*p_Src8);
74228 + p_Dst8++;p_Src8++;
74229 + }
74230 +
74231 + return pDst;
74232 +}
74233 +
74234 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
74235 +{
74236 + uint32_t leftAlign;
74237 + uint32_t rightAlign;
74238 + uint64_t lastWord;
74239 + uint64_t currWord;
74240 + uint64_t *pSrc64;
74241 + uint64_t *pDst64;
74242 + uint8_t *p_Src8;
74243 + uint8_t *p_Dst8;
74244 +
74245 + p_Src8 = (uint8_t*)(pSrc);
74246 + p_Dst8 = (uint8_t*)(pDst);
74247 + /* first copy byte by byte till the source first alignment
74248 + * this step is necessarily to ensure we do not even try to access
74249 + * data which is before the source buffer, hence it is not ours.
74250 + */
74251 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
74252 + {
74253 + *p_Dst8++ = *p_Src8++;
74254 + size--;
74255 + }
74256 +
74257 + /* align destination (possibly disaligning source)*/
74258 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74259 + {
74260 + *p_Dst8++ = *p_Src8++;
74261 + size--;
74262 + }
74263 +
74264 + /* dest is aligned and source is not necessarily aligned */
74265 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
74266 + rightAlign = 64 - leftAlign;
74267 +
74268 +
74269 + if (leftAlign == 0)
74270 + {
74271 + /* source is also aligned */
74272 + pSrc64 = (uint64_t*)(p_Src8);
74273 + pDst64 = (uint64_t*)(p_Dst8);
74274 + while (size >> 3) /* size >= 8 */
74275 + {
74276 + *pDst64++ = *pSrc64++;
74277 + size -= 8;
74278 + }
74279 + p_Src8 = (uint8_t*)(pSrc64);
74280 + p_Dst8 = (uint8_t*)(pDst64);
74281 + }
74282 + else
74283 + {
74284 + /* source is not aligned (destination is aligned)*/
74285 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
74286 + pDst64 = (uint64_t*)(p_Dst8);
74287 + lastWord = *pSrc64++;
74288 + while(size >> 4) /* size >= 16 */
74289 + {
74290 + currWord = *pSrc64;
74291 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
74292 + lastWord = currWord;
74293 + pSrc64++;
74294 + pDst64++;
74295 + size -= 8;
74296 + }
74297 + p_Dst8 = (uint8_t*)(pDst64);
74298 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
74299 + }
74300 +
74301 + /* complete the left overs */
74302 + while (size--)
74303 + *p_Dst8++ = *p_Src8++;
74304 +
74305 + return pDst;
74306 +}
74307 +
74308 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
74309 +{
74310 + uint32_t val32;
74311 + uint32_t *p_Dst32;
74312 + uint8_t *p_Dst8;
74313 +
74314 + p_Dst8 = (uint8_t*)(pDst);
74315 +
74316 + /* generate four 8-bit val's in 32-bit container */
74317 + val32 = (uint32_t) val;
74318 + val32 |= (val32 << 8);
74319 + val32 |= (val32 << 16);
74320 +
74321 + /* align destination to 32 */
74322 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74323 + {
74324 + *p_Dst8++ = val;
74325 + size--;
74326 + }
74327 +
74328 + /* 32-bit chunks */
74329 + p_Dst32 = (uint32_t*)(p_Dst8);
74330 + while (size >> 2) /* size >= 4 */
74331 + {
74332 + *p_Dst32++ = val32;
74333 + size -= 4;
74334 + }
74335 +
74336 + /* complete the leftovers */
74337 + p_Dst8 = (uint8_t*)(p_Dst32);
74338 + while (size--)
74339 + *p_Dst8++ = val;
74340 +
74341 + return pDst;
74342 +}
74343 +
74344 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74345 +{
74346 + uint32_t val32;
74347 + uint32_t *p_Dst32;
74348 + uint8_t *p_Dst8;
74349 +
74350 + p_Dst8 = (uint8_t*)(pDst);
74351 +
74352 + /* generate four 8-bit val's in 32-bit container */
74353 + val32 = (uint32_t) val;
74354 + val32 |= (val32 << 8);
74355 + val32 |= (val32 << 16);
74356 +
74357 + /* align destination to 32 */
74358 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74359 + {
74360 + WRITE_UINT8(*p_Dst8, val);
74361 + p_Dst8++;
74362 + size--;
74363 + }
74364 +
74365 + /* 32-bit chunks */
74366 + p_Dst32 = (uint32_t*)(p_Dst8);
74367 + while (size >> 2) /* size >= 4 */
74368 + {
74369 + WRITE_UINT32(*p_Dst32, val32);
74370 + p_Dst32++;
74371 + size -= 4;
74372 + }
74373 +
74374 + /* complete the leftovers */
74375 + p_Dst8 = (uint8_t*)(p_Dst32);
74376 + while (size--)
74377 + {
74378 + WRITE_UINT8(*p_Dst8, val);
74379 + p_Dst8++;
74380 + }
74381 +
74382 + return pDst;
74383 +}
74384 +
74385 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74386 +{
74387 + uint64_t val64;
74388 + uint64_t *pDst64;
74389 + uint8_t *p_Dst8;
74390 +
74391 + p_Dst8 = (uint8_t*)(pDst);
74392 +
74393 + /* generate four 8-bit val's in 32-bit container */
74394 + val64 = (uint64_t) val;
74395 + val64 |= (val64 << 8);
74396 + val64 |= (val64 << 16);
74397 + val64 |= (val64 << 24);
74398 + val64 |= (val64 << 32);
74399 +
74400 + /* align destination to 64 */
74401 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74402 + {
74403 + *p_Dst8++ = val;
74404 + size--;
74405 + }
74406 +
74407 + /* 64-bit chunks */
74408 + pDst64 = (uint64_t*)(p_Dst8);
74409 + while (size >> 4) /* size >= 8 */
74410 + {
74411 + *pDst64++ = val64;
74412 + size -= 8;
74413 + }
74414 +
74415 + /* complete the leftovers */
74416 + p_Dst8 = (uint8_t*)(pDst64);
74417 + while (size--)
74418 + *p_Dst8++ = val;
74419 +
74420 + return pDst;
74421 +}
74422 +
74423 +void MemDisp(uint8_t *p, int size)
74424 +{
74425 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74426 + uint8_t *p_Limit;
74427 +
74428 + if (space)
74429 + {
74430 + p_Limit = (p - space + 4);
74431 +
74432 + XX_Print("0x%08X: ", (p - space));
74433 +
74434 + while (space--)
74435 + {
74436 + XX_Print("--");
74437 + }
74438 + while (size && (p < p_Limit))
74439 + {
74440 + XX_Print("%02x", *(uint8_t*)p);
74441 + size--;
74442 + p++;
74443 + }
74444 +
74445 + XX_Print(" ");
74446 + p_Limit += 12;
74447 +
74448 + while ((size > 3) && (p < p_Limit))
74449 + {
74450 + XX_Print("%08x ", *(uint32_t*)p);
74451 + size -= 4;
74452 + p += 4;
74453 + }
74454 + XX_Print("\r\n");
74455 + }
74456 +
74457 + while (size > 15)
74458 + {
74459 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74460 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74461 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74462 + size -= 16;
74463 + p += 16;
74464 + }
74465 +
74466 + if (size)
74467 + {
74468 + XX_Print("0x%08X: ", p);
74469 +
74470 + while (size > 3)
74471 + {
74472 + XX_Print("%08x ", *(uint32_t *)p);
74473 + size -= 4;
74474 + p += 4;
74475 + }
74476 + while (size)
74477 + {
74478 + XX_Print("%02x", *(uint8_t *)p);
74479 + size--;
74480 + p++;
74481 + }
74482 +
74483 + XX_Print("\r\n");
74484 + }
74485 +}
74486 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74487 new file mode 100644
74488 index 00000000..9fcc46e0
74489 --- /dev/null
74490 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74491 @@ -0,0 +1,1155 @@
74492 +/*
74493 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74494 + *
74495 + * Redistribution and use in source and binary forms, with or without
74496 + * modification, are permitted provided that the following conditions are met:
74497 + * * Redistributions of source code must retain the above copyright
74498 + * notice, this list of conditions and the following disclaimer.
74499 + * * Redistributions in binary form must reproduce the above copyright
74500 + * notice, this list of conditions and the following disclaimer in the
74501 + * documentation and/or other materials provided with the distribution.
74502 + * * Neither the name of Freescale Semiconductor nor the
74503 + * names of its contributors may be used to endorse or promote products
74504 + * derived from this software without specific prior written permission.
74505 + *
74506 + *
74507 + * ALTERNATIVELY, this software may be distributed under the terms of the
74508 + * GNU General Public License ("GPL") as published by the Free Software
74509 + * Foundation, either version 2 of that License or (at your option) any
74510 + * later version.
74511 + *
74512 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74513 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74514 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74515 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74516 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74517 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74518 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74519 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74520 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74521 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74522 + */
74523 +
74524 +
74525 +#include "string_ext.h"
74526 +#include "error_ext.h"
74527 +#include "std_ext.h"
74528 +#include "part_ext.h"
74529 +#include "xx_ext.h"
74530 +
74531 +#include "mm.h"
74532 +
74533 +
74534 +
74535 +
74536 +/**********************************************************************
74537 + * MM internal routines set *
74538 + **********************************************************************/
74539 +
74540 +/****************************************************************
74541 + * Routine: CreateBusyBlock
74542 + *
74543 + * Description:
74544 + * Initializes a new busy block of "size" bytes and started
74545 + * rom "base" address. Each busy block has a name that
74546 + * specified the purpose of the memory allocation.
74547 + *
74548 + * Arguments:
74549 + * base - base address of the busy block
74550 + * size - size of the busy block
74551 + * name - name that specified the busy block
74552 + *
74553 + * Return value:
74554 + * A pointer to new created structure returned on success;
74555 + * Otherwise, NULL.
74556 + ****************************************************************/
74557 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74558 +{
74559 + t_BusyBlock *p_BusyBlock;
74560 + uint32_t n;
74561 +
74562 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74563 + if ( !p_BusyBlock )
74564 + {
74565 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74566 + return NULL;
74567 + }
74568 +
74569 + p_BusyBlock->base = base;
74570 + p_BusyBlock->end = base + size;
74571 +
74572 + n = strlen(name);
74573 + if (n >= MM_MAX_NAME_LEN)
74574 + n = MM_MAX_NAME_LEN - 1;
74575 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74576 + p_BusyBlock->name[n] = '\0';
74577 + p_BusyBlock->p_Next = 0;
74578 +
74579 + return p_BusyBlock;
74580 +}
74581 +
74582 +/****************************************************************
74583 + * Routine: CreateNewBlock
74584 + *
74585 + * Description:
74586 + * Initializes a new memory block of "size" bytes and started
74587 + * from "base" address.
74588 + *
74589 + * Arguments:
74590 + * base - base address of the memory block
74591 + * size - size of the memory block
74592 + *
74593 + * Return value:
74594 + * A pointer to new created structure returned on success;
74595 + * Otherwise, NULL.
74596 + ****************************************************************/
74597 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74598 +{
74599 + t_MemBlock *p_MemBlock;
74600 +
74601 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74602 + if ( !p_MemBlock )
74603 + {
74604 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74605 + return NULL;
74606 + }
74607 +
74608 + p_MemBlock->base = base;
74609 + p_MemBlock->end = base+size;
74610 + p_MemBlock->p_Next = 0;
74611 +
74612 + return p_MemBlock;
74613 +}
74614 +
74615 +/****************************************************************
74616 + * Routine: CreateFreeBlock
74617 + *
74618 + * Description:
74619 + * Initializes a new free block of of "size" bytes and
74620 + * started from "base" address.
74621 + *
74622 + * Arguments:
74623 + * base - base address of the free block
74624 + * size - size of the free block
74625 + *
74626 + * Return value:
74627 + * A pointer to new created structure returned on success;
74628 + * Otherwise, NULL.
74629 + ****************************************************************/
74630 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74631 +{
74632 + t_FreeBlock *p_FreeBlock;
74633 +
74634 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74635 + if ( !p_FreeBlock )
74636 + {
74637 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74638 + return NULL;
74639 + }
74640 +
74641 + p_FreeBlock->base = base;
74642 + p_FreeBlock->end = base + size;
74643 + p_FreeBlock->p_Next = 0;
74644 +
74645 + return p_FreeBlock;
74646 +}
74647 +
74648 +/****************************************************************
74649 + * Routine: AddFree
74650 + *
74651 + * Description:
74652 + * Adds a new free block to the free lists. It updates each
74653 + * free list to include a new free block.
74654 + * Note, that all free block in each free list are ordered
74655 + * by their base address.
74656 + *
74657 + * Arguments:
74658 + * p_MM - pointer to the MM object
74659 + * base - base address of a given free block
74660 + * end - end address of a given free block
74661 + *
74662 + * Return value:
74663 + *
74664 + *
74665 + ****************************************************************/
74666 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74667 +{
74668 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74669 + uint64_t alignment;
74670 + uint64_t alignBase;
74671 + int i;
74672 +
74673 + /* Updates free lists to include a just released block */
74674 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74675 + {
74676 + p_PrevB = p_NewB = 0;
74677 + p_CurrB = p_MM->freeBlocks[i];
74678 +
74679 + alignment = (uint64_t)(0x1 << i);
74680 + alignBase = MAKE_ALIGNED(base, alignment);
74681 +
74682 + /* Goes to the next free list if there is no block to free */
74683 + if (alignBase >= end)
74684 + continue;
74685 +
74686 + /* Looks for a free block that should be updated */
74687 + while ( p_CurrB )
74688 + {
74689 + if ( alignBase <= p_CurrB->end )
74690 + {
74691 + if ( end > p_CurrB->end )
74692 + {
74693 + t_FreeBlock *p_NextB;
74694 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74695 + {
74696 + p_NextB = p_CurrB->p_Next;
74697 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74698 + XX_Free(p_NextB);
74699 + }
74700 +
74701 + p_NextB = p_CurrB->p_Next;
74702 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74703 + {
74704 + p_CurrB->end = end;
74705 + }
74706 + else
74707 + {
74708 + p_CurrB->end = p_NextB->end;
74709 + p_CurrB->p_Next = p_NextB->p_Next;
74710 + XX_Free(p_NextB);
74711 + }
74712 + }
74713 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74714 + {
74715 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74716 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74717 +
74718 + p_NewB->p_Next = p_CurrB;
74719 + if (p_PrevB)
74720 + p_PrevB->p_Next = p_NewB;
74721 + else
74722 + p_MM->freeBlocks[i] = p_NewB;
74723 + break;
74724 + }
74725 +
74726 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74727 + {
74728 + p_CurrB->base = alignBase;
74729 + }
74730 +
74731 + /* if size of the free block is less then alignment
74732 + * deletes that free block from the free list. */
74733 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74734 + {
74735 + if ( p_PrevB )
74736 + p_PrevB->p_Next = p_CurrB->p_Next;
74737 + else
74738 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74739 + XX_Free(p_CurrB);
74740 + p_CurrB = NULL;
74741 + }
74742 + break;
74743 + }
74744 + else
74745 + {
74746 + p_PrevB = p_CurrB;
74747 + p_CurrB = p_CurrB->p_Next;
74748 + }
74749 + }
74750 +
74751 + /* If no free block found to be updated, insert a new free block
74752 + * to the end of the free list.
74753 + */
74754 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74755 + {
74756 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74757 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74758 +
74759 + if (p_PrevB)
74760 + p_PrevB->p_Next = p_NewB;
74761 + else
74762 + p_MM->freeBlocks[i] = p_NewB;
74763 + }
74764 +
74765 + /* Update boundaries of the new free block */
74766 + if ((alignment == 1) && !p_NewB)
74767 + {
74768 + if ( p_CurrB && base > p_CurrB->base )
74769 + base = p_CurrB->base;
74770 + if ( p_CurrB && end < p_CurrB->end )
74771 + end = p_CurrB->end;
74772 + }
74773 + }
74774 +
74775 + return (E_OK);
74776 +}
74777 +
74778 +/****************************************************************
74779 + * Routine: CutFree
74780 + *
74781 + * Description:
74782 + * Cuts a free block from holdBase to holdEnd from the free lists.
74783 + * That is, it updates all free lists of the MM object do
74784 + * not include a block of memory from holdBase to holdEnd.
74785 + * For each free lists it seek for a free block that holds
74786 + * either holdBase or holdEnd. If such block is found it updates it.
74787 + *
74788 + * Arguments:
74789 + * p_MM - pointer to the MM object
74790 + * holdBase - base address of the allocated block
74791 + * holdEnd - end address of the allocated block
74792 + *
74793 + * Return value:
74794 + * E_OK is returned on success,
74795 + * otherwise returns an error code.
74796 + *
74797 + ****************************************************************/
74798 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74799 +{
74800 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74801 + uint64_t alignBase, base, end;
74802 + uint64_t alignment;
74803 + int i;
74804 +
74805 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74806 + {
74807 + p_PrevB = p_NewB = 0;
74808 + p_CurrB = p_MM->freeBlocks[i];
74809 +
74810 + alignment = (uint64_t)(0x1 << i);
74811 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74812 +
74813 + while ( p_CurrB )
74814 + {
74815 + base = p_CurrB->base;
74816 + end = p_CurrB->end;
74817 +
74818 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74819 + {
74820 + if ( alignBase >= end ||
74821 + (alignBase < end && ((end-alignBase) < alignment)) )
74822 + {
74823 + if (p_PrevB)
74824 + p_PrevB->p_Next = p_CurrB->p_Next;
74825 + else
74826 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74827 + XX_Free(p_CurrB);
74828 + }
74829 + else
74830 + {
74831 + p_CurrB->base = alignBase;
74832 + }
74833 + break;
74834 + }
74835 + else if ( (holdBase > base) && (holdEnd <= end) )
74836 + {
74837 + if ( (holdBase-base) >= alignment )
74838 + {
74839 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74840 + {
74841 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74842 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74843 + p_NewB->p_Next = p_CurrB->p_Next;
74844 + p_CurrB->p_Next = p_NewB;
74845 + }
74846 + p_CurrB->end = holdBase;
74847 + }
74848 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74849 + {
74850 + p_CurrB->base = alignBase;
74851 + }
74852 + else
74853 + {
74854 + if (p_PrevB)
74855 + p_PrevB->p_Next = p_CurrB->p_Next;
74856 + else
74857 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74858 + XX_Free(p_CurrB);
74859 + }
74860 + break;
74861 + }
74862 + else
74863 + {
74864 + p_PrevB = p_CurrB;
74865 + p_CurrB = p_CurrB->p_Next;
74866 + }
74867 + }
74868 + }
74869 +
74870 + return (E_OK);
74871 +}
74872 +
74873 +/****************************************************************
74874 + * Routine: AddBusy
74875 + *
74876 + * Description:
74877 + * Adds a new busy block to the list of busy blocks. Note,
74878 + * that all busy blocks are ordered by their base address in
74879 + * the busy list.
74880 + *
74881 + * Arguments:
74882 + * MM - handler to the MM object
74883 + * p_NewBusyB - pointer to the a busy block
74884 + *
74885 + * Return value:
74886 + * None.
74887 + *
74888 + ****************************************************************/
74889 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
74890 +{
74891 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
74892 +
74893 + /* finds a place of a new busy block in the list of busy blocks */
74894 + p_PrevBusyB = 0;
74895 + p_CurrBusyB = p_MM->busyBlocks;
74896 +
74897 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
74898 + {
74899 + p_PrevBusyB = p_CurrBusyB;
74900 + p_CurrBusyB = p_CurrBusyB->p_Next;
74901 + }
74902 +
74903 + /* insert the new busy block into the list of busy blocks */
74904 + if ( p_CurrBusyB )
74905 + p_NewBusyB->p_Next = p_CurrBusyB;
74906 + if ( p_PrevBusyB )
74907 + p_PrevBusyB->p_Next = p_NewBusyB;
74908 + else
74909 + p_MM->busyBlocks = p_NewBusyB;
74910 +}
74911 +
74912 +/****************************************************************
74913 + * Routine: CutBusy
74914 + *
74915 + * Description:
74916 + * Cuts a block from base to end from the list of busy blocks.
74917 + * This is done by updating the list of busy blocks do not
74918 + * include a given block, that block is going to be free. If a
74919 + * given block is a part of some other busy block, so that
74920 + * busy block is updated. If there are number of busy blocks
74921 + * included in the given block, so all that blocks are removed
74922 + * from the busy list and the end blocks are updated.
74923 + * If the given block devides some block into two parts, a new
74924 + * busy block is added to the busy list.
74925 + *
74926 + * Arguments:
74927 + * p_MM - pointer to the MM object
74928 + * base - base address of a given busy block
74929 + * end - end address of a given busy block
74930 + *
74931 + * Return value:
74932 + * E_OK on success, E_NOMEMORY otherwise.
74933 + *
74934 + ****************************************************************/
74935 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
74936 +{
74937 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
74938 +
74939 + p_CurrB = p_MM->busyBlocks;
74940 + p_PrevB = p_NewB = 0;
74941 +
74942 + while ( p_CurrB )
74943 + {
74944 + if ( base < p_CurrB->end )
74945 + {
74946 + if ( end > p_CurrB->end )
74947 + {
74948 + t_BusyBlock *p_NextB;
74949 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
74950 + {
74951 + p_NextB = p_CurrB->p_Next;
74952 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74953 + XX_Free(p_NextB);
74954 + }
74955 +
74956 + p_NextB = p_CurrB->p_Next;
74957 + if ( p_NextB && end > p_NextB->base )
74958 + {
74959 + p_NextB->base = end;
74960 + }
74961 + }
74962 +
74963 + if ( base <= p_CurrB->base )
74964 + {
74965 + if ( end < p_CurrB->end && end > p_CurrB->base )
74966 + {
74967 + p_CurrB->base = end;
74968 + }
74969 + else if ( end >= p_CurrB->end )
74970 + {
74971 + if ( p_PrevB )
74972 + p_PrevB->p_Next = p_CurrB->p_Next;
74973 + else
74974 + p_MM->busyBlocks = p_CurrB->p_Next;
74975 + XX_Free(p_CurrB);
74976 + }
74977 + }
74978 + else
74979 + {
74980 + if ( end < p_CurrB->end && end > p_CurrB->base )
74981 + {
74982 + if ((p_NewB = CreateBusyBlock(end,
74983 + p_CurrB->end-end,
74984 + p_CurrB->name)) == NULL)
74985 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74986 + p_NewB->p_Next = p_CurrB->p_Next;
74987 + p_CurrB->p_Next = p_NewB;
74988 + }
74989 + p_CurrB->end = base;
74990 + }
74991 + break;
74992 + }
74993 + else
74994 + {
74995 + p_PrevB = p_CurrB;
74996 + p_CurrB = p_CurrB->p_Next;
74997 + }
74998 + }
74999 +
75000 + return (E_OK);
75001 +}
75002 +
75003 +/****************************************************************
75004 + * Routine: MmGetGreaterAlignment
75005 + *
75006 + * Description:
75007 + * Allocates a block of memory according to the given size
75008 + * and the alignment. That routine is called from the MM_Get
75009 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
75010 + * In that case, it goes over free blocks of 64 byte align list
75011 + * and checks if it has the required size of bytes of the required
75012 + * alignment. If no blocks found returns ILLEGAL_BASE.
75013 + * After the block is found and data is allocated, it calls
75014 + * the internal CutFree routine to update all free lists
75015 + * do not include a just allocated block. Of course, each
75016 + * free list contains a free blocks with the same alignment.
75017 + * It is also creates a busy block that holds
75018 + * information about an allocated block.
75019 + *
75020 + * Arguments:
75021 + * MM - handle to the MM object
75022 + * size - size of the MM
75023 + * alignment - index as a power of two defines
75024 + * a required alignment that is greater then 64.
75025 + * name - the name that specifies an allocated block.
75026 + *
75027 + * Return value:
75028 + * base address of an allocated block.
75029 + * ILLEGAL_BASE if can't allocate a block
75030 + *
75031 + ****************************************************************/
75032 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
75033 +{
75034 + t_FreeBlock *p_FreeB;
75035 + t_BusyBlock *p_NewBusyB;
75036 + uint64_t holdBase, holdEnd, alignBase = 0;
75037 +
75038 + /* goes over free blocks of the 64 byte alignment list
75039 + and look for a block of the suitable size and
75040 + base address according to the alignment. */
75041 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
75042 +
75043 + while ( p_FreeB )
75044 + {
75045 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
75046 +
75047 + /* the block is found if the aligned base inside the block
75048 + * and has the anough size. */
75049 + if ( alignBase >= p_FreeB->base &&
75050 + alignBase < p_FreeB->end &&
75051 + size <= (p_FreeB->end - alignBase) )
75052 + break;
75053 + else
75054 + p_FreeB = p_FreeB->p_Next;
75055 + }
75056 +
75057 + /* If such block isn't found */
75058 + if ( !p_FreeB )
75059 + return (uint64_t)(ILLEGAL_BASE);
75060 +
75061 + holdBase = alignBase;
75062 + holdEnd = alignBase + size;
75063 +
75064 + /* init a new busy block */
75065 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75066 + return (uint64_t)(ILLEGAL_BASE);
75067 +
75068 + /* calls Update routine to update a lists of free blocks */
75069 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75070 + {
75071 + XX_Free(p_NewBusyB);
75072 + return (uint64_t)(ILLEGAL_BASE);
75073 + }
75074 +
75075 + /* insert the new busy block into the list of busy blocks */
75076 + AddBusy ( p_MM, p_NewBusyB );
75077 +
75078 + return (holdBase);
75079 +}
75080 +
75081 +
75082 +/**********************************************************************
75083 + * MM API routines set *
75084 + **********************************************************************/
75085 +
75086 +/*****************************************************************************/
75087 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
75088 +{
75089 + t_MM *p_MM;
75090 + uint64_t newBase, newSize;
75091 + int i;
75092 +
75093 + if (!size)
75094 + {
75095 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
75096 + }
75097 +
75098 + /* Initializes a new MM object */
75099 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
75100 + if (!p_MM)
75101 + {
75102 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75103 + }
75104 +
75105 + p_MM->h_Spinlock = XX_InitSpinlock();
75106 + if (!p_MM->h_Spinlock)
75107 + {
75108 + XX_Free(p_MM);
75109 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
75110 + }
75111 +
75112 + /* Initializes counter of free memory to total size */
75113 + p_MM->freeMemSize = size;
75114 +
75115 + /* A busy list is empty */
75116 + p_MM->busyBlocks = 0;
75117 +
75118 + /* Initializes a new memory block */
75119 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
75120 + {
75121 + MM_Free(p_MM);
75122 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75123 + }
75124 +
75125 + /* Initializes a new free block for each free list*/
75126 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75127 + {
75128 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
75129 + newSize = size - (newBase - base);
75130 +
75131 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
75132 + {
75133 + MM_Free(p_MM);
75134 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75135 + }
75136 + }
75137 +
75138 + *h_MM = p_MM;
75139 +
75140 + return (E_OK);
75141 +}
75142 +
75143 +/*****************************************************************************/
75144 +void MM_Free(t_Handle h_MM)
75145 +{
75146 + t_MM *p_MM = (t_MM *)h_MM;
75147 + t_MemBlock *p_MemBlock;
75148 + t_BusyBlock *p_BusyBlock;
75149 + t_FreeBlock *p_FreeBlock;
75150 + void *p_Block;
75151 + int i;
75152 +
75153 + ASSERT_COND(p_MM);
75154 +
75155 + /* release memory allocated for busy blocks */
75156 + p_BusyBlock = p_MM->busyBlocks;
75157 + while ( p_BusyBlock )
75158 + {
75159 + p_Block = p_BusyBlock;
75160 + p_BusyBlock = p_BusyBlock->p_Next;
75161 + XX_Free(p_Block);
75162 + }
75163 +
75164 + /* release memory allocated for free blocks */
75165 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75166 + {
75167 + p_FreeBlock = p_MM->freeBlocks[i];
75168 + while ( p_FreeBlock )
75169 + {
75170 + p_Block = p_FreeBlock;
75171 + p_FreeBlock = p_FreeBlock->p_Next;
75172 + XX_Free(p_Block);
75173 + }
75174 + }
75175 +
75176 + /* release memory allocated for memory blocks */
75177 + p_MemBlock = p_MM->memBlocks;
75178 + while ( p_MemBlock )
75179 + {
75180 + p_Block = p_MemBlock;
75181 + p_MemBlock = p_MemBlock->p_Next;
75182 + XX_Free(p_Block);
75183 + }
75184 +
75185 + if (p_MM->h_Spinlock)
75186 + XX_FreeSpinlock(p_MM->h_Spinlock);
75187 +
75188 + /* release memory allocated for MM object itself */
75189 + XX_Free(p_MM);
75190 +}
75191 +
75192 +/*****************************************************************************/
75193 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
75194 +{
75195 + t_MM *p_MM = (t_MM *)h_MM;
75196 + t_FreeBlock *p_FreeB;
75197 + t_BusyBlock *p_NewBusyB;
75198 + uint64_t holdBase, holdEnd, j, i = 0;
75199 + uint32_t intFlags;
75200 +
75201 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
75202 +
75203 + /* checks that alignment value is greater then zero */
75204 + if (alignment == 0)
75205 + {
75206 + alignment = 1;
75207 + }
75208 +
75209 + j = alignment;
75210 +
75211 + /* checks if alignment is a power of two, if it correct and if the
75212 + required size is multiple of the given alignment. */
75213 + while ((j & 0x1) == 0)
75214 + {
75215 + i++;
75216 + j = j >> 1;
75217 + }
75218 +
75219 + /* if the given alignment isn't power of two, returns an error */
75220 + if (j != 1)
75221 + {
75222 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
75223 + return (uint64_t)ILLEGAL_BASE;
75224 + }
75225 +
75226 + if (i > MM_MAX_ALIGNMENT)
75227 + {
75228 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
75229 + }
75230 +
75231 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75232 + /* look for a block of the size greater or equal to the required size. */
75233 + p_FreeB = p_MM->freeBlocks[i];
75234 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
75235 + p_FreeB = p_FreeB->p_Next;
75236 +
75237 + /* If such block is found */
75238 + if ( !p_FreeB )
75239 + {
75240 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75241 + return (uint64_t)(ILLEGAL_BASE);
75242 + }
75243 +
75244 + holdBase = p_FreeB->base;
75245 + holdEnd = holdBase + size;
75246 +
75247 + /* init a new busy block */
75248 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75249 + {
75250 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75251 + return (uint64_t)(ILLEGAL_BASE);
75252 + }
75253 +
75254 + /* calls Update routine to update a lists of free blocks */
75255 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75256 + {
75257 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75258 + XX_Free(p_NewBusyB);
75259 + return (uint64_t)(ILLEGAL_BASE);
75260 + }
75261 +
75262 + /* Decreasing the allocated memory size from free memory size */
75263 + p_MM->freeMemSize -= size;
75264 +
75265 + /* insert the new busy block into the list of busy blocks */
75266 + AddBusy ( p_MM, p_NewBusyB );
75267 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75268 +
75269 + return (holdBase);
75270 +}
75271 +
75272 +/*****************************************************************************/
75273 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
75274 +{
75275 + t_MM *p_MM = (t_MM *)h_MM;
75276 + t_FreeBlock *p_FreeB;
75277 + t_BusyBlock *p_NewBusyB;
75278 + uint32_t intFlags;
75279 + bool blockIsFree = FALSE;
75280 +
75281 + ASSERT_COND(p_MM);
75282 +
75283 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75284 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
75285 + free list with alignment 1 */
75286 +
75287 + while ( p_FreeB )
75288 + {
75289 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
75290 + {
75291 + blockIsFree = TRUE;
75292 + break;
75293 + }
75294 + else
75295 + p_FreeB = p_FreeB->p_Next;
75296 + }
75297 +
75298 + if ( !blockIsFree )
75299 + {
75300 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75301 + return (uint64_t)(ILLEGAL_BASE);
75302 + }
75303 +
75304 + /* init a new busy block */
75305 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
75306 + {
75307 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75308 + return (uint64_t)(ILLEGAL_BASE);
75309 + }
75310 +
75311 + /* calls Update routine to update a lists of free blocks */
75312 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
75313 + {
75314 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75315 + XX_Free(p_NewBusyB);
75316 + return (uint64_t)(ILLEGAL_BASE);
75317 + }
75318 +
75319 + /* Decreasing the allocated memory size from free memory size */
75320 + p_MM->freeMemSize -= size;
75321 +
75322 + /* insert the new busy block into the list of busy blocks */
75323 + AddBusy ( p_MM, p_NewBusyB );
75324 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75325 +
75326 + return (base);
75327 +}
75328 +
75329 +/*****************************************************************************/
75330 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75331 +{
75332 + t_MM *p_MM = (t_MM *)h_MM;
75333 + t_FreeBlock *p_FreeB;
75334 + t_BusyBlock *p_NewBusyB;
75335 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75336 + uint32_t intFlags;
75337 +
75338 + ASSERT_COND(p_MM);
75339 +
75340 + /* checks if alignment is a power of two, if it correct and if the
75341 + required size is multiple of the given alignment. */
75342 + while ((j & 0x1) == 0)
75343 + {
75344 + i++;
75345 + j = j >> 1;
75346 + }
75347 +
75348 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75349 + {
75350 + return (uint64_t)(ILLEGAL_BASE);
75351 + }
75352 +
75353 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75354 + p_FreeB = p_MM->freeBlocks[i];
75355 +
75356 + /* look for the first block that contains the minimum
75357 + base address. If the whole required size may be fit
75358 + into it, use that block, otherwise look for the next
75359 + block of size greater or equal to the required size. */
75360 + while ( p_FreeB && (min >= p_FreeB->end))
75361 + p_FreeB = p_FreeB->p_Next;
75362 +
75363 + /* If such block is found */
75364 + if ( !p_FreeB )
75365 + {
75366 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75367 + return (uint64_t)(ILLEGAL_BASE);
75368 + }
75369 +
75370 + /* if this block is large enough, use this block */
75371 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75372 + if ((holdBase + size) <= p_FreeB->end )
75373 + {
75374 + holdEnd = holdBase + size;
75375 + }
75376 + else
75377 + {
75378 + p_FreeB = p_FreeB->p_Next;
75379 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75380 + p_FreeB = p_FreeB->p_Next;
75381 +
75382 + /* If such block is found */
75383 + if ( !p_FreeB )
75384 + {
75385 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75386 + return (uint64_t)(ILLEGAL_BASE);
75387 + }
75388 +
75389 + holdBase = p_FreeB->base;
75390 + holdEnd = holdBase + size;
75391 + }
75392 +
75393 + /* init a new busy block */
75394 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75395 + {
75396 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75397 + return (uint64_t)(ILLEGAL_BASE);
75398 + }
75399 +
75400 + /* calls Update routine to update a lists of free blocks */
75401 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75402 + {
75403 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75404 + XX_Free(p_NewBusyB);
75405 + return (uint64_t)(ILLEGAL_BASE);
75406 + }
75407 +
75408 + /* Decreasing the allocated memory size from free memory size */
75409 + p_MM->freeMemSize -= size;
75410 +
75411 + /* insert the new busy block into the list of busy blocks */
75412 + AddBusy( p_MM, p_NewBusyB );
75413 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75414 +
75415 + return (holdBase);
75416 +}
75417 +
75418 +/*****************************************************************************/
75419 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75420 +{
75421 + t_MM *p_MM = (t_MM *)h_MM;
75422 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75423 + uint64_t size;
75424 + uint32_t intFlags;
75425 +
75426 + ASSERT_COND(p_MM);
75427 +
75428 + /* Look for a busy block that have the given base value.
75429 + * That block will be returned back to the memory.
75430 + */
75431 + p_PrevBusyB = 0;
75432 +
75433 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75434 + p_BusyB = p_MM->busyBlocks;
75435 + while ( p_BusyB && base != p_BusyB->base )
75436 + {
75437 + p_PrevBusyB = p_BusyB;
75438 + p_BusyB = p_BusyB->p_Next;
75439 + }
75440 +
75441 + if ( !p_BusyB )
75442 + {
75443 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75444 + return (uint64_t)(0);
75445 + }
75446 +
75447 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75448 + {
75449 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75450 + return (uint64_t)(0);
75451 + }
75452 +
75453 + /* removes a busy block form the list of busy blocks */
75454 + if ( p_PrevBusyB )
75455 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75456 + else
75457 + p_MM->busyBlocks = p_BusyB->p_Next;
75458 +
75459 + size = p_BusyB->end - p_BusyB->base;
75460 +
75461 + /* Adding the deallocated memory size to free memory size */
75462 + p_MM->freeMemSize += size;
75463 +
75464 + XX_Free(p_BusyB);
75465 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75466 +
75467 + return (size);
75468 +}
75469 +
75470 +/*****************************************************************************/
75471 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75472 +{
75473 + t_MM *p_MM = (t_MM *)h_MM;
75474 + uint64_t end = base + size;
75475 + uint32_t intFlags;
75476 +
75477 + ASSERT_COND(p_MM);
75478 +
75479 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75480 +
75481 + if ( CutBusy( p_MM, base, end ) != E_OK )
75482 + {
75483 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75484 + return (uint64_t)(0);
75485 + }
75486 +
75487 + if ( AddFree ( p_MM, base, end ) != E_OK )
75488 + {
75489 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75490 + return (uint64_t)(0);
75491 + }
75492 +
75493 + /* Adding the deallocated memory size to free memory size */
75494 + p_MM->freeMemSize += size;
75495 +
75496 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75497 +
75498 + return (size);
75499 +}
75500 +
75501 +/*****************************************************************************/
75502 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75503 +{
75504 + t_MM *p_MM = (t_MM *)h_MM;
75505 + t_MemBlock *p_MemB, *p_NewMemB;
75506 + t_Error errCode;
75507 + uint32_t intFlags;
75508 +
75509 + ASSERT_COND(p_MM);
75510 +
75511 + /* find a last block in the list of memory blocks to insert a new
75512 + * memory block
75513 + */
75514 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75515 +
75516 + p_MemB = p_MM->memBlocks;
75517 + while ( p_MemB->p_Next )
75518 + {
75519 + if ( base >= p_MemB->base && base < p_MemB->end )
75520 + {
75521 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75522 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75523 + }
75524 + p_MemB = p_MemB->p_Next;
75525 + }
75526 + /* check for a last memory block */
75527 + if ( base >= p_MemB->base && base < p_MemB->end )
75528 + {
75529 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75530 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75531 + }
75532 +
75533 + /* create a new memory block */
75534 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75535 + {
75536 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75537 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75538 + }
75539 +
75540 + /* append a new memory block to the end of the list of memory blocks */
75541 + p_MemB->p_Next = p_NewMemB;
75542 +
75543 + /* add a new free block to the free lists */
75544 + errCode = AddFree(p_MM, base, base+size);
75545 + if (errCode)
75546 + {
75547 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75548 + p_MemB->p_Next = 0;
75549 + XX_Free(p_NewMemB);
75550 + return ((t_Error)errCode);
75551 + }
75552 +
75553 + /* Adding the new block size to free memory size */
75554 + p_MM->freeMemSize += size;
75555 +
75556 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75557 +
75558 + return (E_OK);
75559 +}
75560 +
75561 +/*****************************************************************************/
75562 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75563 +{
75564 + t_MM *p_MM = (t_MM*)h_MM;
75565 + t_MemBlock *p_MemBlock;
75566 + int i;
75567 +
75568 + ASSERT_COND(p_MM);
75569 +
75570 + p_MemBlock = p_MM->memBlocks;
75571 + for (i=0; i < index; i++)
75572 + p_MemBlock = p_MemBlock->p_Next;
75573 +
75574 + if ( p_MemBlock )
75575 + return (p_MemBlock->base);
75576 + else
75577 + return (uint64_t)ILLEGAL_BASE;
75578 +}
75579 +
75580 +/*****************************************************************************/
75581 +uint64_t MM_GetBase(t_Handle h_MM)
75582 +{
75583 + t_MM *p_MM = (t_MM*)h_MM;
75584 + t_MemBlock *p_MemBlock;
75585 +
75586 + ASSERT_COND(p_MM);
75587 +
75588 + p_MemBlock = p_MM->memBlocks;
75589 + return p_MemBlock->base;
75590 +}
75591 +
75592 +/*****************************************************************************/
75593 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75594 +{
75595 + t_MM *p_MM = (t_MM*)h_MM;
75596 + t_MemBlock *p_MemBlock;
75597 +
75598 + ASSERT_COND(p_MM);
75599 +
75600 + p_MemBlock = p_MM->memBlocks;
75601 +
75602 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75603 + return TRUE;
75604 + else
75605 + return FALSE;
75606 +}
75607 +
75608 +/*****************************************************************************/
75609 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75610 +{
75611 + t_MM *p_MM = (t_MM*)h_MM;
75612 +
75613 + ASSERT_COND(p_MM);
75614 +
75615 + return p_MM->freeMemSize;
75616 +}
75617 +
75618 +/*****************************************************************************/
75619 +void MM_Dump(t_Handle h_MM)
75620 +{
75621 + t_MM *p_MM = (t_MM *)h_MM;
75622 + t_FreeBlock *p_FreeB;
75623 + t_BusyBlock *p_BusyB;
75624 + int i;
75625 +
75626 + p_BusyB = p_MM->busyBlocks;
75627 + XX_Print("List of busy blocks:\n");
75628 + while (p_BusyB)
75629 + {
75630 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75631 + p_BusyB = p_BusyB->p_Next;
75632 + }
75633 +
75634 + XX_Print("\nLists of free blocks according to alignment:\n");
75635 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75636 + {
75637 + XX_Print("%d alignment:\n", (0x1 << i));
75638 + p_FreeB = p_MM->freeBlocks[i];
75639 + while (p_FreeB)
75640 + {
75641 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75642 + p_FreeB = p_FreeB->p_Next;
75643 + }
75644 + XX_Print("\n");
75645 + }
75646 +}
75647 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75648 new file mode 100644
75649 index 00000000..43b2298f
75650 --- /dev/null
75651 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75652 @@ -0,0 +1,105 @@
75653 +/*
75654 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75655 + *
75656 + * Redistribution and use in source and binary forms, with or without
75657 + * modification, are permitted provided that the following conditions are met:
75658 + * * Redistributions of source code must retain the above copyright
75659 + * notice, this list of conditions and the following disclaimer.
75660 + * * Redistributions in binary form must reproduce the above copyright
75661 + * notice, this list of conditions and the following disclaimer in the
75662 + * documentation and/or other materials provided with the distribution.
75663 + * * Neither the name of Freescale Semiconductor nor the
75664 + * names of its contributors may be used to endorse or promote products
75665 + * derived from this software without specific prior written permission.
75666 + *
75667 + *
75668 + * ALTERNATIVELY, this software may be distributed under the terms of the
75669 + * GNU General Public License ("GPL") as published by the Free Software
75670 + * Foundation, either version 2 of that License or (at your option) any
75671 + * later version.
75672 + *
75673 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75674 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75675 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75676 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75677 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75678 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75679 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75680 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75681 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75682 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75683 + */
75684 +
75685 +
75686 +/****************************************************************
75687 + *
75688 + * File: mm.h
75689 + *
75690 + *
75691 + * Description:
75692 + * MM (Memory Management) object definitions.
75693 + * It also includes definitions of the Free Block, Busy Block
75694 + * and Memory Block structures used by the MM object.
75695 + *
75696 + ****************************************************************/
75697 +
75698 +#ifndef __MM_H
75699 +#define __MM_H
75700 +
75701 +
75702 +#include "mm_ext.h"
75703 +
75704 +#define __ERR_MODULE__ MODULE_MM
75705 +
75706 +
75707 +#define MAKE_ALIGNED(addr, align) \
75708 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75709 +
75710 +
75711 +/* t_MemBlock data structure defines parameters of the Memory Block */
75712 +typedef struct t_MemBlock
75713 +{
75714 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75715 +
75716 + uint64_t base; /* Base address of the memory block */
75717 + uint64_t end; /* End address of the memory block */
75718 +} t_MemBlock;
75719 +
75720 +
75721 +/* t_FreeBlock data structure defines parameters of the Free Block */
75722 +typedef struct t_FreeBlock
75723 +{
75724 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75725 +
75726 + uint64_t base; /* Base address of the block */
75727 + uint64_t end; /* End address of the block */
75728 +} t_FreeBlock;
75729 +
75730 +
75731 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75732 +typedef struct t_BusyBlock
75733 +{
75734 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75735 +
75736 + uint64_t base; /* Base address of the block */
75737 + uint64_t end; /* End address of the block */
75738 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75739 + something specified by the Name */
75740 +} t_BusyBlock;
75741 +
75742 +
75743 +/* t_MM data structure defines parameters of the MM object */
75744 +typedef struct t_MM
75745 +{
75746 + t_Handle h_Spinlock;
75747 +
75748 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75749 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75750 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75751 + /* Alignment lists of free blocks (Free lists) */
75752 +
75753 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75754 +} t_MM;
75755 +
75756 +
75757 +#endif /* __MM_H */
75758 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75759 new file mode 100644
75760 index 00000000..46d2956a
75761 --- /dev/null
75762 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75763 @@ -0,0 +1,81 @@
75764 +/*
75765 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75766 + *
75767 + * Redistribution and use in source and binary forms, with or without
75768 + * modification, are permitted provided that the following conditions are met:
75769 + * * Redistributions of source code must retain the above copyright
75770 + * notice, this list of conditions and the following disclaimer.
75771 + * * Redistributions in binary form must reproduce the above copyright
75772 + * notice, this list of conditions and the following disclaimer in the
75773 + * documentation and/or other materials provided with the distribution.
75774 + * * Neither the name of Freescale Semiconductor nor the
75775 + * names of its contributors may be used to endorse or promote products
75776 + * derived from this software without specific prior written permission.
75777 + *
75778 + *
75779 + * ALTERNATIVELY, this software may be distributed under the terms of the
75780 + * GNU General Public License ("GPL") as published by the Free Software
75781 + * Foundation, either version 2 of that License or (at your option) any
75782 + * later version.
75783 + *
75784 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75785 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75786 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75787 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75788 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75789 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75790 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75791 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75792 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75793 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75794 + */
75795 +
75796 +
75797 +/*------------------------------------------------------*/
75798 +/* File: sprint.c */
75799 +/* */
75800 +/* Description: */
75801 +/* Debug routines (externals) */
75802 +/*------------------------------------------------------*/
75803 +#include "string_ext.h"
75804 +#include "stdlib_ext.h"
75805 +#include "stdarg_ext.h"
75806 +#include "sprint_ext.h"
75807 +#include "std_ext.h"
75808 +#include "xx_ext.h"
75809 +
75810 +
75811 +int Sprint(char * buf, const char *fmt, ...)
75812 +{
75813 + va_list args;
75814 + int i;
75815 +
75816 + va_start(args, fmt);
75817 + i=vsprintf(buf,fmt,args);
75818 + va_end(args);
75819 + return i;
75820 +}
75821 +
75822 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75823 +{
75824 + va_list args;
75825 + int i;
75826 +
75827 + va_start(args, fmt);
75828 + i=vsnprintf(buf,size,fmt,args);
75829 + va_end(args);
75830 + return i;
75831 +}
75832 +
75833 +#ifndef NCSW_VXWORKS
75834 +int Sscan(const char * buf, const char * fmt, ...)
75835 +{
75836 + va_list args;
75837 + int i;
75838 +
75839 + va_start(args,fmt);
75840 + i = vsscanf(buf,fmt,args);
75841 + va_end(args);
75842 + return i;
75843 +}
75844 +#endif /* NCSW_VXWORKS */
75845 diff --git a/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75846 new file mode 100644
75847 index 00000000..435b0d2b
75848 --- /dev/null
75849 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75850 @@ -0,0 +1,57 @@
75851 +/*
75852 + * Copyright 2012 Freescale Semiconductor Inc.
75853 + *
75854 + * Redistribution and use in source and binary forms, with or without
75855 + * modification, are permitted provided that the following conditions are met:
75856 + * * Redistributions of source code must retain the above copyright
75857 + * notice, this list of conditions and the following disclaimer.
75858 + * * Redistributions in binary form must reproduce the above copyright
75859 + * notice, this list of conditions and the following disclaimer in the
75860 + * documentation and/or other materials provided with the distribution.
75861 + * * Neither the name of Freescale Semiconductor nor the
75862 + * names of its contributors may be used to endorse or promote products
75863 + * derived from this software without specific prior written permission.
75864 + *
75865 + *
75866 + * ALTERNATIVELY, this software may be distributed under the terms of the
75867 + * GNU General Public License ("GPL") as published by the Free Software
75868 + * Foundation, either version 2 of that License or (at your option) any
75869 + * later version.
75870 + *
75871 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75872 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75873 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75874 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75875 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75876 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75877 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75878 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75879 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75880 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75881 + */
75882 +
75883 +#ifndef __dflags_h
75884 +#define __dflags_h
75885 +
75886 +
75887 +#define NCSW_LINUX
75888 +
75889 +#define T4240
75890 +#define NCSW_PPC_CORE
75891 +
75892 +#define DEBUG_ERRORS 1
75893 +
75894 +#if defined(DEBUG)
75895 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75896 +
75897 +#define DEBUG_XX_MALLOC
75898 +#define DEBUG_MEM_LEAKS
75899 +
75900 +#else
75901 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75902 +#endif /* (DEBUG) */
75903 +
75904 +#define REPORT_EVENTS 1
75905 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75906 +
75907 +#endif /* __dflags_h */
75908 diff --git a/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75909 new file mode 100644
75910 index 00000000..789eb879
75911 --- /dev/null
75912 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75913 @@ -0,0 +1,56 @@
75914 +/*
75915 + * Copyright 2012 Freescale Semiconductor Inc.
75916 + *
75917 + * Redistribution and use in source and binary forms, with or without
75918 + * modification, are permitted provided that the following conditions are met:
75919 + * * Redistributions of source code must retain the above copyright
75920 + * notice, this list of conditions and the following disclaimer.
75921 + * * Redistributions in binary form must reproduce the above copyright
75922 + * notice, this list of conditions and the following disclaimer in the
75923 + * documentation and/or other materials provided with the distribution.
75924 + * * Neither the name of Freescale Semiconductor nor the
75925 + * names of its contributors may be used to endorse or promote products
75926 + * derived from this software without specific prior written permission.
75927 + *
75928 + *
75929 + * ALTERNATIVELY, this software may be distributed under the terms of the
75930 + * GNU General Public License ("GPL") as published by the Free Software
75931 + * Foundation, either version 2 of that License or (at your option) any
75932 + * later version.
75933 + *
75934 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75935 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75936 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75937 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75938 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75939 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75940 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75941 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75942 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75943 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75944 + */
75945 +
75946 +#ifndef __dflags_h
75947 +#define __dflags_h
75948 +
75949 +
75950 +#define NCSW_LINUX
75951 +
75952 +#define NCSW_PPC_CORE
75953 +
75954 +#define DEBUG_ERRORS 1
75955 +
75956 +#if defined(DEBUG)
75957 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75958 +
75959 +#define DEBUG_XX_MALLOC
75960 +#define DEBUG_MEM_LEAKS
75961 +
75962 +#else
75963 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75964 +#endif /* (DEBUG) */
75965 +
75966 +#define REPORT_EVENTS 1
75967 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75968 +
75969 +#endif /* __dflags_h */
75970 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75971 new file mode 100644
75972 index 00000000..a84d5631
75973 --- /dev/null
75974 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75975 @@ -0,0 +1,364 @@
75976 +/*
75977 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75978 + *
75979 + * Redistribution and use in source and binary forms, with or without
75980 + * modification, are permitted provided that the following conditions are met:
75981 + * * Redistributions of source code must retain the above copyright
75982 + * notice, this list of conditions and the following disclaimer.
75983 + * * Redistributions in binary form must reproduce the above copyright
75984 + * notice, this list of conditions and the following disclaimer in the
75985 + * documentation and/or other materials provided with the distribution.
75986 + * * Neither the name of Freescale Semiconductor nor the
75987 + * names of its contributors may be used to endorse or promote products
75988 + * derived from this software without specific prior written permission.
75989 + *
75990 + *
75991 + * ALTERNATIVELY, this software may be distributed under the terms of the
75992 + * GNU General Public License ("GPL") as published by the Free Software
75993 + * Foundation, either version 2 of that License or (at your option) any
75994 + * later version.
75995 + *
75996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76006 + */
76007 +
76008 +
76009 +/*------------------------------------------------------*/
76010 +/* */
76011 +/* File: crc_mac_addr_ext.h */
76012 +/* */
76013 +/* Description: */
76014 +/* Define a macro that calculate the crc value of */
76015 +/* an Ethernet MAC address (48 bitd address */
76016 +/*------------------------------------------------------*/
76017 +
76018 +#ifndef __crc_mac_addr_ext_h
76019 +#define __crc_mac_addr_ext_h
76020 +
76021 +#include "std_ext.h"
76022 +
76023 +
76024 +static uint32_t crc_table[256] =
76025 +{
76026 + 0x00000000,
76027 + 0x77073096,
76028 + 0xee0e612c,
76029 + 0x990951ba,
76030 + 0x076dc419,
76031 + 0x706af48f,
76032 + 0xe963a535,
76033 + 0x9e6495a3,
76034 + 0x0edb8832,
76035 + 0x79dcb8a4,
76036 + 0xe0d5e91e,
76037 + 0x97d2d988,
76038 + 0x09b64c2b,
76039 + 0x7eb17cbd,
76040 + 0xe7b82d07,
76041 + 0x90bf1d91,
76042 + 0x1db71064,
76043 + 0x6ab020f2,
76044 + 0xf3b97148,
76045 + 0x84be41de,
76046 + 0x1adad47d,
76047 + 0x6ddde4eb,
76048 + 0xf4d4b551,
76049 + 0x83d385c7,
76050 + 0x136c9856,
76051 + 0x646ba8c0,
76052 + 0xfd62f97a,
76053 + 0x8a65c9ec,
76054 + 0x14015c4f,
76055 + 0x63066cd9,
76056 + 0xfa0f3d63,
76057 + 0x8d080df5,
76058 + 0x3b6e20c8,
76059 + 0x4c69105e,
76060 + 0xd56041e4,
76061 + 0xa2677172,
76062 + 0x3c03e4d1,
76063 + 0x4b04d447,
76064 + 0xd20d85fd,
76065 + 0xa50ab56b,
76066 + 0x35b5a8fa,
76067 + 0x42b2986c,
76068 + 0xdbbbc9d6,
76069 + 0xacbcf940,
76070 + 0x32d86ce3,
76071 + 0x45df5c75,
76072 + 0xdcd60dcf,
76073 + 0xabd13d59,
76074 + 0x26d930ac,
76075 + 0x51de003a,
76076 + 0xc8d75180,
76077 + 0xbfd06116,
76078 + 0x21b4f4b5,
76079 + 0x56b3c423,
76080 + 0xcfba9599,
76081 + 0xb8bda50f,
76082 + 0x2802b89e,
76083 + 0x5f058808,
76084 + 0xc60cd9b2,
76085 + 0xb10be924,
76086 + 0x2f6f7c87,
76087 + 0x58684c11,
76088 + 0xc1611dab,
76089 + 0xb6662d3d,
76090 + 0x76dc4190,
76091 + 0x01db7106,
76092 + 0x98d220bc,
76093 + 0xefd5102a,
76094 + 0x71b18589,
76095 + 0x06b6b51f,
76096 + 0x9fbfe4a5,
76097 + 0xe8b8d433,
76098 + 0x7807c9a2,
76099 + 0x0f00f934,
76100 + 0x9609a88e,
76101 + 0xe10e9818,
76102 + 0x7f6a0dbb,
76103 + 0x086d3d2d,
76104 + 0x91646c97,
76105 + 0xe6635c01,
76106 + 0x6b6b51f4,
76107 + 0x1c6c6162,
76108 + 0x856530d8,
76109 + 0xf262004e,
76110 + 0x6c0695ed,
76111 + 0x1b01a57b,
76112 + 0x8208f4c1,
76113 + 0xf50fc457,
76114 + 0x65b0d9c6,
76115 + 0x12b7e950,
76116 + 0x8bbeb8ea,
76117 + 0xfcb9887c,
76118 + 0x62dd1ddf,
76119 + 0x15da2d49,
76120 + 0x8cd37cf3,
76121 + 0xfbd44c65,
76122 + 0x4db26158,
76123 + 0x3ab551ce,
76124 + 0xa3bc0074,
76125 + 0xd4bb30e2,
76126 + 0x4adfa541,
76127 + 0x3dd895d7,
76128 + 0xa4d1c46d,
76129 + 0xd3d6f4fb,
76130 + 0x4369e96a,
76131 + 0x346ed9fc,
76132 + 0xad678846,
76133 + 0xda60b8d0,
76134 + 0x44042d73,
76135 + 0x33031de5,
76136 + 0xaa0a4c5f,
76137 + 0xdd0d7cc9,
76138 + 0x5005713c,
76139 + 0x270241aa,
76140 + 0xbe0b1010,
76141 + 0xc90c2086,
76142 + 0x5768b525,
76143 + 0x206f85b3,
76144 + 0xb966d409,
76145 + 0xce61e49f,
76146 + 0x5edef90e,
76147 + 0x29d9c998,
76148 + 0xb0d09822,
76149 + 0xc7d7a8b4,
76150 + 0x59b33d17,
76151 + 0x2eb40d81,
76152 + 0xb7bd5c3b,
76153 + 0xc0ba6cad,
76154 + 0xedb88320,
76155 + 0x9abfb3b6,
76156 + 0x03b6e20c,
76157 + 0x74b1d29a,
76158 + 0xead54739,
76159 + 0x9dd277af,
76160 + 0x04db2615,
76161 + 0x73dc1683,
76162 + 0xe3630b12,
76163 + 0x94643b84,
76164 + 0x0d6d6a3e,
76165 + 0x7a6a5aa8,
76166 + 0xe40ecf0b,
76167 + 0x9309ff9d,
76168 + 0x0a00ae27,
76169 + 0x7d079eb1,
76170 + 0xf00f9344,
76171 + 0x8708a3d2,
76172 + 0x1e01f268,
76173 + 0x6906c2fe,
76174 + 0xf762575d,
76175 + 0x806567cb,
76176 + 0x196c3671,
76177 + 0x6e6b06e7,
76178 + 0xfed41b76,
76179 + 0x89d32be0,
76180 + 0x10da7a5a,
76181 + 0x67dd4acc,
76182 + 0xf9b9df6f,
76183 + 0x8ebeeff9,
76184 + 0x17b7be43,
76185 + 0x60b08ed5,
76186 + 0xd6d6a3e8,
76187 + 0xa1d1937e,
76188 + 0x38d8c2c4,
76189 + 0x4fdff252,
76190 + 0xd1bb67f1,
76191 + 0xa6bc5767,
76192 + 0x3fb506dd,
76193 + 0x48b2364b,
76194 + 0xd80d2bda,
76195 + 0xaf0a1b4c,
76196 + 0x36034af6,
76197 + 0x41047a60,
76198 + 0xdf60efc3,
76199 + 0xa867df55,
76200 + 0x316e8eef,
76201 + 0x4669be79,
76202 + 0xcb61b38c,
76203 + 0xbc66831a,
76204 + 0x256fd2a0,
76205 + 0x5268e236,
76206 + 0xcc0c7795,
76207 + 0xbb0b4703,
76208 + 0x220216b9,
76209 + 0x5505262f,
76210 + 0xc5ba3bbe,
76211 + 0xb2bd0b28,
76212 + 0x2bb45a92,
76213 + 0x5cb36a04,
76214 + 0xc2d7ffa7,
76215 + 0xb5d0cf31,
76216 + 0x2cd99e8b,
76217 + 0x5bdeae1d,
76218 + 0x9b64c2b0,
76219 + 0xec63f226,
76220 + 0x756aa39c,
76221 + 0x026d930a,
76222 + 0x9c0906a9,
76223 + 0xeb0e363f,
76224 + 0x72076785,
76225 + 0x05005713,
76226 + 0x95bf4a82,
76227 + 0xe2b87a14,
76228 + 0x7bb12bae,
76229 + 0x0cb61b38,
76230 + 0x92d28e9b,
76231 + 0xe5d5be0d,
76232 + 0x7cdcefb7,
76233 + 0x0bdbdf21,
76234 + 0x86d3d2d4,
76235 + 0xf1d4e242,
76236 + 0x68ddb3f8,
76237 + 0x1fda836e,
76238 + 0x81be16cd,
76239 + 0xf6b9265b,
76240 + 0x6fb077e1,
76241 + 0x18b74777,
76242 + 0x88085ae6,
76243 + 0xff0f6a70,
76244 + 0x66063bca,
76245 + 0x11010b5c,
76246 + 0x8f659eff,
76247 + 0xf862ae69,
76248 + 0x616bffd3,
76249 + 0x166ccf45,
76250 + 0xa00ae278,
76251 + 0xd70dd2ee,
76252 + 0x4e048354,
76253 + 0x3903b3c2,
76254 + 0xa7672661,
76255 + 0xd06016f7,
76256 + 0x4969474d,
76257 + 0x3e6e77db,
76258 + 0xaed16a4a,
76259 + 0xd9d65adc,
76260 + 0x40df0b66,
76261 + 0x37d83bf0,
76262 + 0xa9bcae53,
76263 + 0xdebb9ec5,
76264 + 0x47b2cf7f,
76265 + 0x30b5ffe9,
76266 + 0xbdbdf21c,
76267 + 0xcabac28a,
76268 + 0x53b39330,
76269 + 0x24b4a3a6,
76270 + 0xbad03605,
76271 + 0xcdd70693,
76272 + 0x54de5729,
76273 + 0x23d967bf,
76274 + 0xb3667a2e,
76275 + 0xc4614ab8,
76276 + 0x5d681b02,
76277 + 0x2a6f2b94,
76278 + 0xb40bbe37,
76279 + 0xc30c8ea1,
76280 + 0x5a05df1b,
76281 + 0x2d02ef8d
76282 +};
76283 +
76284 +
76285 +#define GET_MAC_ADDR_CRC(addr, crc) \
76286 +{ \
76287 + uint32_t i; \
76288 + uint8_t data; \
76289 + \
76290 + /* CRC calculation */ \
76291 + crc = 0xffffffff; \
76292 + for (i=0; i < 6; i++) \
76293 + { \
76294 + data = (uint8_t)(addr >> ((5-i)*8)); \
76295 + crc = crc^data; \
76296 + crc = crc_table[crc&0xff] ^ (crc>>8); \
76297 + } \
76298 +} \
76299 +
76300 +/* Define a macro for getting the mirrored value of */
76301 +/* a byte size number. (0x11010011 --> 0x11001011) */
76302 +/* Sometimes the mirrored value of the CRC is required */
76303 +static __inline__ uint8_t GetMirror(uint8_t n)
76304 +{
76305 + uint8_t mirror[16] =
76306 + {
76307 + 0x00,
76308 + 0x08,
76309 + 0x04,
76310 + 0x0c,
76311 + 0x02,
76312 + 0x0a,
76313 + 0x06,
76314 + 0x0e,
76315 + 0x01,
76316 + 0x09,
76317 + 0x05,
76318 + 0x0d,
76319 + 0x03,
76320 + 0x0b,
76321 + 0x07,
76322 + 0x0f
76323 + };
76324 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
76325 +}
76326 +
76327 +static __inline__ uint32_t GetMirror32(uint32_t n)
76328 +{
76329 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
76330 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
76331 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
76332 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76333 +}
76334 +
76335 +#define MIRROR GetMirror
76336 +#define MIRROR_32 GetMirror32
76337 +
76338 +
76339 +#endif /* __crc_mac_addr_ext_h */
76340 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76341 new file mode 100644
76342 index 00000000..e6d9e932
76343 --- /dev/null
76344 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76345 @@ -0,0 +1,210 @@
76346 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76347 + * All rights reserved.
76348 + *
76349 + * Redistribution and use in source and binary forms, with or without
76350 + * modification, are permitted provided that the following conditions are met:
76351 + * * Redistributions of source code must retain the above copyright
76352 + * notice, this list of conditions and the following disclaimer.
76353 + * * Redistributions in binary form must reproduce the above copyright
76354 + * notice, this list of conditions and the following disclaimer in the
76355 + * documentation and/or other materials provided with the distribution.
76356 + * * Neither the name of Freescale Semiconductor nor the
76357 + * names of its contributors may be used to endorse or promote products
76358 + * derived from this software without specific prior written permission.
76359 + *
76360 + *
76361 + * ALTERNATIVELY, this software may be distributed under the terms of the
76362 + * GNU General Public License ("GPL") as published by the Free Software
76363 + * Foundation, either version 2 of that License or (at your option) any
76364 + * later version.
76365 + *
76366 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76367 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76368 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76369 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76370 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76371 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76372 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76373 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76374 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76375 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76376 + */
76377 +
76378 +
76379 +/**************************************************************************//**
76380 + @File dpaa_ext.h
76381 +
76382 + @Description DPAA Application Programming Interface.
76383 +*//***************************************************************************/
76384 +#ifndef __DPAA_EXT_H
76385 +#define __DPAA_EXT_H
76386 +
76387 +#include "std_ext.h"
76388 +#include "error_ext.h"
76389 +
76390 +
76391 +/**************************************************************************//**
76392 + @Group DPAA_grp Data Path Acceleration Architecture API
76393 +
76394 + @Description DPAA API functions, definitions and enums.
76395 +
76396 + @{
76397 +*//***************************************************************************/
76398 +
76399 +#if defined(__MWERKS__) && !defined(__GNUC__)
76400 +#pragma pack(push,1)
76401 +#endif /* defined(__MWERKS__) && ... */
76402 +
76403 +/**************************************************************************//**
76404 + @Description Frame descriptor
76405 +*//***************************************************************************/
76406 +typedef _Packed struct t_DpaaFD {
76407 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76408 + volatile uint8_t liodn;
76409 + volatile uint8_t bpid;
76410 + volatile uint8_t elion;
76411 + volatile uint8_t addrh;
76412 + volatile uint32_t addrl;
76413 +#else
76414 + volatile uint32_t addrl;
76415 + volatile uint8_t addrh;
76416 + volatile uint8_t elion;
76417 + volatile uint8_t bpid;
76418 + volatile uint8_t liodn;
76419 + #endif
76420 + volatile uint32_t length; /**< Frame length */
76421 + volatile uint32_t status; /**< FD status */
76422 +} _PackedType t_DpaaFD;
76423 +
76424 +/**************************************************************************//**
76425 + @Description enum for defining frame format
76426 +*//***************************************************************************/
76427 +typedef enum e_DpaaFDFormatType {
76428 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76429 + small length (9b OFFSET, 20b LENGTH) */
76430 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76431 + (29b LENGTH ,No OFFSET) */
76432 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76433 + and small length (9b OFFSET, 20b LENGTH) */
76434 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76435 + big length (29b LENGTH ,No OFFSET) */
76436 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76437 + No LENGTH or OFFSET) */
76438 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76439 +} e_DpaaFDFormatType;
76440 +
76441 +/**************************************************************************//**
76442 + @Collection Frame descriptor macros
76443 +*//***************************************************************************/
76444 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76445 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76446 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76447 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76448 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76449 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76450 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76451 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76452 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76453 +
76454 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76455 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76456 +#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 */
76457 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76458 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76459 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76460 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76461 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76462 +
76463 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76464 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76465 +#define DPAA_FD_SET_ADDR(fd,val) \
76466 +do { \
76467 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76468 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76469 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76470 +} while (0) /**< Macro to set FD ADDR field */
76471 +#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 */
76472 +#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 */
76473 +#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 */
76474 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76475 +/* @} */
76476 +
76477 +/**************************************************************************//**
76478 + @Description Frame Scatter/Gather Table Entry
76479 +*//***************************************************************************/
76480 +typedef _Packed struct t_DpaaSGTE {
76481 + volatile uint32_t addrh; /**< Buffer Address high */
76482 + volatile uint32_t addrl; /**< Buffer Address low */
76483 + volatile uint32_t length; /**< Buffer length */
76484 + volatile uint32_t offset; /**< SGTE offset */
76485 +} _PackedType t_DpaaSGTE;
76486 +
76487 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76488 +
76489 +/**************************************************************************//**
76490 + @Description Frame Scatter/Gather Table
76491 +*//***************************************************************************/
76492 +typedef _Packed struct t_DpaaSGT {
76493 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76494 + /**< Structure that holds information about
76495 + a single S/G entry. */
76496 +} _PackedType t_DpaaSGT;
76497 +
76498 +/**************************************************************************//**
76499 + @Description Compound Frame Table
76500 +*//***************************************************************************/
76501 +typedef _Packed struct t_DpaaCompTbl {
76502 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76503 + the compound-frame output buffer;
76504 + NOTE: this may point to a S/G table */
76505 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76506 + the compound-frame input buffer;
76507 + NOTE: this may point to a S/G table */
76508 +} _PackedType t_DpaaCompTbl;
76509 +
76510 +/**************************************************************************//**
76511 + @Collection Frame Scatter/Gather Table Entry macros
76512 +*//***************************************************************************/
76513 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76514 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76515 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76516 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76517 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76518 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76519 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76520 +
76521 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76522 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76523 +#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 */
76524 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76525 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76526 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76527 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76528 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76529 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76530 +
76531 +#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 */
76532 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76533 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76534 +do { \
76535 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76536 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76537 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76538 +} while (0) /**< Macro to set SGTE ADDR field */
76539 +#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 */
76540 +#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 */
76541 +#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 */
76542 +#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 */
76543 +#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 */
76544 +/* @} */
76545 +
76546 +#if defined(__MWERKS__) && !defined(__GNUC__)
76547 +#pragma pack(pop)
76548 +#endif /* defined(__MWERKS__) && ... */
76549 +
76550 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76551 +
76552 +/** @} */ /* end of DPAA_grp group */
76553 +
76554 +
76555 +#endif /* __DPAA_EXT_H */
76556 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76557 new file mode 100644
76558 index 00000000..a8a64386
76559 --- /dev/null
76560 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76561 @@ -0,0 +1,1731 @@
76562 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76563 + * All rights reserved.
76564 + *
76565 + * Redistribution and use in source and binary forms, with or without
76566 + * modification, are permitted provided that the following conditions are met:
76567 + * * Redistributions of source code must retain the above copyright
76568 + * notice, this list of conditions and the following disclaimer.
76569 + * * Redistributions in binary form must reproduce the above copyright
76570 + * notice, this list of conditions and the following disclaimer in the
76571 + * documentation and/or other materials provided with the distribution.
76572 + * * Neither the name of Freescale Semiconductor nor the
76573 + * names of its contributors may be used to endorse or promote products
76574 + * derived from this software without specific prior written permission.
76575 + *
76576 + *
76577 + * ALTERNATIVELY, this software may be distributed under the terms of the
76578 + * GNU General Public License ("GPL") as published by the Free Software
76579 + * Foundation, either version 2 of that License or (at your option) any
76580 + * later version.
76581 + *
76582 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76583 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76584 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76585 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76586 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76587 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76588 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76589 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76590 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76591 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76592 + */
76593 +
76594 +
76595 +/**************************************************************************//**
76596 + @File fm_ext.h
76597 +
76598 + @Description FM Application Programming Interface.
76599 +*//***************************************************************************/
76600 +#ifndef __FM_EXT
76601 +#define __FM_EXT
76602 +
76603 +#include "error_ext.h"
76604 +#include "std_ext.h"
76605 +#include "dpaa_ext.h"
76606 +#include "fsl_fman_sp.h"
76607 +
76608 +/**************************************************************************//**
76609 + @Group FM_grp Frame Manager API
76610 +
76611 + @Description FM API functions, definitions and enums.
76612 +
76613 + @{
76614 +*//***************************************************************************/
76615 +
76616 +/**************************************************************************//**
76617 + @Group FM_lib_grp FM library
76618 +
76619 + @Description FM API functions, definitions and enums.
76620 +
76621 + The FM module is the main driver module and is a mandatory module
76622 + for FM driver users. This module must be initialized first prior
76623 + to any other drivers modules.
76624 + The FM is a "singleton" module. It is responsible of the common
76625 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76626 + run-time control routines. This module must be initialized always
76627 + when working with any of the FM modules.
76628 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76629 +
76630 + @{
76631 +*//***************************************************************************/
76632 +
76633 +/**************************************************************************//**
76634 + @Description Enum for defining port types
76635 +*//***************************************************************************/
76636 +typedef enum e_FmPortType {
76637 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76638 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76639 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76640 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76641 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76642 + e_FM_PORT_TYPE_DUMMY
76643 +} e_FmPortType;
76644 +
76645 +/**************************************************************************//**
76646 + @Collection General FM defines
76647 +*//***************************************************************************/
76648 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76649 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76650 +/* @} */
76651 +
76652 +
76653 +#if defined(__MWERKS__) && !defined(__GNUC__)
76654 +#pragma pack(push,1)
76655 +#endif /* defined(__MWERKS__) && ... */
76656 +
76657 +/**************************************************************************//**
76658 + @Description FM physical Address
76659 +*//***************************************************************************/
76660 +typedef _Packed struct t_FmPhysAddr {
76661 + volatile uint8_t high; /**< High part of the physical address */
76662 + volatile uint32_t low; /**< Low part of the physical address */
76663 +} _PackedType t_FmPhysAddr;
76664 +
76665 +/**************************************************************************//**
76666 + @Description Parse results memory layout
76667 +*//***************************************************************************/
76668 +typedef _Packed struct t_FmPrsResult {
76669 + volatile uint8_t lpid; /**< Logical port id */
76670 + volatile uint8_t shimr; /**< Shim header result */
76671 + volatile uint16_t l2r; /**< Layer 2 result */
76672 + volatile uint16_t l3r; /**< Layer 3 result */
76673 + volatile uint8_t l4r; /**< Layer 4 result */
76674 + volatile uint8_t cplan; /**< Classification plan id */
76675 + volatile uint16_t nxthdr; /**< Next Header */
76676 + volatile uint16_t cksum; /**< Running-sum */
76677 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76678 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76679 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76680 + volatile uint8_t shim_off[2]; /**< Shim offset */
76681 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76682 + volatile uint8_t eth_off; /**< ETH offset */
76683 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76684 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76685 + volatile uint8_t etype_off; /**< ETYPE offset */
76686 + volatile uint8_t pppoe_off; /**< PPP offset */
76687 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76688 + volatile uint8_t ip_off[2]; /**< IP offset */
76689 + volatile uint8_t gre_off; /**< GRE offset */
76690 + volatile uint8_t l4_off; /**< Layer 4 offset */
76691 + volatile uint8_t nxthdr_off; /**< Parser end point */
76692 +} _PackedType t_FmPrsResult;
76693 +
76694 +/**************************************************************************//**
76695 + @Collection FM Parser results
76696 +*//***************************************************************************/
76697 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76698 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76699 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76700 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76701 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76702 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76703 +/* @} */
76704 +
76705 +/**************************************************************************//**
76706 + @Collection FM Frame descriptor macros
76707 +*//***************************************************************************/
76708 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76709 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76710 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76711 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76712 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76713 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76714 +
76715 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76716 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76717 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76718 +
76719 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76720 +
76721 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76722 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76723 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76724 +
76725 +#ifdef FM_CAPWAP_SUPPORT
76726 +#define FM_FD_ERR_CRE 0x00200000
76727 +#define FM_FD_ERR_CHE 0x00100000
76728 +#endif /* FM_CAPWAP_SUPPORT */
76729 +
76730 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76731 + error (SGMII and TBI modes), FIFO parity error. PHY
76732 + Sequence error, PHY error control character detected. */
76733 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76734 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76735 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76736 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76737 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76738 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76739 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76740 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76741 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76742 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76743 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76744 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76745 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76746 +
76747 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76748 + FM_FD_ERR_LENGTH | \
76749 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76750 +
76751 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76752 + FM_FD_ERR_LENGTH | \
76753 + FM_FD_ERR_DMA | \
76754 + FM_FD_ERR_IPR | \
76755 + FM_FD_ERR_IPR_TO | \
76756 + FM_FD_ERR_IPR_NCSP | \
76757 + FM_FD_ERR_PHYSICAL | \
76758 + FM_FD_ERR_SIZE | \
76759 + FM_FD_ERR_CLS_DISCARD | \
76760 + FM_FD_ERR_COLOR_RED | \
76761 + FM_FD_ERR_COLOR_YELLOW | \
76762 + FM_FD_ERR_ILL_PLCR | \
76763 + FM_FD_ERR_PLCR_FRAME_LEN | \
76764 + FM_FD_ERR_EXTRACTION | \
76765 + FM_FD_ERR_NO_SCHEME | \
76766 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76767 + FM_FD_ERR_PRS_TIMEOUT | \
76768 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76769 + FM_FD_ERR_PRS_HDR_ERR | \
76770 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76771 +
76772 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76773 +/* @} */
76774 +
76775 +/**************************************************************************//**
76776 + @Description Context A
76777 +*//***************************************************************************/
76778 +typedef _Packed struct t_FmContextA {
76779 + volatile uint32_t command; /**< ContextA Command */
76780 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76781 +} _PackedType t_FmContextA;
76782 +
76783 +/**************************************************************************//**
76784 + @Description Context B
76785 +*//***************************************************************************/
76786 +typedef uint32_t t_FmContextB;
76787 +
76788 +/**************************************************************************//**
76789 + @Collection Special Operation options
76790 +*//***************************************************************************/
76791 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76792 +
76793 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76794 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76795 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76796 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76797 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76798 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76799 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76800 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76801 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76802 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76803 +/* @} */
76804 +
76805 +/**************************************************************************//**
76806 + @Collection Context A macros
76807 +*//***************************************************************************/
76808 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76809 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76810 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76811 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76812 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76813 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76814 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76815 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76816 +
76817 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76818 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76819 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76820 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76821 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76822 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76823 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76824 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76825 +
76826 +#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) ))
76827 +#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) ))
76828 +#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) ))
76829 +#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) ))
76830 +#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) ))
76831 +#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) ))
76832 +#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) ))
76833 +#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) ))
76834 +/* @} */
76835 +
76836 +/**************************************************************************//**
76837 + @Collection Context B macros
76838 +*//***************************************************************************/
76839 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76840 +
76841 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76842 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76843 +/* @} */
76844 +
76845 +#if defined(__MWERKS__) && !defined(__GNUC__)
76846 +#pragma pack(pop)
76847 +#endif /* defined(__MWERKS__) && ... */
76848 +
76849 +
76850 +/**************************************************************************//**
76851 + @Description FM Exceptions
76852 +*//***************************************************************************/
76853 +typedef enum e_FmExceptions {
76854 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76855 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76856 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76857 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76858 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76859 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76860 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76861 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76862 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76863 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76864 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76865 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76866 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76867 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76868 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76869 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76870 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76871 +} e_FmExceptions;
76872 +
76873 +/**************************************************************************//**
76874 + @Description Enum for defining port DMA swap mode
76875 +*//***************************************************************************/
76876 +typedef enum e_FmDmaSwapOption {
76877 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
76878 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
76879 + in PowerPc Little Endian mode. */
76880 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
76881 + in Big Endian mode */
76882 +} e_FmDmaSwapOption;
76883 +
76884 +/**************************************************************************//**
76885 + @Description Enum for defining port DMA cache attributes
76886 +*//***************************************************************************/
76887 +typedef enum e_FmDmaCacheOption {
76888 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
76889 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
76890 +} e_FmDmaCacheOption;
76891 +
76892 +
76893 +/**************************************************************************//**
76894 + @Group FM_init_grp FM Initialization Unit
76895 +
76896 + @Description FM Initialization Unit
76897 +
76898 + Initialization Flow
76899 + Initialization of the FM Module will be carried out by the application
76900 + according to the following sequence:
76901 + - Calling the configuration routine with basic parameters.
76902 + - Calling the advance initialization routines to change driver's defaults.
76903 + - Calling the initialization routine.
76904 +
76905 + @{
76906 +*//***************************************************************************/
76907 +
76908 +/**************************************************************************//**
76909 + @Function t_FmExceptionsCallback
76910 +
76911 + @Description Exceptions user callback routine, will be called upon an
76912 + exception passing the exception identification.
76913 +
76914 + @Param[in] h_App - User's application descriptor.
76915 + @Param[in] exception - The exception.
76916 +*//***************************************************************************/
76917 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
76918 + e_FmExceptions exception);
76919 +
76920 +
76921 +/**************************************************************************//**
76922 + @Function t_FmBusErrorCallback
76923 +
76924 + @Description Bus error user callback routine, will be called upon a
76925 + bus error, passing parameters describing the errors and the owner.
76926 +
76927 + @Param[in] h_App - User's application descriptor.
76928 + @Param[in] portType - Port type (e_FmPortType)
76929 + @Param[in] portId - Port id - relative to type.
76930 + @Param[in] addr - Address that caused the error
76931 + @Param[in] tnum - Owner of error
76932 + @Param[in] liodn - Logical IO device number
76933 +*//***************************************************************************/
76934 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
76935 + e_FmPortType portType,
76936 + uint8_t portId,
76937 + uint64_t addr,
76938 + uint8_t tnum,
76939 + uint16_t liodn);
76940 +
76941 +/**************************************************************************//**
76942 + @Description A structure for defining buffer prefix area content.
76943 +*//***************************************************************************/
76944 +typedef struct t_FmBufferPrefixContent {
76945 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
76946 + of the external buffer; Note that the private-area will
76947 + start from the base of the buffer address. */
76948 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
76949 + User may use FM_PORT_GetBufferPrsResult() in order to
76950 + get the parser-result from a buffer. */
76951 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
76952 + User may use FM_PORT_GetBufferTimeStamp() in order to
76953 + get the parser-result from a buffer. */
76954 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
76955 + User may use FM_PORT_GetBufferHashResult() in order to
76956 + get the parser-result from a buffer. */
76957 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
76958 + AD, hash-result, key, etc. */
76959 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
76960 + other value for selecting a data alignment (must be a power of 2);
76961 + if write optimization is used, must be >= 16. */
76962 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
76963 + Note that this field impacts the size of the buffer-prefix
76964 + (i.e. it pushes the data offset);
76965 + This field is irrelevant if DPAA_VERSION==10 */
76966 +} t_FmBufferPrefixContent;
76967 +
76968 +/**************************************************************************//**
76969 + @Description A structure of information about each of the external
76970 + buffer pools used by a port or storage-profile.
76971 +*//***************************************************************************/
76972 +typedef struct t_FmExtPoolParams {
76973 + uint8_t id; /**< External buffer pool id */
76974 + uint16_t size; /**< External buffer pool buffer size */
76975 +} t_FmExtPoolParams;
76976 +
76977 +/**************************************************************************//**
76978 + @Description A structure for informing the driver about the external
76979 + buffer pools allocated in the BM and used by a port or a
76980 + storage-profile.
76981 +*//***************************************************************************/
76982 +typedef struct t_FmExtPools {
76983 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
76984 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76985 + /**< Parameters for each port */
76986 +} t_FmExtPools;
76987 +
76988 +/**************************************************************************//**
76989 + @Description A structure for defining backup BM Pools.
76990 +*//***************************************************************************/
76991 +typedef struct t_FmBackupBmPools {
76992 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
76993 + must be smaller than the total number of
76994 + pools defined for the specified port.*/
76995 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76996 + /**< numOfBackupPools pool id's, specifying which
76997 + pools should be used only as backup. Pool
76998 + id's specified here must be a subset of the
76999 + pools used by the specified port.*/
77000 +} t_FmBackupBmPools;
77001 +
77002 +/**************************************************************************//**
77003 + @Description A structure for defining BM pool depletion criteria
77004 +*//***************************************************************************/
77005 +typedef struct t_FmBufPoolDepletion {
77006 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
77007 + a number of pools (all together!) are depleted */
77008 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
77009 + pause frames transmission. */
77010 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
77011 + /**< For each pool, TRUE if it should be considered for
77012 + depletion (Note - this pool must be used by this port!). */
77013 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
77014 + a single-pool is depleted; */
77015 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
77016 + /**< For each pool, TRUE if it should be considered for
77017 + depletion (Note - this pool must be used by this port!) */
77018 +#if (DPAA_VERSION >= 11)
77019 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
77020 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
77021 +#endif /* (DPAA_VERSION >= 11) */
77022 +} t_FmBufPoolDepletion;
77023 +
77024 +/**************************************************************************//**
77025 + @Description A Structure for defining Ucode patch for loading.
77026 +*//***************************************************************************/
77027 +typedef struct t_FmFirmwareParams {
77028 + uint32_t size; /**< Size of uCode */
77029 + uint32_t *p_Code; /**< A pointer to the uCode */
77030 +} t_FmFirmwareParams;
77031 +
77032 +/**************************************************************************//**
77033 + @Description A Structure for defining FM initialization parameters
77034 +*//***************************************************************************/
77035 +typedef struct t_FmParams {
77036 + uint8_t fmId; /**< Index of the FM */
77037 + uint8_t guestId; /**< FM Partition Id */
77038 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
77039 + this field is optional when the FM runs in "guest-mode"
77040 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
77041 + use the memory-map instead of calling the IPC where possible;
77042 + NOTE that this should include ALL common registers of the FM including
77043 + the PCD registers area (i.e. until the VSP pages - 880KB). */
77044 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
77045 + to be used by the FM. */
77046 + uint16_t fmClkFreq; /**< In Mhz;
77047 + Relevant when FM not runs in "guest-mode". */
77048 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
77049 + when fmMacClkRatio = 0, ratio is 2:1
77050 + when fmMacClkRatio = 1, ratio is 1:1 */
77051 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
77052 + Relevant when FM not runs in "guest-mode". */
77053 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
77054 + Relevant when FM not runs in "guest-mode". */
77055 + t_Handle h_App; /**< A handle to an application layer object; This handle will
77056 + be passed by the driver upon calling the above callbacks;
77057 + Relevant when FM not runs in "guest-mode". */
77058 + int irq; /**< FM interrupt source for normal events;
77059 + Relevant when FM not runs in "guest-mode". */
77060 + int errIrq; /**< FM interrupt source for errors;
77061 + Relevant when FM not runs in "guest-mode". */
77062 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
77063 + Relevant when FM not runs in "guest-mode". */
77064 +
77065 +#if (DPAA_VERSION >= 11)
77066 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
77067 + i.e. up to 24KB, depending on the specific chip. */
77068 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
77069 + NOTE: this parameter relevant only when working with multiple partitions. */
77070 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
77071 + NOTE: this parameter relevant only when working with multiple partitions. */
77072 +#endif /* (DPAA_VERSION >= 11) */
77073 +} t_FmParams;
77074 +
77075 +
77076 +/**************************************************************************//**
77077 + @Function FM_Config
77078 +
77079 + @Description Creates the FM module and returns its handle (descriptor).
77080 + This descriptor must be passed as first parameter to all other
77081 + FM function calls.
77082 +
77083 + No actual initialization or configuration of FM hardware is
77084 + done by this routine. All FM parameters get default values that
77085 + may be changed by calling one or more of the advance config routines.
77086 +
77087 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
77088 +
77089 + @Return A handle to the FM object, or NULL for Failure.
77090 +*//***************************************************************************/
77091 +t_Handle FM_Config(t_FmParams *p_FmParams);
77092 +
77093 +/**************************************************************************//**
77094 + @Function FM_Init
77095 +
77096 + @Description Initializes the FM module by defining the software structure
77097 + and configuring the hardware registers.
77098 +
77099 + @Param[in] h_Fm - FM module descriptor
77100 +
77101 + @Return E_OK on success; Error code otherwise.
77102 +*//***************************************************************************/
77103 +t_Error FM_Init(t_Handle h_Fm);
77104 +
77105 +/**************************************************************************//**
77106 + @Function FM_Free
77107 +
77108 + @Description Frees all resources that were assigned to FM module.
77109 +
77110 + Calling this routine invalidates the descriptor.
77111 +
77112 + @Param[in] h_Fm - FM module descriptor
77113 +
77114 + @Return E_OK on success; Error code otherwise.
77115 +*//***************************************************************************/
77116 +t_Error FM_Free(t_Handle h_Fm);
77117 +
77118 +
77119 +/**************************************************************************//**
77120 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
77121 +
77122 + @Description Advanced configuration routines are optional routines that may
77123 + be called in order to change the default driver settings.
77124 +
77125 + Note: Advanced configuration routines are not available for guest partition.
77126 + @{
77127 +*//***************************************************************************/
77128 +
77129 +/**************************************************************************//**
77130 + @Description Enum for selecting DMA debug mode
77131 +*//***************************************************************************/
77132 +typedef enum e_FmDmaDbgCntMode {
77133 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
77134 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
77135 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
77136 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
77137 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
77138 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
77139 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
77140 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
77141 +} e_FmDmaDbgCntMode;
77142 +
77143 +/**************************************************************************//**
77144 + @Description Enum for selecting DMA Cache Override
77145 +*//***************************************************************************/
77146 +typedef enum e_FmDmaCacheOverride {
77147 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
77148 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
77149 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
77150 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
77151 +} e_FmDmaCacheOverride;
77152 +
77153 +/**************************************************************************//**
77154 + @Description Enum for selecting DMA External Bus Priority
77155 +*//***************************************************************************/
77156 +typedef enum e_FmDmaExtBusPri {
77157 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
77158 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
77159 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
77160 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
77161 +} e_FmDmaExtBusPri;
77162 +
77163 +/**************************************************************************//**
77164 + @Description Enum for choosing the field that will be output on AID
77165 +*//***************************************************************************/
77166 +typedef enum e_FmDmaAidMode {
77167 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
77168 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
77169 +} e_FmDmaAidMode;
77170 +
77171 +/**************************************************************************//**
77172 + @Description Enum for selecting FPM Catastrophic error behavior
77173 +*//***************************************************************************/
77174 +typedef enum e_FmCatastrophicErr {
77175 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
77176 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
77177 +} e_FmCatastrophicErr;
77178 +
77179 +/**************************************************************************//**
77180 + @Description Enum for selecting FPM DMA Error behavior
77181 +*//***************************************************************************/
77182 +typedef enum e_FmDmaErr {
77183 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
77184 + error (e_FmCatastrophicErr)*/
77185 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
77186 +} e_FmDmaErr;
77187 +
77188 +/**************************************************************************//**
77189 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
77190 +*//***************************************************************************/
77191 +typedef enum e_FmDmaEmergencyLevel {
77192 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
77193 + e_FM_DMA_EM_SOS /**< SOS emergency */
77194 +} e_FmDmaEmergencyLevel;
77195 +
77196 +/**************************************************************************//**
77197 + @Collection Enum for selecting DMA Emergency options
77198 +*//***************************************************************************/
77199 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
77200 +
77201 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
77202 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
77203 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
77204 +/* @} */
77205 +
77206 +/**************************************************************************//**
77207 + @Description A structure for defining DMA emergency level
77208 +*//***************************************************************************/
77209 +typedef struct t_FmDmaEmergency {
77210 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
77211 + should be enabled */
77212 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
77213 +} t_FmDmaEmergency;
77214 +
77215 +/**************************************************************************//*
77216 + @Description structure for defining FM threshold
77217 +*//***************************************************************************/
77218 +typedef struct t_FmThresholds {
77219 + uint8_t dispLimit; /**< The number of times a frames may
77220 + be passed in the FM before assumed to
77221 + be looping. */
77222 + uint8_t prsDispTh; /**< This is the number pf packets that may be
77223 + queued in the parser dispatch queue*/
77224 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
77225 + queued in the policer dispatch queue*/
77226 + uint8_t kgDispTh; /**< This is the number pf packets that may be
77227 + queued in the keygen dispatch queue*/
77228 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
77229 + queued in the BMI dispatch queue*/
77230 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
77231 + queued in the QMI enqueue dispatch queue*/
77232 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
77233 + queued in the QMI dequeue dispatch queue*/
77234 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
77235 + queued in fmCtl1 dispatch queue*/
77236 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
77237 + queued in fmCtl2 dispatch queue*/
77238 +} t_FmThresholds;
77239 +
77240 +/**************************************************************************//*
77241 + @Description structure for defining DMA thresholds
77242 +*//***************************************************************************/
77243 +typedef struct t_FmDmaThresholds {
77244 + uint8_t assertEmergency; /**< When this value is reached,
77245 + assert emergency (Threshold)*/
77246 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
77247 + until this value is reached (Hystheresis) */
77248 +} t_FmDmaThresholds;
77249 +
77250 +/**************************************************************************//**
77251 + @Function t_FmResetOnInitOverrideCallback
77252 +
77253 + @Description FMan specific reset on init user callback routine,
77254 + will be used to override the standard FMan reset on init procedure
77255 +
77256 + @Param[in] h_Fm - FMan handler
77257 +*//***************************************************************************/
77258 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
77259 +
77260 +/**************************************************************************//**
77261 + @Function FM_ConfigResetOnInit
77262 +
77263 + @Description Define whether to reset the FM before initialization.
77264 + Change the default configuration [DEFAULT_resetOnInit].
77265 +
77266 + @Param[in] h_Fm A handle to an FM Module.
77267 + @Param[in] enable When TRUE, FM will be reset before any initialization.
77268 +
77269 + @Return E_OK on success; Error code otherwise.
77270 +
77271 + @Cautions Allowed only following FM_Config() and before FM_Init().
77272 + This routine should NOT be called from guest-partition
77273 + (i.e. guestId != NCSW_MASTER_ID)
77274 +*//***************************************************************************/
77275 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
77276 +
77277 +/**************************************************************************//**
77278 + @Function FM_ConfigResetOnInitOverrideCallback
77279 +
77280 + @Description Define a special reset of FM before initialization.
77281 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
77282 +
77283 + @Param[in] h_Fm A handle to an FM Module.
77284 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
77285 +
77286 + @Return E_OK on success; Error code otherwise.
77287 +
77288 + @Cautions Allowed only following FM_Config() and before FM_Init().
77289 + This routine should NOT be called from guest-partition
77290 + (i.e. guestId != NCSW_MASTER_ID)
77291 +*//***************************************************************************/
77292 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
77293 +
77294 +/**************************************************************************//**
77295 + @Function FM_ConfigTotalFifoSize
77296 +
77297 + @Description Define Total FIFO size for the whole FM.
77298 + Calling this routine changes the total Fifo size in the internal driver
77299 + data base from its default configuration [DEFAULT_totalFifoSize]
77300 +
77301 + @Param[in] h_Fm A handle to an FM Module.
77302 + @Param[in] totalFifoSize The selected new value.
77303 +
77304 + @Return E_OK on success; Error code otherwise.
77305 +
77306 + @Cautions Allowed only following FM_Config() and before FM_Init().
77307 + This routine should NOT be called from guest-partition
77308 + (i.e. guestId != NCSW_MASTER_ID)
77309 +*//***************************************************************************/
77310 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
77311 +
77312 + /**************************************************************************//**
77313 + @Function FM_ConfigDmaCacheOverride
77314 +
77315 + @Description Define cache override mode.
77316 + Calling this routine changes the cache override mode
77317 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
77318 +
77319 + @Param[in] h_Fm A handle to an FM Module.
77320 + @Param[in] cacheOverride The selected new value.
77321 +
77322 + @Return E_OK on success; Error code otherwise.
77323 +
77324 + @Cautions Allowed only following FM_Config() and before FM_Init().
77325 + This routine should NOT be called from guest-partition
77326 + (i.e. guestId != NCSW_MASTER_ID)
77327 +*//***************************************************************************/
77328 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
77329 +
77330 +/**************************************************************************//**
77331 + @Function FM_ConfigDmaAidOverride
77332 +
77333 + @Description Define DMA AID override mode.
77334 + Calling this routine changes the AID override mode
77335 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
77336 +
77337 + @Param[in] h_Fm A handle to an FM Module.
77338 + @Param[in] aidOverride The selected new value.
77339 +
77340 + @Return E_OK on success; Error code otherwise.
77341 +
77342 + @Cautions Allowed only following FM_Config() and before FM_Init().
77343 + This routine should NOT be called from guest-partition
77344 + (i.e. guestId != NCSW_MASTER_ID)
77345 +*//***************************************************************************/
77346 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77347 +
77348 +/**************************************************************************//**
77349 + @Function FM_ConfigDmaAidMode
77350 +
77351 + @Description Define DMA AID mode.
77352 + Calling this routine changes the AID mode in the internal
77353 + driver data base from its default configuration [DEFAULT_aidMode]
77354 +
77355 + @Param[in] h_Fm A handle to an FM Module.
77356 + @Param[in] aidMode The selected new value.
77357 +
77358 + @Return E_OK on success; Error code otherwise.
77359 +
77360 + @Cautions Allowed only following FM_Config() and before FM_Init().
77361 + This routine should NOT be called from guest-partition
77362 + (i.e. guestId != NCSW_MASTER_ID)
77363 +*//***************************************************************************/
77364 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77365 +
77366 +/**************************************************************************//**
77367 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77368 +
77369 + @Description Define DMA AXI number of beats.
77370 + Calling this routine changes the AXI number of beats in the internal
77371 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77372 +
77373 + @Param[in] h_Fm A handle to an FM Module.
77374 + @Param[in] axiDbgNumOfBeats The selected new value.
77375 +
77376 + @Return E_OK on success; Error code otherwise.
77377 +
77378 + @Cautions Allowed only following FM_Config() and before FM_Init().
77379 + This routine should NOT be called from guest-partition
77380 + (i.e. guestId != NCSW_MASTER_ID)
77381 +*//***************************************************************************/
77382 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77383 +
77384 +/**************************************************************************//**
77385 + @Function FM_ConfigDmaCamNumOfEntries
77386 +
77387 + @Description Define number of CAM entries.
77388 + Calling this routine changes the number of CAM entries in the internal
77389 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77390 +
77391 + @Param[in] h_Fm A handle to an FM Module.
77392 + @Param[in] numOfEntries The selected new value.
77393 +
77394 + @Return E_OK on success; Error code otherwise.
77395 +
77396 + @Cautions Allowed only following FM_Config() and before FM_Init().
77397 + This routine should NOT be called from guest-partition
77398 + (i.e. guestId != NCSW_MASTER_ID)
77399 +*//***************************************************************************/
77400 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77401 +
77402 +/**************************************************************************//**
77403 + @Function FM_ConfigEnableCounters
77404 +
77405 + @Description Obsolete, always return E_OK.
77406 +
77407 + @Param[in] h_Fm A handle to an FM Module.
77408 +
77409 + @Return E_OK on success; Error code otherwise.
77410 +*//***************************************************************************/
77411 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77412 +
77413 +/**************************************************************************//**
77414 + @Function FM_ConfigDmaDbgCounter
77415 +
77416 + @Description Define DMA debug counter.
77417 + Calling this routine changes the number of the DMA debug counter in the internal
77418 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77419 +
77420 + @Param[in] h_Fm A handle to an FM Module.
77421 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
77422 +
77423 + @Return E_OK on success; Error code otherwise.
77424 +
77425 + @Cautions Allowed only following FM_Config() and before FM_Init().
77426 + This routine should NOT be called from guest-partition
77427 + (i.e. guestId != NCSW_MASTER_ID)
77428 +*//***************************************************************************/
77429 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77430 +
77431 +/**************************************************************************//**
77432 + @Function FM_ConfigDmaStopOnBusErr
77433 +
77434 + @Description Define bus error behavior.
77435 + Calling this routine changes the bus error behavior definition
77436 + in the internal driver data base from its default
77437 + configuration [DEFAULT_dmaStopOnBusError].
77438 +
77439 + @Param[in] h_Fm A handle to an FM Module.
77440 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77441 +
77442 + @Return E_OK on success; Error code otherwise.
77443 +
77444 + @Cautions Allowed only following FM_Config() and before FM_Init().
77445 + Only if bus error is enabled.
77446 + This routine should NOT be called from guest-partition
77447 + (i.e. guestId != NCSW_MASTER_ID)
77448 +*//***************************************************************************/
77449 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77450 +
77451 +/**************************************************************************//**
77452 + @Function FM_ConfigDmaEmergency
77453 +
77454 + @Description Define DMA emergency.
77455 + Calling this routine changes the DMA emergency definition
77456 + in the internal driver data base from its default
77457 + configuration where's it's disabled.
77458 +
77459 + @Param[in] h_Fm A handle to an FM Module.
77460 + @Param[in] p_Emergency An OR mask of all required options.
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 +*//***************************************************************************/
77468 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77469 +
77470 +/**************************************************************************//**
77471 + @Function FM_ConfigDmaErr
77472 +
77473 + @Description DMA error treatment.
77474 + Calling this routine changes the DMA error treatment
77475 + in the internal driver data base from its default
77476 + configuration [DEFAULT_dmaErr].
77477 +
77478 + @Param[in] h_Fm A handle to an FM Module.
77479 + @Param[in] dmaErr The selected new choice.
77480 +
77481 + @Return E_OK on success; Error code otherwise.
77482 +
77483 + @Cautions Allowed only following FM_Config() and before FM_Init().
77484 + This routine should NOT be called from guest-partition
77485 + (i.e. guestId != NCSW_MASTER_ID)
77486 +*//***************************************************************************/
77487 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77488 +
77489 +/**************************************************************************//**
77490 + @Function FM_ConfigCatastrophicErr
77491 +
77492 + @Description Define FM behavior on catastrophic error.
77493 + Calling this routine changes the FM behavior on catastrophic
77494 + error in the internal driver data base from its default
77495 + [DEFAULT_catastrophicErr].
77496 +
77497 + @Param[in] h_Fm A handle to an FM Module.
77498 + @Param[in] catastrophicErr The selected new choice.
77499 +
77500 + @Return E_OK on success; Error code otherwise.
77501 +
77502 + @Cautions Allowed only following FM_Config() and before FM_Init().
77503 + This routine should NOT be called from guest-partition
77504 + (i.e. guestId != NCSW_MASTER_ID)
77505 +*//***************************************************************************/
77506 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77507 +
77508 +/**************************************************************************//**
77509 + @Function FM_ConfigEnableMuramTestMode
77510 +
77511 + @Description Enable MURAM test mode.
77512 + Calling this routine changes the internal driver data base
77513 + from its default selection of test mode where it's disabled.
77514 + This routine is only avaiable on old FM revisions (FMan v2).
77515 +
77516 + @Param[in] h_Fm A handle to an FM Module.
77517 +
77518 + @Return E_OK on success; Error code otherwise.
77519 +
77520 + @Cautions Allowed only following FM_Config() and before FM_Init().
77521 + This routine should NOT be called from guest-partition
77522 + (i.e. guestId != NCSW_MASTER_ID)
77523 +*//***************************************************************************/
77524 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77525 +
77526 +/**************************************************************************//**
77527 + @Function FM_ConfigEnableIramTestMode
77528 +
77529 + @Description Enable IRAM test mode.
77530 + Calling this routine changes the internal driver data base
77531 + from its default selection of test mode where it's disabled.
77532 + This routine is only avaiable on old FM revisions (FMan v2).
77533 +
77534 + @Param[in] h_Fm A handle to an FM Module.
77535 +
77536 + @Return E_OK on success; Error code otherwise.
77537 +
77538 + @Cautions Allowed only following FM_Config() and before FM_Init().
77539 + This routine should NOT be called from guest-partition
77540 + (i.e. guestId != NCSW_MASTER_ID)
77541 +*//***************************************************************************/
77542 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77543 +
77544 +/**************************************************************************//**
77545 + @Function FM_ConfigHaltOnExternalActivation
77546 +
77547 + @Description Define FM behavior on external halt activation.
77548 + Calling this routine changes the FM behavior on external halt
77549 + activation in the internal driver data base from its default
77550 + [DEFAULT_haltOnExternalActivation].
77551 +
77552 + @Param[in] h_Fm A handle to an FM Module.
77553 + @Param[in] enable TRUE to enable halt on external halt
77554 + activation.
77555 +
77556 + @Return E_OK on success; Error code otherwise.
77557 +
77558 + @Cautions Allowed only following FM_Config() and before FM_Init().
77559 + This routine should NOT be called from guest-partition
77560 + (i.e. guestId != NCSW_MASTER_ID)
77561 +*//***************************************************************************/
77562 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77563 +
77564 +/**************************************************************************//**
77565 + @Function FM_ConfigHaltOnUnrecoverableEccError
77566 +
77567 + @Description Define FM behavior on external halt activation.
77568 + Calling this routine changes the FM behavior on unrecoverable
77569 + ECC error in the internal driver data base from its default
77570 + [DEFAULT_haltOnUnrecoverableEccError].
77571 + This routine is only avaiable on old FM revisions (FMan v2).
77572 +
77573 + @Param[in] h_Fm A handle to an FM Module.
77574 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
77575 +
77576 + @Return E_OK on success; Error code otherwise.
77577 +
77578 + @Cautions Allowed only following FM_Config() and before FM_Init().
77579 + This routine should NOT be called from guest-partition
77580 + (i.e. guestId != NCSW_MASTER_ID)
77581 +*//***************************************************************************/
77582 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77583 +
77584 +/**************************************************************************//**
77585 + @Function FM_ConfigException
77586 +
77587 + @Description Define FM exceptions.
77588 + Calling this routine changes the exceptions defaults in the
77589 + internal driver data base where all exceptions are enabled.
77590 +
77591 + @Param[in] h_Fm A handle to an FM Module.
77592 + @Param[in] exception The exception to be selected.
77593 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77594 +
77595 + @Return E_OK on success; Error code otherwise.
77596 +
77597 + @Cautions Allowed only following FM_Config() and before FM_Init().
77598 + This routine should NOT be called from guest-partition
77599 + (i.e. guestId != NCSW_MASTER_ID)
77600 +*//***************************************************************************/
77601 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77602 +
77603 +/**************************************************************************//**
77604 + @Function FM_ConfigExternalEccRamsEnable
77605 +
77606 + @Description Select external ECC enabling.
77607 + Calling this routine changes the ECC enabling control in the internal
77608 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77609 + When this option is enabled Rams ECC enabling is not effected
77610 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77611 +
77612 + @Param[in] h_Fm A handle to an FM Module.
77613 + @Param[in] enable TRUE to enable this option.
77614 +
77615 + @Return E_OK on success; Error code otherwise.
77616 +
77617 + @Cautions Allowed only following FM_Config() and before FM_Init().
77618 + This routine should NOT be called from guest-partition
77619 + (i.e. guestId != NCSW_MASTER_ID)
77620 +*//***************************************************************************/
77621 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77622 +
77623 +/**************************************************************************//**
77624 + @Function FM_ConfigTnumAgingPeriod
77625 +
77626 + @Description Define Tnum aging period.
77627 + Calling this routine changes the Tnum aging of dequeue TNUMs
77628 + in the QMI in the internal driver data base from its default
77629 + [DEFAULT_tnumAgingPeriod].
77630 +
77631 + @Param[in] h_Fm A handle to an FM Module.
77632 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77633 + Note that period is recalculated in units of
77634 + 64 FM clocks. Driver will pick the closest
77635 + possible period.
77636 +
77637 + @Return E_OK on success; Error code otherwise.
77638 +
77639 + @Cautions Allowed only following FM_Config() and before FM_Init().
77640 + This routine should NOT be called from guest-partition
77641 + (i.e. guestId != NCSW_MASTER_ID)
77642 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77643 + allowed.
77644 +*//***************************************************************************/
77645 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77646 +
77647 +/**************************************************************************//*
77648 + @Function FM_ConfigDmaEmergencySmoother
77649 +
77650 + @Description Define DMA emergency smoother.
77651 + Calling this routine changes the definition of the minimum
77652 + amount of DATA beats transferred on the AXI READ and WRITE
77653 + ports before lowering the emergency level.
77654 + By default smoother is disabled.
77655 +
77656 + @Param[in] h_Fm A handle to an FM Module.
77657 + @Param[in] emergencyCnt emergency switching counter.
77658 +
77659 + @Return E_OK on success; Error code otherwise.
77660 +
77661 + @Cautions Allowed only following FM_Config() and before FM_Init().
77662 + This routine should NOT be called from guest-partition
77663 + (i.e. guestId != NCSW_MASTER_ID)
77664 +*//***************************************************************************/
77665 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77666 +
77667 +/**************************************************************************//*
77668 + @Function FM_ConfigThresholds
77669 +
77670 + @Description Calling this routine changes the internal driver data base
77671 + from its default FM threshold configuration:
77672 + dispLimit: [DEFAULT_dispLimit]
77673 + prsDispTh: [DEFAULT_prsDispTh]
77674 + plcrDispTh: [DEFAULT_plcrDispTh]
77675 + kgDispTh: [DEFAULT_kgDispTh]
77676 + bmiDispTh: [DEFAULT_bmiDispTh]
77677 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77678 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77679 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77680 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77681 +
77682 +
77683 + @Param[in] h_Fm A handle to an FM Module.
77684 + @Param[in] p_FmThresholds A structure of threshold parameters.
77685 +
77686 + @Return E_OK on success; Error code otherwise.
77687 +
77688 + @Cautions Allowed only following FM_Config() and before FM_Init().
77689 + This routine should NOT be called from guest-partition
77690 + (i.e. guestId != NCSW_MASTER_ID)
77691 +*//***************************************************************************/
77692 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77693 +
77694 +/**************************************************************************//*
77695 + @Function FM_ConfigDmaSosEmergencyThreshold
77696 +
77697 + @Description Calling this routine changes the internal driver data base
77698 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77699 +
77700 + @Param[in] h_Fm A handle to an FM Module.
77701 + @Param[in] dmaSosEmergency The selected new value.
77702 +
77703 + @Return E_OK on success; Error code otherwise.
77704 +
77705 + @Cautions Allowed only following FM_Config() and before FM_Init().
77706 + This routine should NOT be called from guest-partition
77707 + (i.e. guestId != NCSW_MASTER_ID)
77708 +*//***************************************************************************/
77709 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77710 +
77711 +/**************************************************************************//*
77712 + @Function FM_ConfigDmaWriteBufThresholds
77713 +
77714 + @Description Calling this routine changes the internal driver data base
77715 + from its default configuration of DMA write buffer threshold
77716 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77717 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77718 + This routine is only avaiable on old FM revisions (FMan v2).
77719 +
77720 + @Param[in] h_Fm A handle to an FM Module.
77721 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77722 + When 'assertEmergency' value is reached, emergency is asserted,
77723 + then it is held until 'clearEmergency' value is reached.
77724 +
77725 + @Return E_OK on success; Error code otherwise.
77726 +
77727 + @Cautions Allowed only following FM_Config() and before FM_Init().
77728 + This routine should NOT be called from guest-partition
77729 + (i.e. guestId != NCSW_MASTER_ID)
77730 +*//***************************************************************************/
77731 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77732 +
77733 + /**************************************************************************//*
77734 + @Function FM_ConfigDmaCommQThresholds
77735 +
77736 + @Description Calling this routine changes the internal driver data base
77737 + from its default configuration of DMA command queue threshold
77738 + assertEmergency: [DEFAULT_dmaCommQLow]
77739 + clearEmergency: [DEFAULT_dmaCommQHigh]
77740 +
77741 + @Param[in] h_Fm A handle to an FM Module.
77742 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77743 + When 'assertEmergency' value is reached, emergency is asserted,
77744 + then it is held until 'clearEmergency' value is reached..
77745 +
77746 + @Return E_OK on success; Error code otherwise.
77747 +
77748 + @Cautions Allowed only following FM_Config() and before FM_Init().
77749 + This routine should NOT be called from guest-partition
77750 + (i.e. guestId != NCSW_MASTER_ID)
77751 +*//***************************************************************************/
77752 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77753 +
77754 +/**************************************************************************//*
77755 + @Function FM_ConfigDmaReadBufThresholds
77756 +
77757 + @Description Calling this routine changes the internal driver data base
77758 + from its default configuration of DMA read buffer threshold
77759 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77760 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77761 + This routine is only avaiable on old FM revisions (FMan v2).
77762 +
77763 + @Param[in] h_Fm A handle to an FM Module.
77764 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77765 + When 'assertEmergency' value is reached, emergency is asserted,
77766 + then it is held until 'clearEmergency' value is reached..
77767 +
77768 + @Return E_OK on success; Error code otherwise.
77769 +
77770 + @Cautions Allowed only following FM_Config() and before FM_Init().
77771 + This routine should NOT be called from guest-partition
77772 + (i.e. guestId != NCSW_MASTER_ID)
77773 +*//***************************************************************************/
77774 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77775 +
77776 +/**************************************************************************//*
77777 + @Function FM_ConfigDmaWatchdog
77778 +
77779 + @Description Calling this routine changes the internal driver data base
77780 + from its default watchdog configuration, which is disabled
77781 + [DEFAULT_dmaWatchdog].
77782 +
77783 + @Param[in] h_Fm A handle to an FM Module.
77784 + @Param[in] watchDogValue The selected new value - in microseconds.
77785 +
77786 + @Return E_OK on success; Error code otherwise.
77787 +
77788 + @Cautions Allowed only following FM_Config() and before FM_Init().
77789 + This routine should NOT be called from guest-partition
77790 + (i.e. guestId != NCSW_MASTER_ID)
77791 +*//***************************************************************************/
77792 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77793 +
77794 +/** @} */ /* end of FM_advanced_init_grp group */
77795 +/** @} */ /* end of FM_init_grp group */
77796 +
77797 +
77798 +/**************************************************************************//**
77799 + @Group FM_runtime_control_grp FM Runtime Control Unit
77800 +
77801 + @Description FM Runtime control unit API functions, definitions and enums.
77802 + The FM driver provides a set of control routines.
77803 + These routines may only be called after the module was fully
77804 + initialized (both configuration and initialization routines were
77805 + called). They are typically used to get information from hardware
77806 + (status, counters/statistics, revision etc.), to modify a current
77807 + state or to force/enable a required action. Run-time control may
77808 + be called whenever necessary and as many times as needed.
77809 + @{
77810 +*//***************************************************************************/
77811 +
77812 +/**************************************************************************//**
77813 + @Collection General FM defines.
77814 +*//***************************************************************************/
77815 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77816 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77817 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77818 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77819 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77820 +/* @} */
77821 +
77822 +/**************************************************************************//*
77823 + @Description A Structure for Port bandwidth requirement. Port is identified
77824 + by type and relative id.
77825 +*//***************************************************************************/
77826 +typedef struct t_FmPortBandwidth {
77827 + e_FmPortType type; /**< FM port type */
77828 + uint8_t relativePortId; /**< Type relative port id */
77829 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77830 +} t_FmPortBandwidth;
77831 +
77832 +/**************************************************************************//*
77833 + @Description A Structure containing an array of Port bandwidth requirements.
77834 + The user should state the ports requiring bandwidth in terms of
77835 + percentage - i.e. all port's bandwidths in the array must add
77836 + up to 100.
77837 +*//***************************************************************************/
77838 +typedef struct t_FmPortsBandwidthParams {
77839 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77840 + number of valid entries in the array below */
77841 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77842 + /**< for each port, it's bandwidth (all port's
77843 + bandwidths must add up to 100.*/
77844 +} t_FmPortsBandwidthParams;
77845 +
77846 +/**************************************************************************//**
77847 + @Description DMA Emergency control on MURAM
77848 +*//***************************************************************************/
77849 +typedef enum e_FmDmaMuramPort {
77850 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77851 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77852 +} e_FmDmaMuramPort;
77853 +
77854 +/**************************************************************************//**
77855 + @Description Enum for defining FM counters
77856 +*//***************************************************************************/
77857 +typedef enum e_FmCounters {
77858 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77859 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77860 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77861 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77862 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77863 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77864 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77865 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77866 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77867 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77868 +} e_FmCounters;
77869 +
77870 +/**************************************************************************//**
77871 + @Description A Structure for returning FM revision information
77872 +*//***************************************************************************/
77873 +typedef struct t_FmRevisionInfo {
77874 + uint8_t majorRev; /**< Major revision */
77875 + uint8_t minorRev; /**< Minor revision */
77876 +} t_FmRevisionInfo;
77877 +
77878 +/**************************************************************************//**
77879 + @Description A Structure for returning FM ctrl code revision information
77880 +*//***************************************************************************/
77881 +typedef struct t_FmCtrlCodeRevisionInfo {
77882 + uint16_t packageRev; /**< Package revision */
77883 + uint8_t majorRev; /**< Major revision */
77884 + uint8_t minorRev; /**< Minor revision */
77885 +} t_FmCtrlCodeRevisionInfo;
77886 +
77887 +/**************************************************************************//**
77888 + @Description A Structure for defining DMA status
77889 +*//***************************************************************************/
77890 +typedef struct t_FmDmaStatus {
77891 + bool cmqNotEmpty; /**< Command queue is not empty */
77892 + bool busError; /**< Bus error occurred */
77893 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
77894 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
77895 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
77896 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
77897 +} t_FmDmaStatus;
77898 +
77899 +/**************************************************************************//**
77900 + @Description A Structure for obtaining FM controller monitor values
77901 +*//***************************************************************************/
77902 +typedef struct t_FmCtrlMon {
77903 + uint8_t percentCnt[2]; /**< Percentage value */
77904 +} t_FmCtrlMon;
77905 +
77906 +
77907 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
77908 +/**************************************************************************//**
77909 + @Function FM_DumpRegs
77910 +
77911 + @Description Dumps all FM registers
77912 +
77913 + @Param[in] h_Fm A handle to an FM Module.
77914 +
77915 + @Return E_OK on success;
77916 +
77917 + @Cautions Allowed only following FM_Init().
77918 +*//***************************************************************************/
77919 +t_Error FM_DumpRegs(t_Handle h_Fm);
77920 +#endif /* (defined(DEBUG_ERRORS) && ... */
77921 +
77922 +/**************************************************************************//**
77923 + @Function FM_SetException
77924 +
77925 + @Description Calling this routine enables/disables the specified exception.
77926 +
77927 + @Param[in] h_Fm A handle to an FM Module.
77928 + @Param[in] exception The exception to be selected.
77929 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77930 +
77931 + @Return E_OK on success; Error code otherwise.
77932 +
77933 + @Cautions Allowed only following FM_Init().
77934 + This routine should NOT be called from guest-partition
77935 + (i.e. guestId != NCSW_MASTER_ID)
77936 +*//***************************************************************************/
77937 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77938 +
77939 +/**************************************************************************//**
77940 + @Function FM_EnableRamsEcc
77941 +
77942 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77943 + MURAM, Parser, Keygen, Policer, etc.
77944 + Note:
77945 + If FM_ConfigExternalEccRamsEnable was called to enable external
77946 + setting of ECC, this routine effects IRAM ECC only.
77947 + This routine is also called by the driver if an ECC exception is
77948 + enabled.
77949 +
77950 + @Param[in] h_Fm A handle to an FM Module.
77951 +
77952 + @Return E_OK on success; Error code otherwise.
77953 +
77954 + @Cautions Allowed only following FM_Config() and before FM_Init().
77955 + This routine should NOT be called from guest-partition
77956 + (i.e. guestId != NCSW_MASTER_ID)
77957 +*//***************************************************************************/
77958 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
77959 +
77960 +/**************************************************************************//**
77961 + @Function FM_DisableRamsEcc
77962 +
77963 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77964 + MURAM, Parser, Keygen, Policer, etc.
77965 + Note:
77966 + If FM_ConfigExternalEccRamsEnable was called to enable external
77967 + setting of ECC, this routine effects IRAM ECC only.
77968 + In opposed to FM_EnableRamsEcc, this routine must be called
77969 + explicitly to disable all Rams ECC.
77970 +
77971 + @Param[in] h_Fm A handle to an FM Module.
77972 +
77973 + @Return E_OK on success; Error code otherwise.
77974 +
77975 + @Cautions Allowed only following FM_Config() and before FM_Init().
77976 + This routine should NOT be called from guest-partition
77977 + (i.e. guestId != NCSW_MASTER_ID)
77978 +*//***************************************************************************/
77979 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
77980 +
77981 +/**************************************************************************//**
77982 + @Function FM_GetRevision
77983 +
77984 + @Description Returns the FM revision
77985 +
77986 + @Param[in] h_Fm A handle to an FM Module.
77987 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
77988 +
77989 + @Return E_OK on success; Error code otherwise.
77990 +
77991 + @Cautions Allowed only following FM_Init().
77992 +*//***************************************************************************/
77993 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
77994 +
77995 +/**************************************************************************//**
77996 + @Function FM_GetFmanCtrlCodeRevision
77997 +
77998 + @Description Returns the Fman controller code revision
77999 +
78000 + @Param[in] h_Fm A handle to an FM Module.
78001 + @Param[out] p_RevisionInfo A structure of revision information parameters.
78002 +
78003 + @Return E_OK on success; Error code otherwise.
78004 +
78005 + @Cautions Allowed only following FM_Init().
78006 +*//***************************************************************************/
78007 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
78008 +
78009 +/**************************************************************************//**
78010 + @Function FM_GetCounter
78011 +
78012 + @Description Reads one of the FM counters.
78013 +
78014 + @Param[in] h_Fm A handle to an FM Module.
78015 + @Param[in] counter The requested counter.
78016 +
78017 + @Return Counter's current value.
78018 +
78019 + @Cautions Allowed only following FM_Init().
78020 + Note that it is user's responsibility to call this routine only
78021 + for enabled counters, and there will be no indication if a
78022 + disabled counter is accessed.
78023 +*//***************************************************************************/
78024 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
78025 +
78026 +/**************************************************************************//**
78027 + @Function FM_ModifyCounter
78028 +
78029 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
78030 +
78031 + @Param[in] h_Fm A handle to an FM Module.
78032 + @Param[in] counter The requested counter.
78033 + @Param[in] val The requested value to be written into the counter.
78034 +
78035 + @Return E_OK on success; Error code otherwise.
78036 +
78037 + @Cautions Allowed only following FM_Init().
78038 + This routine should NOT be called from guest-partition
78039 + (i.e. guestId != NCSW_MASTER_ID)
78040 +*//***************************************************************************/
78041 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
78042 +
78043 +/**************************************************************************//**
78044 + @Function FM_Resume
78045 +
78046 + @Description Release FM after halt FM command or after unrecoverable ECC error.
78047 +
78048 + @Param[in] h_Fm A handle to an FM Module.
78049 +
78050 + @Return E_OK on success; Error code otherwise.
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 +void FM_Resume(t_Handle h_Fm);
78057 +
78058 +/**************************************************************************//**
78059 + @Function FM_SetDmaEmergency
78060 +
78061 + @Description Manual emergency set
78062 +
78063 + @Param[in] h_Fm A handle to an FM Module.
78064 + @Param[in] muramPort MURAM direction select.
78065 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
78066 +
78067 + @Return None.
78068 +
78069 + @Cautions Allowed only following FM_Init().
78070 + This routine should NOT be called from guest-partition
78071 + (i.e. guestId != NCSW_MASTER_ID)
78072 +*//***************************************************************************/
78073 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
78074 +
78075 +/**************************************************************************//**
78076 + @Function FM_SetDmaExtBusPri
78077 +
78078 + @Description Set the DMA external bus priority
78079 +
78080 + @Param[in] h_Fm A handle to an FM Module.
78081 + @Param[in] pri External bus priority select
78082 +
78083 + @Return None.
78084 +
78085 + @Cautions Allowed only following FM_Init().
78086 + This routine should NOT be called from guest-partition
78087 + (i.e. guestId != NCSW_MASTER_ID)
78088 +*//***************************************************************************/
78089 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
78090 +
78091 +/**************************************************************************//**
78092 + @Function FM_GetDmaStatus
78093 +
78094 + @Description Reads the DMA current status
78095 +
78096 + @Param[in] h_Fm A handle to an FM Module.
78097 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
78098 +
78099 + @Cautions Allowed only following FM_Init().
78100 +*//***************************************************************************/
78101 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
78102 +
78103 +/**************************************************************************//**
78104 + @Function FM_ErrorIsr
78105 +
78106 + @Description FM interrupt-service-routine for errors.
78107 +
78108 + @Param[in] h_Fm A handle to an FM Module.
78109 +
78110 + @Return E_OK on success; E_EMPTY if no errors found in register, other
78111 + error code otherwise.
78112 +
78113 + @Cautions Allowed only following FM_Init().
78114 + This routine should NOT be called from guest-partition
78115 + (i.e. guestId != NCSW_MASTER_ID)
78116 +*//***************************************************************************/
78117 +t_Error FM_ErrorIsr(t_Handle h_Fm);
78118 +
78119 +/**************************************************************************//**
78120 + @Function FM_EventIsr
78121 +
78122 + @Description FM interrupt-service-routine for normal events.
78123 +
78124 + @Param[in] h_Fm A handle to an FM Module.
78125 +
78126 + @Cautions Allowed only following FM_Init().
78127 + This routine should NOT be called from guest-partition
78128 + (i.e. guestId != NCSW_MASTER_ID)
78129 +*//***************************************************************************/
78130 +void FM_EventIsr(t_Handle h_Fm);
78131 +
78132 +/**************************************************************************//**
78133 + @Function FM_GetSpecialOperationCoding
78134 +
78135 + @Description Return a specific coding according to the input mask.
78136 +
78137 + @Param[in] h_Fm A handle to an FM Module.
78138 + @Param[in] spOper special operation mask.
78139 + @Param[out] p_SpOperCoding special operation code.
78140 +
78141 + @Return E_OK on success; Error code otherwise.
78142 +
78143 + @Cautions Allowed only following FM_Init().
78144 +*//***************************************************************************/
78145 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
78146 + fmSpecialOperations_t spOper,
78147 + uint8_t *p_SpOperCoding);
78148 +
78149 +/**************************************************************************//**
78150 + @Function FM_CtrlMonStart
78151 +
78152 + @Description Start monitoring utilization of all available FM controllers.
78153 +
78154 + In order to obtain FM controllers utilization the following sequence
78155 + should be used:
78156 + -# FM_CtrlMonStart()
78157 + -# FM_CtrlMonStop()
78158 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78159 +
78160 + @Param[in] h_Fm A handle to an FM Module.
78161 +
78162 + @Return E_OK on success; Error code otherwise.
78163 +
78164 + @Cautions Allowed only following FM_Init().
78165 + This routine should NOT be called from guest-partition
78166 + (i.e. guestId != NCSW_MASTER_ID).
78167 +*//***************************************************************************/
78168 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
78169 +
78170 +/**************************************************************************//**
78171 + @Function FM_CtrlMonStop
78172 +
78173 + @Description Stop monitoring utilization of all available FM controllers.
78174 +
78175 + In order to obtain FM controllers utilization the following sequence
78176 + should be used:
78177 + -# FM_CtrlMonStart()
78178 + -# FM_CtrlMonStop()
78179 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78180 +
78181 + @Param[in] h_Fm A handle to an FM Module.
78182 +
78183 + @Return E_OK on success; Error code otherwise.
78184 +
78185 + @Cautions Allowed only following FM_Init().
78186 + This routine should NOT be called from guest-partition
78187 + (i.e. guestId != NCSW_MASTER_ID).
78188 +*//***************************************************************************/
78189 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
78190 +
78191 +/**************************************************************************//**
78192 + @Function FM_CtrlMonGetCounters
78193 +
78194 + @Description Obtain FM controller utilization parameters.
78195 +
78196 + In order to obtain FM controllers utilization the following sequence
78197 + should be used:
78198 + -# FM_CtrlMonStart()
78199 + -# FM_CtrlMonStop()
78200 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78201 +
78202 + @Param[in] h_Fm A handle to an FM Module.
78203 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
78204 + are requested.
78205 + @Param[in] p_Mon Pointer to utilization results structure.
78206 +
78207 + @Return E_OK on success; Error code otherwise.
78208 +
78209 + @Cautions Allowed only following FM_Init().
78210 + This routine should NOT be called from guest-partition
78211 + (i.e. guestId != NCSW_MASTER_ID).
78212 +*//***************************************************************************/
78213 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
78214 +
78215 +
78216 +/**************************************************************************//*
78217 + @Function FM_ForceIntr
78218 +
78219 + @Description Causes an interrupt event on the requested source.
78220 +
78221 + @Param[in] h_Fm A handle to an FM Module.
78222 + @Param[in] exception An exception to be forced.
78223 +
78224 + @Return E_OK on success; Error code if the exception is not enabled,
78225 + or is not able to create interrupt.
78226 +
78227 + @Cautions Allowed only following FM_Init().
78228 + This routine should NOT be called from guest-partition
78229 + (i.e. guestId != NCSW_MASTER_ID)
78230 +*//***************************************************************************/
78231 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
78232 +
78233 +/**************************************************************************//*
78234 + @Function FM_SetPortsBandwidth
78235 +
78236 + @Description Sets relative weights between ports when accessing common resources.
78237 +
78238 + @Param[in] h_Fm A handle to an FM Module.
78239 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
78240 + total must equal 100.
78241 +
78242 + @Return E_OK on success; Error code otherwise.
78243 +
78244 + @Cautions Allowed only following FM_Init().
78245 + This routine should NOT be called from guest-partition
78246 + (i.e. guestId != NCSW_MASTER_ID)
78247 +*//***************************************************************************/
78248 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
78249 +
78250 +/**************************************************************************//*
78251 + @Function FM_GetMuramHandle
78252 +
78253 + @Description Gets the corresponding MURAM handle
78254 +
78255 + @Param[in] h_Fm A handle to an FM Module.
78256 +
78257 + @Return MURAM handle; NULL otherwise.
78258 +
78259 + @Cautions Allowed only following FM_Init().
78260 + This routine should NOT be called from guest-partition
78261 + (i.e. guestId != NCSW_MASTER_ID)
78262 +*//***************************************************************************/
78263 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
78264 +
78265 +/** @} */ /* end of FM_runtime_control_grp group */
78266 +/** @} */ /* end of FM_lib_grp group */
78267 +/** @} */ /* end of FM_grp group */
78268 +
78269 +
78270 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
78271 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
78272 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
78273 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
78274 +typedef t_FmExtPools t_FmPortExtPools;
78275 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
78276 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
78277 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
78278 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
78279 +
78280 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
78281 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
78282 +
78283 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
78284 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
78285 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
78286 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
78287 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
78288 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
78289 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
78290 +
78291 +
78292 +#endif /* __FM_EXT */
78293 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78294 new file mode 100644
78295 index 00000000..da7e0463
78296 --- /dev/null
78297 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78298 @@ -0,0 +1,859 @@
78299 +/*
78300 + * Copyright 2008-2012 Freescale Semiconductor Inc.
78301 + *
78302 + * Redistribution and use in source and binary forms, with or without
78303 + * modification, are permitted provided that the following conditions are met:
78304 + * * Redistributions of source code must retain the above copyright
78305 + * notice, this list of conditions and the following disclaimer.
78306 + * * Redistributions in binary form must reproduce the above copyright
78307 + * notice, this list of conditions and the following disclaimer in the
78308 + * documentation and/or other materials provided with the distribution.
78309 + * * Neither the name of Freescale Semiconductor nor the
78310 + * names of its contributors may be used to endorse or promote products
78311 + * derived from this software without specific prior written permission.
78312 + *
78313 + *
78314 + * ALTERNATIVELY, this software may be distributed under the terms of the
78315 + * GNU General Public License ("GPL") as published by the Free Software
78316 + * Foundation, either version 2 of that License or (at your option) any
78317 + * later version.
78318 + *
78319 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78320 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78321 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78322 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78323 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78324 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78325 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78326 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78327 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78328 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78329 + */
78330 +
78331 +
78332 +/**************************************************************************//**
78333 + @File fm_mac_ext.h
78334 +
78335 + @Description FM MAC ...
78336 +*//***************************************************************************/
78337 +#ifndef __FM_MAC_EXT_H
78338 +#define __FM_MAC_EXT_H
78339 +
78340 +#include "std_ext.h"
78341 +#include "enet_ext.h"
78342 +
78343 +
78344 +/**************************************************************************//**
78345 +
78346 + @Group FM_grp Frame Manager API
78347 +
78348 + @Description FM API functions, definitions and enums
78349 +
78350 + @{
78351 +*//***************************************************************************/
78352 +
78353 +/**************************************************************************//**
78354 + @Group FM_mac_grp FM MAC
78355 +
78356 + @Description FM MAC API functions, definitions and enums
78357 +
78358 + @{
78359 +*//***************************************************************************/
78360 +
78361 +#define FM_MAC_NO_PFC 0xff
78362 +
78363 +
78364 +/**************************************************************************//**
78365 + @Description FM MAC Exceptions
78366 +*//***************************************************************************/
78367 +typedef enum e_FmMacExceptions {
78368 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78369 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78370 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78371 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78372 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78373 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78374 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78375 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78376 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78377 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78378 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78379 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78380 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78381 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78382 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78383 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78384 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78385 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78386 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78387 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78388 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78389 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78390 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78391 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78392 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78393 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78394 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78395 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78396 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78397 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78398 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78399 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78400 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78401 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78402 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78403 + not supported on T4240/B4860 rev1 chips */
78404 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78405 + /**< mEMAC Magic Packet Indication Interrupt */
78406 +} e_FmMacExceptions;
78407 +
78408 +/**************************************************************************//**
78409 + @Description TM MAC statistics level
78410 +*//***************************************************************************/
78411 +typedef enum e_FmMacStatisticsLevel {
78412 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78413 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78414 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78415 +} e_FmMacStatisticsLevel;
78416 +
78417 +
78418 +#if (DPAA_VERSION >= 11)
78419 +/**************************************************************************//**
78420 + @Description Priority Flow Control Parameters
78421 +*//***************************************************************************/
78422 +typedef struct t_FmMacPfcParams {
78423 + bool pfcEnable; /**< Enable/Disable PFC */
78424 +
78425 + 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*/
78426 +
78427 + 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*/
78428 +
78429 +
78430 +} t_FmMacPfcParams;
78431 +#endif /* (DPAA_VERSION >= 11) */
78432 +
78433 +/**************************************************************************//**
78434 + @Function t_FmMacExceptionCallback
78435 +
78436 + @Description Fm Mac Exception Callback from FM MAC to the user
78437 +
78438 + @Param[in] h_App - Handle to the upper layer handler
78439 +
78440 + @Param[in] exceptions - The exception that occurred
78441 +
78442 + @Return void.
78443 +*//***************************************************************************/
78444 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78445 +
78446 +
78447 +/**************************************************************************//**
78448 + @Description TM MAC statistics rfc3635
78449 +*//***************************************************************************/
78450 +typedef struct t_FmMacStatistics {
78451 +/* RMON */
78452 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78453 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78454 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78455 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78456 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78457 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78458 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78459 +/* */
78460 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78461 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78462 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78463 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78464 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78465 + This count does not include range length errors */
78466 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78467 + a valid FCS and otherwise well formed */
78468 +/* Pause */
78469 + uint64_t teStatPause; /**< Pause MAC Control received */
78470 + uint64_t reStatPause; /**< Pause MAC Control sent */
78471 +/* MIB II */
78472 + uint64_t ifInOctets; /**< Total number of byte received. */
78473 + uint64_t ifInPkts; /**< Total number of packets received.*/
78474 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78475 + NOTE: this counter is not supported on dTSEC MAC */
78476 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78477 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78478 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78479 + uint64_t ifInErrors; /**< Number of frames received with error:
78480 + - FIFO Overflow Error
78481 + - CRC Error
78482 + - Frame Too Long Error
78483 + - Alignment Error
78484 + - The dedicated Error Code (0xfe, not a code error) was received */
78485 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78486 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78487 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78488 + NOTE: this counter is not supported on dTSEC MAC */
78489 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78490 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78491 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78492 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78493 + - FIFO Overflow Error
78494 + - FIFO Underflow Error
78495 + - Other */
78496 +} t_FmMacStatistics;
78497 +
78498 +
78499 +/**************************************************************************//**
78500 + @Group FM_mac_init_grp FM MAC Initialization Unit
78501 +
78502 + @Description FM MAC Initialization Unit
78503 +
78504 + @{
78505 +*//***************************************************************************/
78506 +
78507 +/**************************************************************************//**
78508 + @Description FM MAC config input
78509 +*//***************************************************************************/
78510 +typedef struct t_FmMacParams {
78511 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78512 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78513 + uint8_t macId; /**< MAC ID;
78514 + numbering of dTSEC and 1G-mEMAC:
78515 + 0 - FM_MAX_NUM_OF_1G_MACS;
78516 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78517 + 0 - FM_MAX_NUM_OF_10G_MACS */
78518 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78519 + Note that the speed should indicate the maximum rate that
78520 + this MAC should support rather than the actual speed;
78521 + i.e. user should use the FM_MAC_AdjustLink() routine to
78522 + provide accurate speed;
78523 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78524 + automatic mode, where actual speed/duplex mode information
78525 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78526 + function should be used to switch to manual RGMII speed/duplex mode
78527 + configuration if RGMII PHY doesn't support in-band status signaling;
78528 + In addition, in mEMAC, in case where user is using the higher MACs
78529 + (i.e. the MACs that should support 10G), user should pass here
78530 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78531 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78532 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78533 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78534 + mdio-irq, or for polling */
78535 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78536 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78537 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78538 + be passed by the driver upon calling the above callbacks */
78539 +} t_FmMacParams;
78540 +
78541 +
78542 +/**************************************************************************//**
78543 + @Function FM_MAC_Config
78544 +
78545 + @Description Creates descriptor for the FM MAC module.
78546 +
78547 + The routine returns a handle (descriptor) to the FM MAC object.
78548 + This descriptor must be passed as first parameter to all other
78549 + FM MAC function calls.
78550 +
78551 + No actual initialization or configuration of FM MAC hardware is
78552 + done by this routine.
78553 +
78554 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78555 +
78556 + @Retval Handle to FM MAC object, or NULL for Failure.
78557 +*//***************************************************************************/
78558 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78559 +
78560 +/**************************************************************************//**
78561 + @Function FM_MAC_Init
78562 +
78563 + @Description Initializes the FM MAC module
78564 +
78565 + @Param[in] h_FmMac - FM module descriptor
78566 +
78567 + @Return E_OK on success; Error code otherwise.
78568 +*//***************************************************************************/
78569 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78570 +
78571 +/**************************************************************************//**
78572 + @Function FM_Free
78573 +
78574 + @Description Frees all resources that were assigned to FM MAC module.
78575 +
78576 + Calling this routine invalidates the descriptor.
78577 +
78578 + @Param[in] h_FmMac - FM module descriptor
78579 +
78580 + @Return E_OK on success; Error code otherwise.
78581 +*//***************************************************************************/
78582 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78583 +
78584 +
78585 +/**************************************************************************//**
78586 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78587 +
78588 + @Description Configuration functions used to change default values.
78589 +
78590 + @{
78591 +*//***************************************************************************/
78592 +
78593 +/**************************************************************************//**
78594 + @Function FM_MAC_ConfigResetOnInit
78595 +
78596 + @Description Tell the driver whether to reset the FM MAC before initialization or
78597 + not. It changes the default configuration [DEFAULT_resetOnInit].
78598 +
78599 + @Param[in] h_FmMac A handle to a FM MAC Module.
78600 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78601 +
78602 + @Return E_OK on success; Error code otherwise.
78603 +
78604 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78605 +*//***************************************************************************/
78606 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78607 +
78608 +/**************************************************************************//**
78609 + @Function FM_MAC_ConfigLoopback
78610 +
78611 + @Description Enable/Disable internal loopback mode
78612 +
78613 + @Param[in] h_FmMac A handle to a FM MAC Module.
78614 + @Param[in] enable TRUE to enable or FALSE to disable.
78615 +
78616 + @Return E_OK on success; Error code otherwise.
78617 +
78618 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78619 +*//***************************************************************************/
78620 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78621 +
78622 +/**************************************************************************//**
78623 + @Function FM_MAC_ConfigMaxFrameLength
78624 +
78625 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78626 +
78627 + @Param[in] h_FmMac A handle to a FM MAC Module.
78628 + @Param[in] newVal MAX Frame length
78629 +
78630 + @Return E_OK on success; Error code otherwise.
78631 +
78632 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78633 +*//***************************************************************************/
78634 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78635 +
78636 +/**************************************************************************//**
78637 + @Function FM_MAC_ConfigWan
78638 +
78639 + @Description ENABLE WAN mode in 10G-MAC
78640 +
78641 + @Param[in] h_FmMac A handle to a FM MAC Module.
78642 + @Param[in] enable TRUE to enable or FALSE to disable.
78643 +
78644 + @Return E_OK on success; Error code otherwise.
78645 +
78646 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78647 +*//***************************************************************************/
78648 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78649 +
78650 +/**************************************************************************//**
78651 + @Function FM_MAC_ConfigPadAndCrc
78652 +
78653 + @Description Config PAD and CRC mode
78654 +
78655 + @Param[in] h_FmMac A handle to a FM MAC Module.
78656 + @Param[in] enable TRUE to enable or FALSE to disable.
78657 +
78658 + @Return E_OK on success; Error code otherwise.
78659 +
78660 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78661 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78662 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78663 + added automatically by HW).
78664 +*//***************************************************************************/
78665 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78666 +
78667 +/**************************************************************************//**
78668 + @Function FM_MAC_ConfigHalfDuplex
78669 +
78670 + @Description Config Half Duplex Mode
78671 +
78672 + @Param[in] h_FmMac A handle to a FM MAC Module.
78673 + @Param[in] enable TRUE to enable or FALSE to disable.
78674 +
78675 + @Return E_OK on success; Error code otherwise.
78676 +
78677 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78678 +*//***************************************************************************/
78679 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78680 +
78681 +/**************************************************************************//**
78682 + @Function FM_MAC_ConfigTbiPhyAddr
78683 +
78684 + @Description Configures the address of internal TBI PHY.
78685 +
78686 + @Param[in] h_FmMac A handle to a FM MAC Module.
78687 + @Param[in] newVal TBI PHY address (1-31).
78688 +
78689 + @Return E_OK on success; Error code otherwise.
78690 +
78691 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78692 +*//***************************************************************************/
78693 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78694 +
78695 +/**************************************************************************//**
78696 + @Function FM_MAC_ConfigLengthCheck
78697 +
78698 + @Description Configure the frame length checking.
78699 +
78700 + @Param[in] h_FmMac A handle to a FM MAC Module.
78701 + @Param[in] enable TRUE to enable or FALSE to disable.
78702 +
78703 + @Return E_OK on success; Error code otherwise.
78704 +
78705 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78706 +*//***************************************************************************/
78707 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78708 +
78709 +/**************************************************************************//**
78710 + @Function FM_MAC_ConfigException
78711 +
78712 + @Description Change Exception selection from default
78713 +
78714 + @Param[in] h_FmMac A handle to a FM MAC Module.
78715 + @Param[in] ex Type of the desired exceptions
78716 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78717 +
78718 + @Return E_OK on success; Error code otherwise.
78719 +
78720 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78721 +*//***************************************************************************/
78722 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78723 +
78724 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78725 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78726 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78727 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78728 +/** @} */ /* end of FM_mac_init_grp group */
78729 +
78730 +
78731 +/**************************************************************************//**
78732 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78733 +
78734 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78735 +
78736 + @{
78737 +*//***************************************************************************/
78738 +
78739 +/**************************************************************************//**
78740 + @Function FM_MAC_Enable
78741 +
78742 + @Description Enable the MAC
78743 +
78744 + @Param[in] h_FmMac A handle to a FM MAC Module.
78745 + @Param[in] mode Mode of operation (RX, TX, Both)
78746 +
78747 + @Return E_OK on success; Error code otherwise.
78748 +
78749 + @Cautions Allowed only following FM_MAC_Init().
78750 +*//***************************************************************************/
78751 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78752 +
78753 +/**************************************************************************//**
78754 + @Function FM_MAC_Disable
78755 +
78756 + @Description DISABLE the MAC
78757 +
78758 + @Param[in] h_FmMac A handle to a FM MAC Module.
78759 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
78760 +
78761 + @Return E_OK on success; Error code otherwise.
78762 +
78763 + @Cautions Allowed only following FM_MAC_Init().
78764 +*//***************************************************************************/
78765 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
78766 +
78767 +/**************************************************************************//**
78768 + @Function FM_MAC_Resume
78769 +
78770 + @Description Re-init the MAC after suspend
78771 +
78772 + @Param[in] h_FmMac A handle to a FM MAC Module.
78773 +
78774 + @Return E_OK on success; Error code otherwise.
78775 +
78776 + @Cautions Allowed only following FM_MAC_Init().
78777 +*//***************************************************************************/
78778 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78779 +
78780 +/**************************************************************************//**
78781 + @Function FM_MAC_Enable1588TimeStamp
78782 +
78783 + @Description Enables the TSU operation.
78784 +
78785 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78786 +
78787 + @Return E_OK on success; Error code otherwise.
78788 +
78789 + @Cautions Allowed only following FM_MAC_Init().
78790 +*//***************************************************************************/
78791 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78792 +
78793 +/**************************************************************************//**
78794 + @Function FM_MAC_Disable1588TimeStamp
78795 +
78796 + @Description Disables the TSU operation.
78797 +
78798 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78799 +
78800 + @Return E_OK on success; Error code otherwise.
78801 +
78802 + @Cautions Allowed only following FM_MAC_Init().
78803 +*//***************************************************************************/
78804 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78805 +
78806 +/**************************************************************************//**
78807 + @Function FM_MAC_SetTxAutoPauseFrames
78808 +
78809 + @Description Enable/Disable transmission of Pause-Frames.
78810 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78811 +
78812 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78813 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78814 + Each quanta represents a 512 bit-times; Note that '0'
78815 + as an input here will be used as disabling the
78816 + transmission of the pause-frames.
78817 +
78818 + @Return E_OK on success; Error code otherwise.
78819 +
78820 + @Cautions Allowed only following FM_MAC_Init().
78821 +*//***************************************************************************/
78822 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78823 + uint16_t pauseTime);
78824 +
78825 + /**************************************************************************//**
78826 + @Function FM_MAC_SetTxPauseFrames
78827 +
78828 + @Description Enable/Disable transmission of Pause-Frames.
78829 + The routine changes the default configuration:
78830 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78831 + threshold-time - [0]
78832 +
78833 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78834 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78835 + to indicate legacy pause support (i.e. no PFC).
78836 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78837 + Each quanta represents a 512 bit-times;
78838 + Note that '0' as an input here will be used as disabling the
78839 + transmission of the pause-frames.
78840 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78841 + if the situation causing a pause frame to be sent didn't finish when the timer
78842 + reached the threshold quanta, the MAC will retransmit the pause frame.
78843 + Each quanta represents a 512 bit-times.
78844 +
78845 + @Return E_OK on success; Error code otherwise.
78846 +
78847 + @Cautions Allowed only following FM_MAC_Init().
78848 + In order for PFC to work properly the user must configure
78849 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78850 + rate limit in the tx port should be disabled;
78851 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78852 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78853 + in the 'priority' field.
78854 +*//***************************************************************************/
78855 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78856 + uint8_t priority,
78857 + uint16_t pauseTime,
78858 + uint16_t threshTime);
78859 +
78860 +/**************************************************************************//**
78861 + @Function FM_MAC_SetRxIgnorePauseFrames
78862 +
78863 + @Description Enable/Disable ignoring of Pause-Frames.
78864 +
78865 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78866 + @Param[in] en - boolean indicates whether to ignore the incoming pause
78867 + frames or not.
78868 +
78869 + @Return E_OK on success; Error code otherwise.
78870 +
78871 + @Cautions Allowed only following FM_MAC_Init().
78872 +*//***************************************************************************/
78873 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
78874 +
78875 +/**************************************************************************//**
78876 + @Function FM_MAC_SetWakeOnLan
78877 +
78878 + @Description Enable/Disable Wake On Lan support
78879 +
78880 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78881 + @Param[in] en - boolean indicates whether to enable Wake On Lan
78882 + support or not.
78883 +
78884 + @Return E_OK on success; Error code otherwise.
78885 +
78886 + @Cautions Allowed only following FM_MAC_Init().
78887 +*//***************************************************************************/
78888 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
78889 +
78890 +/**************************************************************************//**
78891 + @Function FM_MAC_ResetCounters
78892 +
78893 + @Description reset all statistics counters
78894 +
78895 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78896 +
78897 + @Return E_OK on success; Error code otherwise.
78898 +
78899 + @Cautions Allowed only following FM_MAC_Init().
78900 +*//***************************************************************************/
78901 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
78902 +
78903 +/**************************************************************************//**
78904 + @Function FM_MAC_SetException
78905 +
78906 + @Description Enable/Disable a specific Exception
78907 +
78908 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78909 + @Param[in] ex - Type of the desired exceptions
78910 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
78911 +
78912 +
78913 + @Return E_OK on success; Error code otherwise.
78914 +
78915 + @Cautions Allowed only following FM_MAC_Init().
78916 +*//***************************************************************************/
78917 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78918 +
78919 +/**************************************************************************//**
78920 + @Function FM_MAC_SetStatistics
78921 +
78922 + @Description Define Statistics level.
78923 + Where applicable, the routine also enables the MIB counters
78924 + overflow interrupt in order to keep counters accurate
78925 + and account for overflows.
78926 + This routine is relevant only for dTSEC.
78927 +
78928 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78929 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
78930 + reduce performance. Partial statistics provides only special
78931 + event counters (errors etc.). If selected, regular counters (such as
78932 + byte/packet) will be invalid and will return -1.
78933 +
78934 + @Return E_OK on success; Error code otherwise.
78935 +
78936 + @Cautions Allowed only following FM_MAC_Init().
78937 +*//***************************************************************************/
78938 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
78939 +
78940 +/**************************************************************************//**
78941 + @Function FM_MAC_GetStatistics
78942 +
78943 + @Description get all statistics counters
78944 +
78945 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78946 + @Param[in] p_Statistics - Structure with statistics
78947 +
78948 + @Return E_OK on success; Error code otherwise.
78949 +
78950 + @Cautions Allowed only following FM_Init().
78951 +*//***************************************************************************/
78952 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
78953 +
78954 +/**************************************************************************//**
78955 + @Function FM_MAC_ModifyMacAddr
78956 +
78957 + @Description Replace the main MAC Address
78958 +
78959 + @Param[in] h_FmMac - A handle to a FM Module.
78960 + @Param[in] p_EnetAddr - Ethernet Mac address
78961 +
78962 + @Return E_OK on success; Error code otherwise.
78963 +
78964 + @Cautions Allowed only after FM_MAC_Init().
78965 +*//***************************************************************************/
78966 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78967 +
78968 +/**************************************************************************//**
78969 + @Function FM_MAC_AddHashMacAddr
78970 +
78971 + @Description Add an Address to the hash table. This is for filter purpose only.
78972 +
78973 + @Param[in] h_FmMac - A handle to a FM Module.
78974 + @Param[in] p_EnetAddr - Ethernet Mac address
78975 +
78976 + @Return E_OK on success; Error code otherwise.
78977 +
78978 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
78979 + @Cautions Some address need to be filterd out in upper FM blocks.
78980 +*//***************************************************************************/
78981 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78982 +
78983 +/**************************************************************************//**
78984 + @Function FM_MAC_RemoveHashMacAddr
78985 +
78986 + @Description Delete an Address to the hash table. This is for filter purpose only.
78987 +
78988 + @Param[in] h_FmMac - A handle to a FM Module.
78989 + @Param[in] p_EnetAddr - Ethernet Mac address
78990 +
78991 + @Return E_OK on success; Error code otherwise.
78992 +
78993 + @Cautions Allowed only following FM_MAC_Init().
78994 +*//***************************************************************************/
78995 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78996 +
78997 +/**************************************************************************//**
78998 + @Function FM_MAC_AddExactMatchMacAddr
78999 +
79000 + @Description Add a unicast or multicast mac address for exact-match filtering
79001 + (8 on dTSEC, 2 for 10G-MAC)
79002 +
79003 + @Param[in] h_FmMac - A handle to a FM Module.
79004 + @Param[in] p_EnetAddr - MAC Address to ADD
79005 +
79006 + @Return E_OK on success; Error code otherwise.
79007 +
79008 + @Cautions Allowed only after FM_MAC_Init().
79009 +*//***************************************************************************/
79010 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79011 +
79012 +/**************************************************************************//**
79013 + @Function FM_MAC_RemovelExactMatchMacAddr
79014 +
79015 + @Description Remove a uni cast or multi cast mac address.
79016 +
79017 + @Param[in] h_FmMac - A handle to a FM Module.
79018 + @Param[in] p_EnetAddr - MAC Address to remove
79019 +
79020 + @Return E_OK on success; Error code otherwise..
79021 +
79022 + @Cautions Allowed only after FM_MAC_Init().
79023 +*//***************************************************************************/
79024 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79025 +
79026 +/**************************************************************************//**
79027 + @Function FM_MAC_SetPromiscuous
79028 +
79029 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
79030 +
79031 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79032 + @Param[in] enable - TRUE to enable or FALSE to disable.
79033 +
79034 + @Return E_OK on success; Error code otherwise.
79035 +
79036 + @Cautions Allowed only after FM_MAC_Init().
79037 +*//***************************************************************************/
79038 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
79039 +
79040 +/**************************************************************************//**
79041 + @Function FM_MAC_AdjustLink
79042 +
79043 + @Description Adjusts the Ethernet link with new speed/duplex setup.
79044 + This routine is relevant for dTSEC and mEMAC.
79045 + In case of mEMAC, this routine is also used for manual
79046 + re-configuration of RGMII speed and duplex mode for
79047 + RGMII PHYs not supporting in-band status information
79048 + to MAC.
79049 +
79050 + @Param[in] h_FmMac - A handle to a FM Module.
79051 + @Param[in] speed - Ethernet speed.
79052 + @Param[in] fullDuplex - TRUE for full-duplex mode;
79053 + FALSE for half-duplex mode.
79054 +
79055 + @Return E_OK on success; Error code otherwise.
79056 +*//***************************************************************************/
79057 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
79058 +
79059 +/**************************************************************************//**
79060 + @Function FM_MAC_RestartAutoneg
79061 +
79062 + @Description Restarts the auto-negotiation process.
79063 + When auto-negotiation process is invoked under traffic the
79064 + auto-negotiation process between the internal SGMII PHY and the
79065 + external PHY does not always complete successfully. Calling this
79066 + function will restart the auto-negotiation process that will end
79067 + successfully. It is recommended to call this function after issuing
79068 + auto-negotiation restart command to the Eth Phy.
79069 + This routine is relevant only for dTSEC.
79070 +
79071 + @Param[in] h_FmMac - A handle to a FM Module.
79072 +
79073 + @Return E_OK on success; Error code otherwise.
79074 +*//***************************************************************************/
79075 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
79076 +
79077 +/**************************************************************************//**
79078 + @Function FM_MAC_GetId
79079 +
79080 + @Description Return the MAC ID
79081 +
79082 + @Param[in] h_FmMac - A handle to a FM Module.
79083 + @Param[out] p_MacId - MAC ID of device
79084 +
79085 + @Return E_OK on success; Error code otherwise.
79086 +
79087 + @Cautions Allowed only after FM_MAC_Init().
79088 +*//***************************************************************************/
79089 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
79090 +
79091 +/**************************************************************************//**
79092 + @Function FM_MAC_GetVesrion
79093 +
79094 + @Description Return Mac HW chip version
79095 +
79096 + @Param[in] h_FmMac - A handle to a FM Module.
79097 + @Param[out] p_MacVresion - Mac version as defined by the chip
79098 +
79099 + @Return E_OK on success; Error code otherwise.
79100 +
79101 + @Cautions Allowed only after FM_MAC_Init().
79102 +*//***************************************************************************/
79103 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
79104 +
79105 +/**************************************************************************//**
79106 + @Function FM_MAC_MII_WritePhyReg
79107 +
79108 + @Description Write data into Phy Register
79109 +
79110 + @Param[in] h_FmMac - A handle to a FM Module.
79111 + @Param[in] phyAddr - Phy Address on the MII bus
79112 + @Param[in] reg - Register Number.
79113 + @Param[in] data - Data to write.
79114 +
79115 + @Return E_OK on success; Error code otherwise.
79116 +
79117 + @Cautions Allowed only after FM_MAC_Init().
79118 +*//***************************************************************************/
79119 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
79120 +
79121 +/**************************************************************************//**
79122 + @Function FM_MAC_MII_ReadPhyReg
79123 +
79124 + @Description Read data from Phy Register
79125 +
79126 + @Param[in] h_FmMac - A handle to a FM Module.
79127 + @Param[in] phyAddr - Phy Address on the MII bus
79128 + @Param[in] reg - Register Number.
79129 + @Param[out] p_Data - Data from PHY.
79130 +
79131 + @Return E_OK on success; Error code otherwise.
79132 +
79133 + @Cautions Allowed only after FM_MAC_Init().
79134 +*//***************************************************************************/
79135 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
79136 +
79137 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79138 +/**************************************************************************//**
79139 + @Function FM_MAC_DumpRegs
79140 +
79141 + @Description Dump internal registers
79142 +
79143 + @Param[in] h_FmMac - A handle to a FM Module.
79144 +
79145 + @Return E_OK on success; Error code otherwise.
79146 +
79147 + @Cautions Allowed only after FM_MAC_Init().
79148 +*//***************************************************************************/
79149 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
79150 +#endif /* (defined(DEBUG_ERRORS) && ... */
79151 +
79152 +/** @} */ /* end of FM_mac_runtime_control_grp group */
79153 +/** @} */ /* end of FM_mac_grp group */
79154 +/** @} */ /* end of FM_grp group */
79155 +
79156 +
79157 +#endif /* __FM_MAC_EXT_H */
79158 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79159 new file mode 100644
79160 index 00000000..57925f10
79161 --- /dev/null
79162 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79163 @@ -0,0 +1,1271 @@
79164 +/*
79165 + * Copyright 2008-2015 Freescale Semiconductor Inc.
79166 + *
79167 + * Redistribution and use in source and binary forms, with or without
79168 + * modification, are permitted provided that the following conditions are met:
79169 + * * Redistributions of source code must retain the above copyright
79170 + * notice, this list of conditions and the following disclaimer.
79171 + * * Redistributions in binary form must reproduce the above copyright
79172 + * notice, this list of conditions and the following disclaimer in the
79173 + * documentation and/or other materials provided with the distribution.
79174 + * * Neither the name of Freescale Semiconductor nor the
79175 + * names of its contributors may be used to endorse or promote products
79176 + * derived from this software without specific prior written permission.
79177 + *
79178 + *
79179 + * ALTERNATIVELY, this software may be distributed under the terms of the
79180 + * GNU General Public License ("GPL") as published by the Free Software
79181 + * Foundation, either version 2 of that License or (at your option) any
79182 + * later version.
79183 + *
79184 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
79185 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79186 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79187 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
79188 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79189 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79190 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79191 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79192 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79193 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79194 + */
79195 +
79196 +/**************************************************************************//**
79197 + @File fm_macsec_ext.h
79198 +
79199 + @Description FM MACSEC ...
79200 +*//***************************************************************************/
79201 +#ifndef __FM_MACSEC_EXT_H
79202 +#define __FM_MACSEC_EXT_H
79203 +
79204 +#include "std_ext.h"
79205 +
79206 +
79207 +/**************************************************************************//**
79208 + @Group FM_grp Frame Manager API
79209 +
79210 + @Description FM API functions, definitions and enums
79211 +
79212 + @{
79213 +*//***************************************************************************/
79214 +
79215 +/**************************************************************************//**
79216 + @Group FM_MACSEC_grp FM MACSEC
79217 +
79218 + @Description FM MACSEC API functions, definitions and enums
79219 +
79220 + @{
79221 +*//***************************************************************************/
79222 +
79223 +/**************************************************************************//**
79224 + @Description MACSEC Exceptions
79225 +*//***************************************************************************/
79226 +typedef enum e_FmMacsecExceptions {
79227 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
79228 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
79229 +} e_FmMacsecExceptions;
79230 +
79231 +
79232 +/**************************************************************************//**
79233 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
79234 +
79235 + @Description FM MACSEC Initialization Unit
79236 +
79237 + @{
79238 +*//***************************************************************************/
79239 +
79240 +/**************************************************************************//**
79241 + @Function t_FmMacsecExceptionsCallback
79242 +
79243 + @Description Exceptions user callback routine, will be called upon an
79244 + exception passing the exception identification.
79245 +
79246 + @Param[in] h_App A handle to an application layer object; This handle
79247 + will be passed by the driver upon calling this callback.
79248 + @Param[in] exception The exception.
79249 +*//***************************************************************************/
79250 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
79251 + e_FmMacsecExceptions exception);
79252 +
79253 +
79254 +/**************************************************************************//**
79255 + @Description FM MACSEC config input
79256 +*//***************************************************************************/
79257 +typedef struct t_FmMacsecParams {
79258 + t_Handle h_Fm; /**< A handle to the FM object related to */
79259 + bool guestMode; /**< Partition-id */
79260 + union {
79261 + struct {
79262 + uint8_t fmMacId; /**< FM MAC id */
79263 + } guestParams;
79264 +
79265 + struct {
79266 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
79267 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
79268 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
79269 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79270 + be passed by the driver upon calling the above callbacks */
79271 + } nonGuestParams;
79272 + };
79273 +} t_FmMacsecParams;
79274 +
79275 +/**************************************************************************//**
79276 + @Function FM_MACSEC_Config
79277 +
79278 + @Description Creates descriptor for the FM MACSEC module;
79279 +
79280 + The routine returns a handle (descriptor) to the FM MACSEC object;
79281 + This descriptor must be passed as first parameter to all other
79282 + FM MACSEC function calls;
79283 +
79284 + No actual initialization or configuration of FM MACSEC hardware is
79285 + done by this routine.
79286 +
79287 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
79288 +
79289 + @Retval Handle to FM MACSEC object, or NULL for Failure.
79290 +*//***************************************************************************/
79291 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
79292 +
79293 +/**************************************************************************//**
79294 + @Function FM_MACSEC_Init
79295 +
79296 + @Description Initializes the FM MACSEC module.
79297 +
79298 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79299 +
79300 + @Return E_OK on success; Error code otherwise.
79301 +*//***************************************************************************/
79302 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
79303 +
79304 +/**************************************************************************//**
79305 + @Function FM_MACSEC_Free
79306 +
79307 + @Description Frees all resources that were assigned to FM MACSEC module;
79308 +
79309 + Calling this routine invalidates the descriptor.
79310 +
79311 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79312 +
79313 + @Return E_OK on success; Error code otherwise.
79314 +*//***************************************************************************/
79315 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
79316 +
79317 +
79318 +/**************************************************************************//**
79319 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
79320 +
79321 + @Description Configuration functions used to change default values.
79322 +
79323 + @{
79324 +*//***************************************************************************/
79325 +
79326 +/**************************************************************************//**
79327 + @Description enum for unknown sci frame treatment
79328 +*//***************************************************************************/
79329 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
79330 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
79331 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
79332 + Controlled port - Check or Disable mode */
79333 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
79334 + 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,
79335 + else discard on uncontrolled port and deliver on controlled port
79336 + Controlled port - Check or Disable mode */
79337 +} e_FmMacsecUnknownSciFrameTreatment;
79338 +
79339 +/**************************************************************************//**
79340 + @Description enum for untag frame treatment
79341 +*//***************************************************************************/
79342 +typedef enum e_FmMacsecUntagFrameTreatment {
79343 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
79344 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79345 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79346 +} e_FmMacsecUntagFrameTreatment;
79347 +
79348 +/**************************************************************************//**
79349 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79350 +
79351 + @Description Change the treatment for received frames with unknown sci from its default
79352 + configuration [DEFAULT_unknownSciFrameTreatment].
79353 +
79354 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79355 + @Param[in] treatMode The selected mode.
79356 +
79357 + @Return E_OK on success; Error code otherwise.
79358 +
79359 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79360 +*//***************************************************************************/
79361 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79362 +
79363 +/**************************************************************************//**
79364 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79365 +
79366 + @Description Change the treatment for received frames with invalid tags or
79367 + a zero value PN or an invalid ICV from its default configuration
79368 + [DEFAULT_invalidTagsFrameTreatment].
79369 +
79370 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79371 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79372 + In both cases discard on the controlled port;
79373 + this provide Strict, Check or Disable mode.
79374 +
79375 + @Return E_OK on success; Error code otherwise.
79376 +
79377 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79378 +*//***************************************************************************/
79379 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79380 +
79381 +/**************************************************************************//**
79382 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79383 +
79384 + @Description Change the treatment for received frames with the Encryption bit
79385 + set and the Changed Text bit clear from its default configuration
79386 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79387 +
79388 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79389 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79390 + In both cases discard on the controlled port;
79391 + this provide Strict, Check or Disable mode.
79392 +
79393 + @Return E_OK on success; Error code otherwise.
79394 +
79395 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79396 +*//***************************************************************************/
79397 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79398 +
79399 +/**************************************************************************//**
79400 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79401 +
79402 + @Description Change the treatment for received frames with the Encryption bit
79403 + clear and the Changed Text bit set from its default configuration
79404 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79405 +
79406 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79407 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79408 + In both cases discard on the controlled port;
79409 + this provide Strict, Check or Disable mode.
79410 +
79411 + @Return E_OK on success; Error code otherwise.
79412 +
79413 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79414 +*//***************************************************************************/
79415 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79416 +
79417 +/**************************************************************************//**
79418 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79419 +
79420 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79421 + from its default configuration [DEFAULT_untagFrameTreatment].
79422 +
79423 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79424 + @Param[in] treatMode The selected mode.
79425 +
79426 + @Return E_OK on success; Error code otherwise.
79427 +
79428 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79429 +*//***************************************************************************/
79430 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79431 +
79432 +/**************************************************************************//**
79433 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79434 +
79435 + @Description Change the treatment for received frames with only SCB bit set
79436 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79437 +
79438 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79439 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79440 + In both cases discard on the controlled port;
79441 + this provide Strict, Check or Disable mode.
79442 +
79443 + @Return E_OK on success; Error code otherwise.
79444 +
79445 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79446 +*//***************************************************************************/
79447 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79448 +
79449 +/**************************************************************************//**
79450 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79451 +
79452 + @Description It's provide the ability to configure a PN exhaustion threshold;
79453 + When the NextPn crosses this value an interrupt event
79454 + is asserted to warn that the active SA should re-key.
79455 +
79456 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79457 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79458 + is asserted to re-key.
79459 +
79460 + @Return E_OK on success; Error code otherwise.
79461 +
79462 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79463 +*//***************************************************************************/
79464 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79465 +
79466 +/**************************************************************************//**
79467 + @Function FM_MACSEC_ConfigKeysUnreadable
79468 +
79469 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79470 + Can not be cleared unless hard reset.
79471 +
79472 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79473 +
79474 + @Return E_OK on success; Error code otherwise.
79475 +
79476 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79477 +*//***************************************************************************/
79478 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79479 +
79480 +/**************************************************************************//**
79481 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79482 +
79483 + @Description Promise that all generated Sectag will be without SCI included.
79484 +
79485 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79486 +
79487 + @Return E_OK on success; Error code otherwise.
79488 +
79489 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79490 +*//***************************************************************************/
79491 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79492 +
79493 +/**************************************************************************//**
79494 + @Function FM_MACSEC_ConfigException
79495 +
79496 + @Description Calling this routine changes the internal driver data base
79497 + from its default selection of exceptions enablement;
79498 + By default all exceptions are enabled.
79499 +
79500 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79501 + @Param[in] exception The exception to be selected.
79502 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79503 +
79504 + @Return E_OK on success; Error code otherwise.
79505 +
79506 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79507 +*//***************************************************************************/
79508 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79509 +
79510 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79511 +/** @} */ /* end of FM_MACSEC_init_grp group */
79512 +
79513 +
79514 +/**************************************************************************//**
79515 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79516 +
79517 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79518 +
79519 + @{
79520 +*//***************************************************************************/
79521 +
79522 +/**************************************************************************//**
79523 + @Function FM_MACSEC_GetRevision
79524 +
79525 + @Description Return MACSEC HW chip revision
79526 +
79527 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79528 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79529 +
79530 + @Return E_OK on success; Error code otherwise.
79531 +
79532 + @Cautions Allowed only after FM_MACSEC_Init().
79533 +*//***************************************************************************/
79534 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79535 +
79536 +/**************************************************************************//**
79537 + @Function FM_MACSEC_Enable
79538 +
79539 + @Description This routine should be called after MACSEC is initialized for enabling all
79540 + MACSEC engines according to their existing configuration.
79541 +
79542 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79543 +
79544 + @Return E_OK on success; Error code otherwise.
79545 +
79546 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79547 +*//***************************************************************************/
79548 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79549 +
79550 +/**************************************************************************//**
79551 + @Function FM_MACSEC_Disable
79552 +
79553 + @Description This routine may be called when MACSEC is enabled in order to
79554 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79555 +
79556 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79557 +
79558 + @Return E_OK on success; Error code otherwise.
79559 +
79560 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79561 +*//***************************************************************************/
79562 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79563 +
79564 +/**************************************************************************//**
79565 + @Function FM_MACSEC_SetException
79566 +
79567 + @Description Calling this routine enables/disables the specified exception.
79568 +
79569 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79570 + @Param[in] exception The exception to be selected.
79571 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79572 +
79573 + @Return E_OK on success; Error code otherwise.
79574 +
79575 + @Cautions Allowed only following FM_MACSEC_Init().
79576 +*//***************************************************************************/
79577 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79578 +
79579 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79580 +/**************************************************************************//**
79581 + @Function FM_MACSEC_DumpRegs
79582 +
79583 + @Description Dump internal registers.
79584 +
79585 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79586 +
79587 + @Return E_OK on success; Error code otherwise.
79588 +
79589 + @Cautions Allowed only after FM_MACSEC_Init().
79590 +*//***************************************************************************/
79591 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79592 +#endif /* (defined(DEBUG_ERRORS) && ... */
79593 +
79594 +#ifdef VERIFICATION_SUPPORT
79595 +/********************* VERIFICATION ONLY ********************************/
79596 +/**************************************************************************//**
79597 + @Function FM_MACSEC_BackdoorSet
79598 +
79599 + @Description Set register of the MACSEC memory map
79600 +
79601 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79602 + @Param[out] offset Register offset.
79603 + @Param[out] value Value to write.
79604 +
79605 +
79606 + @Return None
79607 +
79608 + @Cautions Allowed only following FM_MACSEC_Init().
79609 +*//***************************************************************************/
79610 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79611 +
79612 +/**************************************************************************//**
79613 + @Function FM_MACSEC_BackdoorGet
79614 +
79615 + @Description Read from register of the MACSEC memory map.
79616 +
79617 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79618 + @Param[out] offset Register offset.
79619 +
79620 + @Return Value read
79621 +
79622 + @Cautions Allowed only following FM_MACSEC_Init().
79623 +*//***************************************************************************/
79624 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79625 +#endif /* VERIFICATION_SUPPORT */
79626 +
79627 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79628 +
79629 +
79630 +/**************************************************************************//**
79631 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79632 +
79633 + @Description FM-MACSEC SecY API functions, definitions and enums
79634 +
79635 + @{
79636 +*//***************************************************************************/
79637 +
79638 +typedef uint8_t macsecSAKey_t[32];
79639 +typedef uint64_t macsecSCI_t;
79640 +typedef uint8_t macsecAN_t;
79641 +
79642 +/**************************************************************************//**
79643 +@Description MACSEC SECY Cipher Suite
79644 +*//***************************************************************************/
79645 +typedef enum e_FmMacsecSecYCipherSuite {
79646 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79647 +#if (DPAA_VERSION >= 11)
79648 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79649 +#endif /* (DPAA_VERSION >= 11) */
79650 +} e_FmMacsecSecYCipherSuite;
79651 +
79652 +/**************************************************************************//**
79653 + @Description MACSEC SECY Exceptions
79654 +*//***************************************************************************/
79655 +typedef enum e_FmMacsecSecYExceptions {
79656 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79657 +} e_FmMacsecSecYExceptions;
79658 +
79659 +/**************************************************************************//**
79660 + @Description MACSEC SECY Events
79661 +*//***************************************************************************/
79662 +typedef enum e_FmMacsecSecYEvents {
79663 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79664 +} e_FmMacsecSecYEvents;
79665 +
79666 +/**************************************************************************//**
79667 + @Collection MACSEC SECY Frame Discarded Descriptor error
79668 +*//***************************************************************************/
79669 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79670 +
79671 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79672 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79673 +/* @} */
79674 +
79675 +/**************************************************************************//**
79676 + @Function t_FmMacsecSecYExceptionsCallback
79677 +
79678 + @Description Exceptions user callback routine, will be called upon an
79679 + exception passing the exception identification.
79680 +
79681 + @Param[in] h_App A handle to an application layer object; This handle
79682 + will be passed by the driver upon calling this callback.
79683 + @Param[in] exception The exception.
79684 +*//***************************************************************************/
79685 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79686 + e_FmMacsecSecYExceptions exception);
79687 +
79688 +/**************************************************************************//**
79689 + @Function t_FmMacsecSecYEventsCallback
79690 +
79691 + @Description Events user callback routine, will be called upon an
79692 + event passing the event identification.
79693 +
79694 + @Param[in] h_App A handle to an application layer object; This handle
79695 + will be passed by the driver upon calling this callback.
79696 + @Param[in] event The event.
79697 +*//***************************************************************************/
79698 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79699 + e_FmMacsecSecYEvents event);
79700 +
79701 +/**************************************************************************//**
79702 + @Description RFC2863 MIB
79703 +*//***************************************************************************/
79704 +typedef struct t_MIBStatistics {
79705 + uint64_t ifInOctets; /**< Total number of byte received */
79706 + uint64_t ifInPkts; /**< Total number of packets received */
79707 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79708 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79709 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79710 + - InPktsNoTag,
79711 + - InPktsLate,
79712 + - InPktsOverrun */
79713 + uint64_t ifInErrors; /**< Number of frames received with error:
79714 + - InPktsBadTag,
79715 + - InPktsNoSCI,
79716 + - InPktsNotUsingSA
79717 + - InPktsNotValid */
79718 + uint64_t ifOutOctets; /**< Total number of byte sent */
79719 + uint64_t ifOutPkts; /**< Total number of packets sent */
79720 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79721 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79722 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79723 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79724 + - FIFO Overflow Error
79725 + - FIFO Underflow Error
79726 + - Other */
79727 +} t_MIBStatistics;
79728 +
79729 +/**************************************************************************//**
79730 + @Description MACSEC SecY Rx SA Statistics
79731 +*//***************************************************************************/
79732 +typedef struct t_FmMacsecSecYRxSaStatistics {
79733 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79734 + frame validation frame validation with the validateFrame not set to disable */
79735 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79736 + validation with the validateFrame set to check */
79737 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79738 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79739 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79740 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79741 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79742 + with validateFrame not in the strict mode and the C bit is cleared */
79743 +} t_FmMacsecSecYRxSaStatistics;
79744 +
79745 +/**************************************************************************//**
79746 + @Description MACSEC SecY Tx SA Statistics
79747 +*//***************************************************************************/
79748 +typedef struct t_FmMacsecSecYTxSaStatistics {
79749 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79750 + be transmitted, which were integrity protected */
79751 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79752 + be transmitted, which were confidentiality protected */
79753 +} t_FmMacsecSecYTxSaStatistics;
79754 +
79755 +/**************************************************************************//**
79756 + @Description MACSEC SecY Rx SC Statistics
79757 +*//***************************************************************************/
79758 +typedef struct t_FmMacsecSecYRxScStatistics {
79759 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79760 + that are not validated with the validateFrame set to disable */
79761 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79762 + that have their PN smaller than the lowest_PN with the validateFrame set to
79763 + disable or replayProtect disabled */
79764 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79765 + that have their PN smaller than the lowest_PN with the validateFrame set to
79766 + Check or Strict and replayProtect enabled */
79767 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79768 + frame validation frame validation with the validateFrame not set to disable */
79769 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79770 + validation with the validateFrame set to check */
79771 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79772 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79773 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79774 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79775 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79776 + with validateFrame not in the strict mode and the C bit is cleared */
79777 +} t_FmMacsecSecYRxScStatistics;
79778 +
79779 +/**************************************************************************//**
79780 + @Description MACSEC SecY Tx SC Statistics
79781 +*//***************************************************************************/
79782 +typedef struct t_FmMacsecSecYTxScStatistics {
79783 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79784 + be transmitted, which were integrity protected */
79785 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79786 + be transmitted, which were confidentiality protected */
79787 +} t_FmMacsecSecYTxScStatistics;
79788 +
79789 +/**************************************************************************//**
79790 + @Description MACSEC SecY Statistics
79791 +*//***************************************************************************/
79792 +typedef struct t_FmMacsecSecYStatistics {
79793 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79794 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79795 +/* Frame verification statistics */
79796 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79797 + (SecTAG) with validateFrames which is not in the strict mode */
79798 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79799 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79800 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79801 + SecTAG or a zero value PN or an invalid ICV */
79802 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79803 + condition : validateFrames is not in the strict mode and the
79804 + C bit in the SecTAG is not set */
79805 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79806 + information with the condition : validateFrames is in the strict mode
79807 + or the C bit in the SecTAG is set */
79808 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79809 + received packets exceeded the cryptographic performance capabilities */
79810 +/* Frame validation statistics */
79811 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79812 + resolved SCI that were integrity protected but not encrypted */
79813 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79814 + resolved SCI that were integrity protected and encrypted */
79815 +/* Frame generation statistics */
79816 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79817 + be transmitted, with protectFrame false */
79818 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79819 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79820 +/* Frame protection statistics */
79821 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79822 + integrity protected but not encrypted */
79823 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79824 + both integrity protected and encrypted */
79825 +} t_FmMacsecSecYStatistics;
79826 +
79827 +
79828 +/**************************************************************************//**
79829 + @Description MACSEC SecY SC Params
79830 +*//***************************************************************************/
79831 +typedef struct t_FmMacsecSecYSCParams {
79832 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79833 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79834 +} t_FmMacsecSecYSCParams;
79835 +
79836 +/**************************************************************************//**
79837 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79838 +
79839 + @Description FM-MACSEC SecY Initialization Unit
79840 +
79841 + @{
79842 +*//***************************************************************************/
79843 +
79844 +/**************************************************************************//**
79845 + @Description enum for validate frames
79846 +*//***************************************************************************/
79847 +typedef enum e_FmMacsecValidFrameBehavior {
79848 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
79849 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
79850 + without filtering out invalid frames */
79851 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
79852 + out those invalid frames */
79853 +} e_FmMacsecValidFrameBehavior;
79854 +
79855 +/**************************************************************************//**
79856 + @Description enum for sci insertion
79857 +*//***************************************************************************/
79858 +typedef enum e_FmMacsecSciInsertionMode {
79859 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
79860 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
79861 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
79862 +} e_FmMacsecSciInsertionMode;
79863 +
79864 +/**************************************************************************//**
79865 + @Description FM MACSEC SecY config input
79866 +*//***************************************************************************/
79867 +typedef struct t_FmMacsecSecYParams {
79868 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
79869 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
79870 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
79871 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
79872 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
79873 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79874 + be passed by the driver upon calling the above callbacks */
79875 +} t_FmMacsecSecYParams;
79876 +
79877 +/**************************************************************************//**
79878 + @Function FM_MACSEC_SECY_Config
79879 +
79880 + @Description Creates descriptor for the FM MACSEC SECY module;
79881 +
79882 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
79883 + This descriptor must be passed as first parameter to all other
79884 + FM MACSEC SECY function calls;
79885 + No actual initialization or configuration of FM MACSEC SecY hardware is
79886 + done by this routine.
79887 +
79888 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
79889 +
79890 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
79891 +*//***************************************************************************/
79892 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
79893 +
79894 +/**************************************************************************//**
79895 + @Function FM_MACSEC_SECY_Init
79896 +
79897 + @Description Initializes the FM MACSEC SECY module.
79898 +
79899 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79900 +
79901 + @Return E_OK on success; Error code otherwise.
79902 +*//***************************************************************************/
79903 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
79904 +
79905 +/**************************************************************************//**
79906 + @Function FM_MACSEC_SECY_Free
79907 +
79908 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
79909 +
79910 + Calling this routine invalidates the descriptor.
79911 +
79912 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79913 +
79914 + @Return E_OK on success; Error code otherwise.
79915 +*//***************************************************************************/
79916 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
79917 +
79918 +/**************************************************************************//**
79919 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
79920 +
79921 + @Description Configuration functions used to change default values.
79922 +
79923 + @{
79924 +*//***************************************************************************/
79925 +
79926 +/**************************************************************************//**
79927 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
79928 +
79929 + @Description Calling this routine changes the SCI-insertion-mode in the
79930 + internal driver data base from its default configuration
79931 + [DEFAULT_sciInsertionMode]
79932 +
79933 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79934 + @Param[in] sciInsertionMode Sci insertion mode
79935 +
79936 + @Return E_OK on success; Error code otherwise.
79937 +
79938 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79939 +
79940 +*//***************************************************************************/
79941 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
79942 +
79943 +/**************************************************************************//**
79944 + @Function FM_MACSEC_SECY_ConfigProtectFrames
79945 +
79946 + @Description Calling this routine changes the protect-frame mode in the
79947 + internal driver data base from its default configuration
79948 + [DEFAULT_protectFrames]
79949 +
79950 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79951 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
79952 +
79953 + @Return E_OK on success; Error code otherwise.
79954 +
79955 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79956 +
79957 +*//***************************************************************************/
79958 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
79959 +
79960 +/**************************************************************************//**
79961 + @Function FM_MACSEC_SECY_ConfigReplayWindow
79962 +
79963 + @Description Calling this routine changes the replay-window settings in the
79964 + internal driver data base from its default configuration
79965 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
79966 +
79967 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79968 + @Param[in] replayProtect; Replay protection function mode
79969 + @Param[in] replayWindow; The size of the replay window
79970 +
79971 + @Return E_OK on success; Error code otherwise.
79972 +
79973 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79974 +
79975 +*//***************************************************************************/
79976 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
79977 +
79978 +/**************************************************************************//**
79979 + @Function FM_MACSEC_SECY_ConfigValidationMode
79980 +
79981 + @Description Calling this routine changes the frame-validation-behavior mode
79982 + in the internal driver data base from its default configuration
79983 + [DEFAULT_validateFrames]
79984 +
79985 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79986 + @Param[in] validateFrames Validation function mode
79987 +
79988 + @Return E_OK on success; Error code otherwise.
79989 +
79990 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79991 +
79992 +*//***************************************************************************/
79993 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
79994 +
79995 +/**************************************************************************//**
79996 + @Function FM_MACSEC_SECY_ConfigConfidentiality
79997 +
79998 + @Description Calling this routine changes the confidentiality settings in the
79999 + internal driver data base from its default configuration
80000 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
80001 +
80002 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80003 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
80004 + FALSE - no confidentiality protection, only integrity protection
80005 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
80006 + common values are 0, 30, and 50
80007 +
80008 + @Return E_OK on success; Error code otherwise.
80009 +
80010 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80011 +
80012 +*//***************************************************************************/
80013 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
80014 +
80015 +/**************************************************************************//**
80016 + @Function FM_MACSEC_SECY_ConfigPointToPoint
80017 +
80018 + @Description configure this SecY to work in point-to-point mode, means that
80019 + it will have only one rx sc;
80020 +
80021 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80022 +
80023 + @Return E_OK on success; Error code otherwise.
80024 +
80025 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80026 + Can be called only once in a system; only the first secY that will call this
80027 + routine will be able to operate in Point-To-Point mode.
80028 +*//***************************************************************************/
80029 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
80030 +
80031 +/**************************************************************************//**
80032 + @Function FM_MACSEC_SECY_ConfigException
80033 +
80034 + @Description Calling this routine changes the internal driver data base
80035 + from its default selection of exceptions enablement;
80036 + By default all exceptions are enabled.
80037 +
80038 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80039 + @Param[in] exception The exception to be selected.
80040 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80041 +
80042 + @Return E_OK on success; Error code otherwise.
80043 +
80044 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80045 +*//***************************************************************************/
80046 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
80047 +
80048 +/**************************************************************************//**
80049 + @Function FM_MACSEC_SECY_ConfigEvent
80050 +
80051 + @Description Calling this routine changes the internal driver data base
80052 + from its default selection of events enablement;
80053 + By default all events are enabled.
80054 +
80055 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80056 + @Param[in] event The event to be selected.
80057 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80058 +
80059 + @Return E_OK on success; Error code otherwise.
80060 +
80061 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80062 +*//***************************************************************************/
80063 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80064 +
80065 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
80066 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
80067 +
80068 +
80069 +/**************************************************************************//**
80070 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
80071 +
80072 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
80073 +
80074 + @{
80075 +*//***************************************************************************/
80076 +
80077 +/**************************************************************************//**
80078 + @Function FM_MACSEC_SECY_CreateRxSc
80079 +
80080 + @Description Create a receive secure channel.
80081 +
80082 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80083 + @Param[in] scParams secure channel params.
80084 +
80085 + @Return E_OK on success; Error code otherwise.
80086 +
80087 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80088 +*//***************************************************************************/
80089 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
80090 +
80091 +/**************************************************************************//**
80092 + @Function FM_MACSEC_SECY_DeleteRxSc
80093 +
80094 + @Description Deleting an initialized secure channel.
80095 +
80096 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80097 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80098 +
80099 + @Return E_OK on success; Error code otherwise.
80100 +
80101 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80102 +*//***************************************************************************/
80103 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
80104 +
80105 +/**************************************************************************//**
80106 + @Function FM_MACSEC_SECY_CreateRxSa
80107 +
80108 + @Description Create a receive secure association for the secure channel;
80109 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
80110 +
80111 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80112 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80113 + @Param[in] an association number represent the SA.
80114 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
80115 + @Param[in] key the desired key for this SA.
80116 +
80117 + @Return E_OK on success; Error code otherwise.
80118 +
80119 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80120 +*//***************************************************************************/
80121 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
80122 +
80123 +/**************************************************************************//**
80124 + @Function FM_MACSEC_SECY_DeleteRxSa
80125 +
80126 + @Description Deleting an initialized secure association.
80127 +
80128 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80129 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80130 + @Param[in] an association number represent the SA.
80131 +
80132 + @Return E_OK on success; Error code otherwise.
80133 +
80134 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80135 +*//***************************************************************************/
80136 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80137 +
80138 +/**************************************************************************//**
80139 + @Function FM_MACSEC_SECY_RxSaEnableReceive
80140 +
80141 + @Description Enabling the SA to receive frames.
80142 +
80143 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80144 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80145 + @Param[in] an association number represent the SA.
80146 +
80147 + @Return E_OK on success; Error code otherwise.
80148 +
80149 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80150 +*//***************************************************************************/
80151 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80152 +
80153 +/**************************************************************************//**
80154 + @Function FM_MACSEC_SECY_RxSaDisableReceive
80155 +
80156 + @Description Disabling the SA from receive frames.
80157 +
80158 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80159 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80160 + @Param[in] an association number represent the SA.
80161 +
80162 + @Return E_OK on success; Error code otherwise.
80163 +
80164 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80165 +*//***************************************************************************/
80166 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80167 +
80168 +/**************************************************************************//**
80169 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
80170 +
80171 + @Description Update the next packet number expected on RX;
80172 + The value of nextPN shall be set to the greater of its existing value and the
80173 + supplied of updtNextPN (802.1AE-2006 10.7.15).
80174 +
80175 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80176 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80177 + @Param[in] an association number represent the SA.
80178 + @Param[in] updtNextPN the next PN value for a received frame.
80179 +
80180 + @Return E_OK on success; Error code otherwise.
80181 +
80182 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80183 +*//***************************************************************************/
80184 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
80185 +
80186 +/**************************************************************************//**
80187 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
80188 +
80189 + @Description Update the lowest packet number expected on RX;
80190 + The value of lowestPN shall be set to the greater of its existing value and the
80191 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
80192 +
80193 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80194 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80195 + @Param[in] an association number represent the SA.
80196 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
80197 +
80198 + @Return E_OK on success; Error code otherwise.
80199 +
80200 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80201 +*//***************************************************************************/
80202 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
80203 +
80204 +/**************************************************************************//**
80205 + @Function FM_MACSEC_SECY_RxSaModifyKey
80206 +
80207 + @Description Modify the current key of the SA with a new one.
80208 +
80209 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80210 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80211 + @Param[in] an association number represent the SA.
80212 + @Param[in] key new key to replace the current key.
80213 +
80214 + @Return E_OK on success; Error code otherwise.
80215 +
80216 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80217 +*//***************************************************************************/
80218 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
80219 +
80220 +/**************************************************************************//**
80221 + @Function FM_MACSEC_SECY_CreateTxSa
80222 +
80223 + @Description Create a transmit secure association for the secure channel;
80224 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
80225 + Only one SA can be active at a time.
80226 +
80227 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80228 + @Param[in] an association number represent the SA.
80229 + @Param[in] key the desired key for this SA.
80230 +
80231 + @Return E_OK on success; Error code otherwise.
80232 +
80233 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80234 +*//***************************************************************************/
80235 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
80236 +
80237 +/**************************************************************************//**
80238 + @Function FM_MACSEC_SECY_DeleteTxSa
80239 +
80240 + @Description Deleting an initialized secure association.
80241 +
80242 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80243 + @Param[in] an association number represent the SA.
80244 +
80245 + @Return E_OK on success; Error code otherwise.
80246 +
80247 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80248 +*//***************************************************************************/
80249 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
80250 +
80251 +/**************************************************************************//**
80252 + @Function FM_MACSEC_SECY_TxSaModifyKey
80253 +
80254 + @Description Modify the key of the inactive SA with a new one.
80255 +
80256 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80257 + @Param[in] nextActiveAn association number represent the next SA to be activated.
80258 + @Param[in] key new key to replace the current key.
80259 +
80260 + @Return E_OK on success; Error code otherwise.
80261 +
80262 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80263 +*//***************************************************************************/
80264 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
80265 +
80266 +/**************************************************************************//**
80267 + @Function FM_MACSEC_SECY_TxSaSetActive
80268 +
80269 + @Description Set this SA to the active SA to be used on TX for SC;
80270 + only one SA can be active at a time.
80271 +
80272 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80273 + @Param[in] an association number represent the SA.
80274 +
80275 + @Return E_OK on success; Error code otherwise.
80276 +
80277 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80278 +*//***************************************************************************/
80279 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
80280 +
80281 +/**************************************************************************//**
80282 + @Function FM_MACSEC_SECY_TxSaGetActive
80283 +
80284 + @Description Get the active SA that being used for TX.
80285 +
80286 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80287 + @Param[out] p_An the active an.
80288 +
80289 + @Return E_OK on success; Error code otherwise.
80290 +
80291 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80292 +*//***************************************************************************/
80293 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
80294 +
80295 +/**************************************************************************//**
80296 + @Function FM_MACSEC_SECY_GetStatistics
80297 +
80298 + @Description get all statistics counters.
80299 +
80300 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80301 + @Param[in] p_Statistics Structure with statistics.
80302 +
80303 + @Return E_OK on success; Error code otherwise.
80304 +
80305 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80306 +*//***************************************************************************/
80307 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
80308 +
80309 +/**************************************************************************//**
80310 + @Function FM_MACSEC_SECY_RxScGetStatistics
80311 +
80312 + @Description get all statistics counters.
80313 +
80314 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80315 + @Param[in] h_Sc Rx Sc handle.
80316 + @Param[in] p_Statistics Structure with statistics.
80317 +
80318 + @Return E_OK on success; Error code otherwise.
80319 +
80320 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80321 +*//***************************************************************************/
80322 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
80323 +
80324 +/**************************************************************************//**
80325 + @Function FM_MACSEC_SECY_RxSaGetStatistics
80326 +
80327 + @Description get all statistics counters
80328 +
80329 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80330 + @Param[in] h_Sc Rx Sc handle.
80331 + @Param[in] an association number represent the SA.
80332 + @Param[in] p_Statistics Structure with statistics.
80333 +
80334 + @Return E_OK on success; Error code otherwise.
80335 +
80336 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80337 +*//***************************************************************************/
80338 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
80339 +
80340 +/**************************************************************************//**
80341 + @Function FM_MACSEC_SECY_TxScGetStatistics
80342 +
80343 + @Description get all statistics counters.
80344 +
80345 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80346 + @Param[in] p_Statistics Structure with statistics.
80347 +
80348 + @Return E_OK on success; Error code otherwise.
80349 +
80350 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80351 +*//***************************************************************************/
80352 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80353 +
80354 +/**************************************************************************//**
80355 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80356 +
80357 + @Description get all statistics counters.
80358 +
80359 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80360 + @Param[in] an association number represent the SA.
80361 + @Param[in] p_Statistics Structure with statistics.
80362 +
80363 + @Return E_OK on success; Error code otherwise.
80364 +
80365 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80366 +*//***************************************************************************/
80367 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80368 +
80369 +/**************************************************************************//**
80370 + @Function FM_MACSEC_SECY_SetException
80371 +
80372 + @Description Calling this routine enables/disables the specified exception.
80373 +
80374 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80375 + @Param[in] exception The exception to be selected.
80376 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80377 +
80378 + @Return E_OK on success; Error code otherwise.
80379 +
80380 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80381 +*//***************************************************************************/
80382 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80383 +
80384 +/**************************************************************************//**
80385 + @Function FM_MACSEC_SECY_SetEvent
80386 +
80387 + @Description Calling this routine enables/disables the specified event.
80388 +
80389 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80390 + @Param[in] event The event to be selected.
80391 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80392 +
80393 + @Return E_OK on success; Error code otherwise.
80394 +
80395 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80396 +*//***************************************************************************/
80397 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80398 +
80399 +/**************************************************************************//**
80400 + @Function FM_MACSEC_SECY_GetRxScPhysId
80401 +
80402 + @Description return the physical id of the Secure Channel.
80403 +
80404 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80405 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80406 + @Param[out] p_ScPhysId the SC physical id.
80407 +
80408 + @Return E_OK on success; Error code otherwise.
80409 +
80410 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80411 +*//***************************************************************************/
80412 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80413 +
80414 +/**************************************************************************//**
80415 + @Function FM_MACSEC_SECY_GetTxScPhysId
80416 +
80417 + @Description return the physical id of the Secure Channel.
80418 +
80419 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80420 + @Param[out] p_ScPhysId the SC physical id.
80421 +
80422 + @Return E_OK on success; Error code otherwise.
80423 +
80424 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80425 +*//***************************************************************************/
80426 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80427 +
80428 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80429 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80430 +/** @} */ /* end of FM_MACSEC_grp group */
80431 +/** @} */ /* end of FM_grp group */
80432 +
80433 +
80434 +#endif /* __FM_MACSEC_EXT_H */
80435 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80436 new file mode 100644
80437 index 00000000..ef62c8ef
80438 --- /dev/null
80439 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80440 @@ -0,0 +1,170 @@
80441 +/*
80442 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80443 + *
80444 + * Redistribution and use in source and binary forms, with or without
80445 + * modification, are permitted provided that the following conditions are met:
80446 + * * Redistributions of source code must retain the above copyright
80447 + * notice, this list of conditions and the following disclaimer.
80448 + * * Redistributions in binary form must reproduce the above copyright
80449 + * notice, this list of conditions and the following disclaimer in the
80450 + * documentation and/or other materials provided with the distribution.
80451 + * * Neither the name of Freescale Semiconductor nor the
80452 + * names of its contributors may be used to endorse or promote products
80453 + * derived from this software without specific prior written permission.
80454 + *
80455 + *
80456 + * ALTERNATIVELY, this software may be distributed under the terms of the
80457 + * GNU General Public License ("GPL") as published by the Free Software
80458 + * Foundation, either version 2 of that License or (at your option) any
80459 + * later version.
80460 + *
80461 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80462 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80463 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80464 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80465 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80466 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80467 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80468 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80469 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80470 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80471 + */
80472 +
80473 +
80474 +/**************************************************************************//**
80475 + @File fm_muram_ext.h
80476 +
80477 + @Description FM MURAM Application Programming Interface.
80478 +*//***************************************************************************/
80479 +#ifndef __FM_MURAM_EXT
80480 +#define __FM_MURAM_EXT
80481 +
80482 +#include "error_ext.h"
80483 +#include "std_ext.h"
80484 +
80485 +
80486 +/**************************************************************************//**
80487 +
80488 + @Group FM_grp Frame Manager API
80489 +
80490 + @Description FM API functions, definitions and enums
80491 +
80492 + @{
80493 +*//***************************************************************************/
80494 +
80495 +/**************************************************************************//**
80496 + @Group FM_muram_grp FM MURAM
80497 +
80498 + @Description FM MURAM API functions, definitions and enums
80499 +
80500 + @{
80501 +*//***************************************************************************/
80502 +
80503 +/**************************************************************************//**
80504 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80505 +
80506 + @Description FM MURAM initialization API functions, definitions and enums
80507 +
80508 + @{
80509 +*//***************************************************************************/
80510 +
80511 +/**************************************************************************//**
80512 + @Function FM_MURAM_ConfigAndInit
80513 +
80514 + @Description Creates partition in the MURAM.
80515 +
80516 + The routine returns a handle (descriptor) to the MURAM partition.
80517 + This descriptor must be passed as first parameter to all other
80518 + FM-MURAM function calls.
80519 +
80520 + No actual initialization or configuration of FM_MURAM hardware is
80521 + done by this routine.
80522 +
80523 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80524 + @Param[in] size - Size of the FM-MURAM partition.
80525 +
80526 + @Return Handle to FM-MURAM object, or NULL for Failure.
80527 +*//***************************************************************************/
80528 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80529 +
80530 +/**************************************************************************//**
80531 + @Function FM_MURAM_Free
80532 +
80533 + @Description Frees all resources that were assigned to FM-MURAM module.
80534 +
80535 + Calling this routine invalidates the descriptor.
80536 +
80537 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80538 +
80539 + @Return E_OK on success; Error code otherwise.
80540 +*//***************************************************************************/
80541 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80542 +
80543 +/** @} */ /* end of FM_muram_init_grp group */
80544 +
80545 +
80546 +/**************************************************************************//**
80547 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80548 +
80549 + @Description FM MURAM control API functions, definitions and enums
80550 +
80551 + @{
80552 +*//***************************************************************************/
80553 +
80554 +/**************************************************************************//**
80555 + @Function FM_MURAM_AllocMem
80556 +
80557 + @Description Allocate some memory from FM-MURAM partition.
80558 +
80559 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80560 + @Param[in] size - size of the memory to be allocated.
80561 + @Param[in] align - Alignment of the memory.
80562 +
80563 + @Return address of the allocated memory; NULL otherwise.
80564 +*//***************************************************************************/
80565 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80566 +
80567 +/**************************************************************************//**
80568 + @Function FM_MURAM_AllocMemForce
80569 +
80570 + @Description Allocate some specific memory from FM-MURAM partition (according
80571 + to base).
80572 +
80573 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80574 + @Param[in] base - the desired base-address to be allocated.
80575 + @Param[in] size - size of the memory to be allocated.
80576 +
80577 + @Return address of the allocated memory; NULL otherwise.
80578 +*//***************************************************************************/
80579 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80580 +
80581 +/**************************************************************************//**
80582 + @Function FM_MURAM_FreeMem
80583 +
80584 + @Description Free an allocated memory from FM-MURAM partition.
80585 +
80586 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80587 + @Param[in] ptr - A pointer to an allocated memory.
80588 +
80589 + @Return E_OK on success; Error code otherwise.
80590 +*//***************************************************************************/
80591 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80592 +
80593 +/**************************************************************************//**
80594 + @Function FM_MURAM_GetFreeMemSize
80595 +
80596 + @Description Returns the size (in bytes) of free MURAM memory.
80597 +
80598 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80599 +
80600 + @Return Free MURAM memory size in bytes.
80601 +*//***************************************************************************/
80602 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80603 +
80604 +/** @} */ /* end of FM_muram_ctrl_grp group */
80605 +/** @} */ /* end of FM_muram_grp group */
80606 +/** @} */ /* end of FM_grp group */
80607 +
80608 +
80609 +
80610 +#endif /* __FM_MURAM_EXT */
80611 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80612 new file mode 100644
80613 index 00000000..8d1c3d88
80614 --- /dev/null
80615 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80616 @@ -0,0 +1,3974 @@
80617 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80618 + * All rights reserved.
80619 + *
80620 + * Redistribution and use in source and binary forms, with or without
80621 + * modification, are permitted provided that the following conditions are met:
80622 + * * Redistributions of source code must retain the above copyright
80623 + * notice, this list of conditions and the following disclaimer.
80624 + * * Redistributions in binary form must reproduce the above copyright
80625 + * notice, this list of conditions and the following disclaimer in the
80626 + * documentation and/or other materials provided with the distribution.
80627 + * * Neither the name of Freescale Semiconductor nor the
80628 + * names of its contributors may be used to endorse or promote products
80629 + * derived from this software without specific prior written permission.
80630 + *
80631 + *
80632 + * ALTERNATIVELY, this software may be distributed under the terms of the
80633 + * GNU General Public License ("GPL") as published by the Free Software
80634 + * Foundation, either version 2 of that License or (at your option) any
80635 + * later version.
80636 + *
80637 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80638 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80639 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80640 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80641 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80642 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80643 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80644 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80645 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80646 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80647 + */
80648 +
80649 +
80650 +/**************************************************************************//**
80651 + @File fm_pcd_ext.h
80652 +
80653 + @Description FM PCD API definitions
80654 +*//***************************************************************************/
80655 +#ifndef __FM_PCD_EXT
80656 +#define __FM_PCD_EXT
80657 +
80658 +#include "std_ext.h"
80659 +#include "net_ext.h"
80660 +#include "list_ext.h"
80661 +#include "fm_ext.h"
80662 +#include "fsl_fman_kg.h"
80663 +
80664 +
80665 +/**************************************************************************//**
80666 + @Group FM_grp Frame Manager API
80667 +
80668 + @Description Frame Manager Application Programming Interface
80669 +
80670 + @{
80671 +*//***************************************************************************/
80672 +
80673 +/**************************************************************************//**
80674 + @Group FM_PCD_grp FM PCD
80675 +
80676 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80677 +
80678 + The FM PCD module is responsible for the initialization of all
80679 + global classifying FM modules. This includes the parser general and
80680 + common registers, the key generator global and common registers,
80681 + and the policer global and common registers.
80682 + In addition, the FM PCD SW module will initialize all required
80683 + key generator schemes, coarse classification flows, and policer
80684 + profiles. When FM module is configured to work with one of these
80685 + entities, it will register to it using the FM PORT API. The PCD
80686 + module will manage the PCD resources - i.e. resource management of
80687 + KeyGen schemes, etc.
80688 +
80689 + @{
80690 +*//***************************************************************************/
80691 +
80692 +/**************************************************************************//**
80693 + @Collection General PCD defines
80694 +*//***************************************************************************/
80695 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80696 +
80697 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80698 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80699 + /**< Number of distinction units is limited by
80700 + register size (32 bits) minus reserved bits
80701 + for private headers. */
80702 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80703 + in a distinction unit */
80704 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80705 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80706 + For HW implementation reasons, in most
80707 + cases less than this will be allowed; The
80708 + driver will return an initialization error
80709 + if resource is unavailable. */
80710 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80711 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80712 +
80713 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80714 +#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)
80715 + /**< Maximum size of SW parser code */
80716 +
80717 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80718 + insert manipulation */
80719 +
80720 +#if (DPAA_VERSION >= 11)
80721 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80722 +#endif /* (DPAA_VERSION >= 11) */
80723 +/* @} */
80724 +
80725 +
80726 +/**************************************************************************//**
80727 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80728 +
80729 + @Description Frame Manager PCD Initialization Unit API
80730 +
80731 + @{
80732 +*//***************************************************************************/
80733 +
80734 +/**************************************************************************//**
80735 + @Description PCD counters
80736 +*//***************************************************************************/
80737 +typedef enum e_FmPcdCounters {
80738 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80739 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80740 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80741 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80742 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80743 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80744 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80745 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80746 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80747 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80748 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80749 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80750 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80751 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80752 + 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. */
80753 + 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. */
80754 + 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. */
80755 + 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. */
80756 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80757 + 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. */
80758 + 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). */
80759 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80760 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80761 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80762 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80763 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80764 +} e_FmPcdCounters;
80765 +
80766 +/**************************************************************************//**
80767 + @Description PCD interrupts
80768 +*//***************************************************************************/
80769 +typedef enum e_FmPcdExceptions {
80770 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80771 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80772 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80773 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80774 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80775 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80776 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80777 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80778 +} e_FmPcdExceptions;
80779 +
80780 +
80781 +/**************************************************************************//**
80782 + @Description Exceptions user callback routine, will be called upon an
80783 + exception passing the exception identification.
80784 +
80785 + @Param[in] h_App - User's application descriptor.
80786 + @Param[in] exception - The exception.
80787 + *//***************************************************************************/
80788 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80789 +
80790 +/**************************************************************************//**
80791 + @Description Exceptions user callback routine, will be called upon an exception
80792 + passing the exception identification.
80793 +
80794 + @Param[in] h_App - User's application descriptor.
80795 + @Param[in] exception - The exception.
80796 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80797 + *//***************************************************************************/
80798 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80799 + e_FmPcdExceptions exception,
80800 + uint16_t index);
80801 +
80802 +/**************************************************************************//**
80803 + @Description A callback for enqueuing frame onto a QM queue.
80804 +
80805 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80806 + @Param[in] p_Fd - Frame descriptor for the frame.
80807 +
80808 + @Return E_OK on success; Error code otherwise.
80809 + *//***************************************************************************/
80810 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80811 +
80812 +/**************************************************************************//**
80813 + @Description Host-Command parameters structure.
80814 +
80815 + When using Host command for PCD functionalities, a dedicated port
80816 + must be used. If this routine is called for a PCD in a single partition
80817 + environment, or it is the Master partition in a Multi-partition
80818 + environment, The port will be initialized by the PCD driver
80819 + initialization routine.
80820 + *//***************************************************************************/
80821 +typedef struct t_FmPcdHcParams {
80822 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80823 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80824 + NOTE: When configuring Host Command port for
80825 + FMANv3 devices (DPAA_VERSION 11 and higher),
80826 + portId=0 MUST be used. */
80827 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80828 + (irrelevant for P4080 revision 1.0) */
80829 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80830 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80831 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80832 + will be used by the FM for dequeue. */
80833 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80834 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80835 +} t_FmPcdHcParams;
80836 +
80837 +/**************************************************************************//**
80838 + @Description The main structure for PCD initialization
80839 + *//***************************************************************************/
80840 +typedef struct t_FmPcdParams {
80841 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80842 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80843 + of the FM ports. */
80844 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80845 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80846 + t_Handle h_Fm; /**< A handle to the FM module. */
80847 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
80848 + this parameter is relevant if 'kgSupport'=TRUE. */
80849 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
80850 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
80851 + Relevant when FM not runs in "guest-mode". */
80852 +
80853 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
80854 + Relevant when FM not runs in "guest-mode". */
80855 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
80856 + Policer profile exceptions;
80857 + Relevant when FM not runs in "guest-mode". */
80858 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80859 + be passed by the driver upon calling the above callbacks;
80860 + Relevant when FM not runs in "guest-mode". */
80861 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
80862 + this parameter is relevant if 'plcrSupport'=TRUE.
80863 + NOTE: this parameter relevant only when working with multiple partitions. */
80864 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
80865 + this parameter is relevant if 'plcrSupport'=TRUE.
80866 + NOTE: this parameter relevant only when working with multiple partitions. */
80867 +} t_FmPcdParams;
80868 +
80869 +
80870 +/**************************************************************************//**
80871 + @Function FM_PCD_Config
80872 +
80873 + @Description Basic configuration of the PCD module.
80874 + Creates descriptor for the FM PCD module.
80875 +
80876 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
80877 +
80878 + @Return A handle to the initialized module.
80879 +*//***************************************************************************/
80880 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
80881 +
80882 +/**************************************************************************//**
80883 + @Function FM_PCD_Init
80884 +
80885 + @Description Initialization of the PCD module.
80886 +
80887 + @Param[in] h_FmPcd - FM PCD module descriptor.
80888 +
80889 + @Return E_OK on success; Error code otherwise.
80890 +*//***************************************************************************/
80891 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
80892 +
80893 +/**************************************************************************//**
80894 + @Function FM_PCD_Free
80895 +
80896 + @Description Frees all resources that were assigned to FM module.
80897 +
80898 + Calling this routine invalidates the descriptor.
80899 +
80900 + @Param[in] h_FmPcd - FM PCD module descriptor.
80901 +
80902 + @Return E_OK on success; Error code otherwise.
80903 +*//***************************************************************************/
80904 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
80905 +
80906 +/**************************************************************************//**
80907 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
80908 +
80909 + @Description Frame Manager PCD Advanced Configuration API.
80910 +
80911 + @{
80912 +*//***************************************************************************/
80913 +
80914 +/**************************************************************************//**
80915 + @Function FM_PCD_ConfigException
80916 +
80917 + @Description Calling this routine changes the internal driver data base
80918 + from its default selection of exceptions enabling.
80919 + [DEFAULT_numOfSharedPlcrProfiles].
80920 +
80921 + @Param[in] h_FmPcd FM PCD module descriptor.
80922 + @Param[in] exception The exception to be selected.
80923 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80924 +
80925 + @Return E_OK on success; Error code otherwise.
80926 +
80927 + @Cautions This routine should NOT be called from guest-partition
80928 + (i.e. guestId != NCSW_MASTER_ID)
80929 +*//***************************************************************************/
80930 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80931 +
80932 +/**************************************************************************//**
80933 + @Function FM_PCD_ConfigHcFramesDataMemory
80934 +
80935 + @Description Configures memory-partition-id for FMan-Controller Host-Command
80936 + frames. Calling this routine changes the internal driver data
80937 + base from its default configuration [0].
80938 +
80939 + @Param[in] h_FmPcd FM PCD module descriptor.
80940 + @Param[in] memId Memory partition ID.
80941 +
80942 + @Return E_OK on success; Error code otherwise.
80943 +
80944 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
80945 + when FM_PCD_Config() routine was called.
80946 +*//***************************************************************************/
80947 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
80948 +
80949 +/**************************************************************************//**
80950 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
80951 +
80952 + @Description Calling this routine changes the internal driver data base
80953 + from its default selection of exceptions enablement.
80954 + [DEFAULT_numOfSharedPlcrProfiles].
80955 +
80956 + @Param[in] h_FmPcd FM PCD module descriptor.
80957 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
80958 + be shared between ports on this partition
80959 +
80960 + @Return E_OK on success; Error code otherwise.
80961 +*//***************************************************************************/
80962 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
80963 +
80964 +/**************************************************************************//**
80965 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
80966 +
80967 + @Description Calling this routine changes the internal driver data base
80968 + from its default selection of exceptions enablement.
80969 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
80970 +
80971 + @Param[in] h_FmPcd FM PCD module descriptor.
80972 + @Param[in] enable TRUE to enable, FALSE to disable
80973 +
80974 + @Return E_OK on success; Error code otherwise.
80975 +
80976 + @Cautions This routine should NOT be called from guest-partition
80977 + (i.e. guestId != NCSW_MASTER_ID)
80978 +*//***************************************************************************/
80979 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
80980 +
80981 +/**************************************************************************//**
80982 + @Function FM_PCD_ConfigPrsMaxCycleLimit
80983 +
80984 + @Description Calling this routine changes the internal data structure for
80985 + the maximum parsing time from its default value
80986 + [DEFAULT_MAX_PRS_CYC_LIM].
80987 +
80988 + @Param[in] h_FmPcd FM PCD module descriptor.
80989 + @Param[in] value 0 to disable the mechanism, or new
80990 + maximum parsing time.
80991 +
80992 + @Return E_OK on success; Error code otherwise.
80993 +
80994 + @Cautions This routine should NOT be called from guest-partition
80995 + (i.e. guestId != NCSW_MASTER_ID)
80996 +*//***************************************************************************/
80997 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
80998 +
80999 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
81000 +/** @} */ /* end of FM_PCD_init_grp group */
81001 +
81002 +
81003 +/**************************************************************************//**
81004 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
81005 +
81006 + @Description Frame Manager PCD Runtime Unit API
81007 +
81008 + The runtime control allows creation of PCD infrastructure modules
81009 + such as Network Environment Characteristics, Classification Plan
81010 + Groups and Coarse Classification Trees.
81011 + It also allows on-the-fly initialization, modification and removal
81012 + of PCD modules such as KeyGen schemes, coarse classification nodes
81013 + and Policer profiles.
81014 +
81015 + In order to explain the programming model of the PCD driver interface
81016 + a few terms should be explained, and will be used below.
81017 + - Distinction Header - One of the 16 protocols supported by the FM parser,
81018 + or one of the SHIM headers (1 or 2). May be a header with a special
81019 + option (see below).
81020 + - Interchangeable Headers Group - This is a group of Headers recognized
81021 + by either one of them. For example, if in a specific context the user
81022 + chooses to treat IPv4 and IPV6 in the same way, they may create an
81023 + interchangeable Headers Unit consisting of these 2 headers.
81024 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
81025 + Group.
81026 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
81027 + IPv6, includes multicast, broadcast and other protocol specific options.
81028 + In terms of hardware it relates to the options available in the classification
81029 + plan.
81030 + - Network Environment Characteristics - a set of Distinction Units that define
81031 + the total recognizable header selection for a certain environment. This is
81032 + NOT the list of all headers that will ever appear in a flow, but rather
81033 + everything that needs distinction in a flow, where distinction is made by KeyGen
81034 + schemes and coarse classification action descriptors.
81035 +
81036 + The PCD runtime modules initialization is done in stages. The first stage after
81037 + initializing the PCD module itself is to establish a Network Flows Environment
81038 + Definition. The application may choose to establish one or more such environments.
81039 + Later, when needed, the application will have to state, for some of its modules,
81040 + to which single environment it belongs.
81041 +
81042 + @{
81043 +*//***************************************************************************/
81044 +
81045 +/**************************************************************************//**
81046 + @Description A structure for SW parser labels
81047 + *//***************************************************************************/
81048 +typedef struct t_FmPcdPrsLabelParams {
81049 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
81050 + resolution), relative to Parser RAM. */
81051 + e_NetHeaderType hdr; /**< The existence of this header will invoke
81052 + the SW parser code; Use HEADER_TYPE_NONE
81053 + to indicate that sw parser is to run
81054 + independent of the existence of any protocol
81055 + (run before HW parser). */
81056 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
81057 + attachments for the same header, use this
81058 + index to distinguish between them. */
81059 +} t_FmPcdPrsLabelParams;
81060 +
81061 +/**************************************************************************//**
81062 + @Description A structure for SW parser
81063 + *//***************************************************************************/
81064 +typedef struct t_FmPcdPrsSwParams {
81065 + bool override; /**< FALSE to invoke a check that nothing else
81066 + was loaded to this address, including
81067 + internal patches.
81068 + TRUE to override any existing code.*/
81069 + uint32_t size; /**< SW parser code size */
81070 + uint16_t base; /**< SW parser base (in instruction counts!
81071 + must be larger than 0x20)*/
81072 + uint8_t *p_Code; /**< SW parser code */
81073 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
81074 + /**< SW parser data (parameters) */
81075 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
81076 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
81077 + /**< SW parser labels table, containing
81078 + numOfLabels entries */
81079 +} t_FmPcdPrsSwParams;
81080 +
81081 +
81082 +/**************************************************************************//**
81083 + @Function FM_PCD_Enable
81084 +
81085 + @Description This routine should be called after PCD is initialized for enabling all
81086 + PCD engines according to their existing configuration.
81087 +
81088 + @Param[in] h_FmPcd FM PCD module descriptor.
81089 +
81090 + @Return E_OK on success; Error code otherwise.
81091 +
81092 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81093 +*//***************************************************************************/
81094 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
81095 +
81096 +/**************************************************************************//**
81097 + @Function FM_PCD_Disable
81098 +
81099 + @Description This routine may be called when PCD is enabled in order to
81100 + disable all PCD engines. It may be called
81101 + only when none of the ports in the system are using the PCD.
81102 +
81103 + @Param[in] h_FmPcd FM PCD module descriptor.
81104 +
81105 + @Return E_OK on success; Error code otherwise.
81106 +
81107 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
81108 +*//***************************************************************************/
81109 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
81110 +
81111 +/**************************************************************************//**
81112 + @Function FM_PCD_GetCounter
81113 +
81114 + @Description Reads one of the FM PCD counters.
81115 +
81116 + @Param[in] h_FmPcd FM PCD module descriptor.
81117 + @Param[in] counter The requested counter.
81118 +
81119 + @Return Counter's current value.
81120 +
81121 + @Cautions Allowed only following FM_PCD_Init().
81122 + Note that it is user's responsibility to call this routine only
81123 + for enabled counters, and there will be no indication if a
81124 + disabled counter is accessed.
81125 +*//***************************************************************************/
81126 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
81127 +
81128 +/**************************************************************************//**
81129 +@Function FM_PCD_PrsLoadSw
81130 +
81131 +@Description This routine may be called in order to load software parsing code.
81132 +
81133 +
81134 +@Param[in] h_FmPcd FM PCD module descriptor.
81135 +@Param[in] p_SwPrs A pointer to a structure of software
81136 + parser parameters, including the software
81137 + parser image.
81138 +
81139 +@Return E_OK on success; Error code otherwise.
81140 +
81141 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81142 + This routine should NOT be called from guest-partition
81143 + (i.e. guestId != NCSW_MASTER_ID)
81144 +*//***************************************************************************/
81145 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
81146 +
81147 +/**************************************************************************//**
81148 +@Function FM_PCD_SetAdvancedOffloadSupport
81149 +
81150 +@Description This routine must be called in order to support the following features:
81151 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
81152 +
81153 +@Param[in] h_FmPcd FM PCD module descriptor.
81154 +
81155 +@Return E_OK on success; Error code otherwise.
81156 +
81157 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81158 + This routine should NOT be called from guest-partition
81159 + (i.e. guestId != NCSW_MASTER_ID)
81160 +*//***************************************************************************/
81161 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
81162 +
81163 +/**************************************************************************//**
81164 + @Function FM_PCD_KgSetDfltValue
81165 +
81166 + @Description Calling this routine sets a global default value to be used
81167 + by the KeyGen when parser does not recognize a required
81168 + field/header.
81169 + By default default values are 0.
81170 +
81171 + @Param[in] h_FmPcd FM PCD module descriptor.
81172 + @Param[in] valueId 0,1 - one of 2 global default values.
81173 + @Param[in] value The requested default value.
81174 +
81175 + @Return E_OK on success; Error code otherwise.
81176 +
81177 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81178 + This routine should NOT be called from guest-partition
81179 + (i.e. guestId != NCSW_MASTER_ID)
81180 +*//***************************************************************************/
81181 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
81182 +
81183 +/**************************************************************************//**
81184 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
81185 +
81186 + @Description Calling this routine allows the KeyGen to access data past
81187 + the parser finishing point.
81188 +
81189 + @Param[in] h_FmPcd FM PCD module descriptor.
81190 + @Param[in] payloadOffset the number of bytes beyond the parser location.
81191 +
81192 + @Return E_OK on success; Error code otherwise.
81193 +
81194 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81195 + This routine should NOT be called from guest-partition
81196 + (i.e. guestId != NCSW_MASTER_ID)
81197 +*//***************************************************************************/
81198 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
81199 +
81200 +/**************************************************************************//**
81201 + @Function FM_PCD_SetException
81202 +
81203 + @Description Calling this routine enables/disables PCD interrupts.
81204 +
81205 + @Param[in] h_FmPcd FM PCD module descriptor.
81206 + @Param[in] exception The exception to be selected.
81207 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81208 +
81209 + @Return E_OK on success; Error code otherwise.
81210 +
81211 + @Cautions Allowed only following FM_PCD_Init().
81212 + This routine should NOT be called from guest-partition
81213 + (i.e. guestId != NCSW_MASTER_ID)
81214 +*//***************************************************************************/
81215 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81216 +
81217 +/**************************************************************************//**
81218 + @Function FM_PCD_ModifyCounter
81219 +
81220 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
81221 +
81222 + @Param[in] h_FmPcd FM PCD module descriptor.
81223 + @Param[in] counter The requested counter.
81224 + @Param[in] value The requested value to be written into the counter.
81225 +
81226 + @Return E_OK on success; Error code otherwise.
81227 +
81228 + @Cautions Allowed only following FM_PCD_Init().
81229 + This routine should NOT be called from guest-partition
81230 + (i.e. guestId != NCSW_MASTER_ID)
81231 +*//***************************************************************************/
81232 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
81233 +
81234 +/**************************************************************************//**
81235 + @Function FM_PCD_SetPlcrStatistics
81236 +
81237 + @Description This routine may be used to enable/disable policer statistics
81238 + counter. By default the statistics is enabled.
81239 +
81240 + @Param[in] h_FmPcd FM PCD module descriptor
81241 + @Param[in] enable TRUE to enable, FALSE to disable.
81242 +
81243 + @Return E_OK on success; Error code otherwise.
81244 +
81245 + @Cautions Allowed only following FM_PCD_Init().
81246 + This routine should NOT be called from guest-partition
81247 + (i.e. guestId != NCSW_MASTER_ID)
81248 +*//***************************************************************************/
81249 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
81250 +
81251 +/**************************************************************************//**
81252 + @Function FM_PCD_SetPrsStatistics
81253 +
81254 + @Description Defines whether to gather parser statistics including all ports.
81255 +
81256 + @Param[in] h_FmPcd FM PCD module descriptor.
81257 + @Param[in] enable TRUE to enable, FALSE to disable.
81258 +
81259 + @Return None
81260 +
81261 + @Cautions Allowed only following FM_PCD_Init().
81262 + This routine should NOT be called from guest-partition
81263 + (i.e. guestId != NCSW_MASTER_ID)
81264 +*//***************************************************************************/
81265 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
81266 +
81267 +/**************************************************************************//**
81268 + @Function FM_PCD_HcTxConf
81269 +
81270 + @Description This routine should be called to confirm frames that were
81271 + received on the HC confirmation queue.
81272 +
81273 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81274 + @Param[in] p_Fd Frame descriptor of the received frame.
81275 +
81276 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
81277 + option was selected in the initialization.
81278 +*//***************************************************************************/
81279 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
81280 +
81281 +/**************************************************************************//*
81282 + @Function FM_PCD_ForceIntr
81283 +
81284 + @Description Causes an interrupt event on the requested source.
81285 +
81286 + @Param[in] h_FmPcd FM PCD module descriptor.
81287 + @Param[in] exception An exception to be forced.
81288 +
81289 + @Return E_OK on success; Error code if the exception is not enabled,
81290 + or is not able to create interrupt.
81291 +
81292 + @Cautions Allowed only following FM_PCD_Init().
81293 + This routine should NOT be called from guest-partition
81294 + (i.e. guestId != NCSW_MASTER_ID)
81295 +*//***************************************************************************/
81296 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
81297 +
81298 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81299 +/**************************************************************************//**
81300 + @Function FM_PCD_DumpRegs
81301 +
81302 + @Description Dumps all PCD registers
81303 +
81304 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81305 +
81306 + @Return E_OK on success; Error code otherwise.
81307 +
81308 + @Cautions Allowed only following FM_PCD_Init().
81309 + NOTE: this routine may be called only for FM in master mode
81310 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81311 + are mapped.
81312 +*//***************************************************************************/
81313 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
81314 +
81315 +/**************************************************************************//**
81316 + @Function FM_PCD_KgDumpRegs
81317 +
81318 + @Description Dumps all PCD KG registers
81319 +
81320 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81321 +
81322 + @Return E_OK on success; Error code otherwise.
81323 +
81324 + @Cautions Allowed only following FM_PCD_Init().
81325 + NOTE: this routine may be called only for FM in master mode
81326 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81327 + are mapped.
81328 +*//***************************************************************************/
81329 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
81330 +
81331 +/**************************************************************************//**
81332 + @Function FM_PCD_PlcrDumpRegs
81333 +
81334 + @Description Dumps all PCD Policer registers
81335 +
81336 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81337 +
81338 + @Return E_OK on success; Error code otherwise.
81339 +
81340 + @Cautions Allowed only following FM_PCD_Init().
81341 + NOTE: this routine may be called only for FM in master mode
81342 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81343 + are mapped.
81344 +*//***************************************************************************/
81345 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
81346 +
81347 +/**************************************************************************//**
81348 + @Function FM_PCD_PlcrProfileDumpRegs
81349 +
81350 + @Description Dumps all PCD Policer profile registers
81351 +
81352 + @Param[in] h_Profile A handle to a Policer profile.
81353 +
81354 + @Return E_OK on success; Error code otherwise.
81355 +
81356 + @Cautions Allowed only following FM_PCD_Init().
81357 + NOTE: this routine may be called only for FM in master mode
81358 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81359 + are mapped.
81360 +*//***************************************************************************/
81361 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81362 +
81363 +/**************************************************************************//**
81364 + @Function FM_PCD_PrsDumpRegs
81365 +
81366 + @Description Dumps all PCD Parser registers
81367 +
81368 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81369 +
81370 + @Return E_OK on success; Error code otherwise.
81371 +
81372 + @Cautions Allowed only following FM_PCD_Init().
81373 + NOTE: this routine may be called only for FM in master mode
81374 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81375 + are mapped.
81376 +*//***************************************************************************/
81377 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81378 +
81379 +/**************************************************************************//**
81380 + @Function FM_PCD_HcDumpRegs
81381 +
81382 + @Description Dumps HC Port registers
81383 +
81384 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81385 +
81386 + @Return E_OK on success; Error code otherwise.
81387 +
81388 + @Cautions Allowed only following FM_PCD_Init().
81389 + NOTE: this routine may be called only for FM in master mode
81390 + (i.e. 'guestId'=NCSW_MASTER_ID).
81391 +*//***************************************************************************/
81392 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81393 +#endif /* (defined(DEBUG_ERRORS) && ... */
81394 +
81395 +
81396 +
81397 +/**************************************************************************//**
81398 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81399 +
81400 + @Description Frame Manager PCD Runtime Building API
81401 +
81402 + This group contains routines for setting, deleting and modifying
81403 + PCD resources, for defining the total PCD tree.
81404 + @{
81405 +*//***************************************************************************/
81406 +
81407 +/**************************************************************************//**
81408 + @Collection Definitions of coarse classification
81409 + parameters as required by KeyGen (when coarse classification
81410 + is the next engine after this scheme).
81411 +*//***************************************************************************/
81412 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81413 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81414 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81415 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81416 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81417 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81418 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81419 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81420 +
81421 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81422 +/* @} */
81423 +
81424 +/**************************************************************************//**
81425 + @Collection A set of definitions to allow protocol
81426 + special option description.
81427 +*//***************************************************************************/
81428 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81429 +
81430 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81431 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81432 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81433 +
81434 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81435 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81436 +
81437 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81438 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81439 +
81440 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81441 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81442 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81443 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81444 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81445 +
81446 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81447 + IPV4 Reassembly manipulation requires network
81448 + environment with IPV4 header and IPV4_FRAG_1 option */
81449 +
81450 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81451 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81452 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81453 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81454 +
81455 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81456 + IPV6 Reassembly manipulation requires network
81457 + environment with IPV6 header and IPV6_FRAG_1 option;
81458 + in case where fragment found, the fragment-extension offset
81459 + may be found at 'shim2' (in parser-result). */
81460 +#if (DPAA_VERSION >= 11)
81461 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81462 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81463 + CAPWAP Reassembly manipulation requires network
81464 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81465 + in case where fragment found, the fragment-extension offset
81466 + may be found at 'shim2' (in parser-result). */
81467 +#endif /* (DPAA_VERSION >= 11) */
81468 +
81469 +
81470 +/* @} */
81471 +
81472 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81473 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81474 +
81475 +/**************************************************************************//**
81476 + @Collection A set of definitions to support Header Manipulation selection.
81477 +*//***************************************************************************/
81478 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81479 +
81480 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81481 +
81482 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81483 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81484 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81485 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81486 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81487 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81488 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81489 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81490 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81491 +
81492 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81493 +
81494 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81495 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81496 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81497 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81498 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81499 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81500 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81501 +
81502 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81503 +
81504 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81505 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81506 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81507 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81508 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81509 +
81510 +/* @} */
81511 +
81512 +/**************************************************************************//**
81513 + @Description A type used for returning the order of the key extraction.
81514 + each value in this array represents the index of the extraction
81515 + command as defined by the user in the initialization extraction array.
81516 + The valid size of this array is the user define number of extractions
81517 + required (also marked by the second '0' in this array).
81518 +*//***************************************************************************/
81519 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81520 +
81521 +/**************************************************************************//**
81522 + @Description All PCD engines
81523 +*//***************************************************************************/
81524 +typedef enum e_FmPcdEngine {
81525 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81526 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81527 + e_FM_PCD_KG, /**< KeyGen */
81528 + e_FM_PCD_CC, /**< Coarse classifier */
81529 + e_FM_PCD_PLCR, /**< Policer */
81530 + e_FM_PCD_PRS, /**< Parser */
81531 +#if (DPAA_VERSION >= 11)
81532 + e_FM_PCD_FR, /**< Frame-Replicator */
81533 +#endif /* (DPAA_VERSION >= 11) */
81534 + e_FM_PCD_HASH /**< Hash table */
81535 +} e_FmPcdEngine;
81536 +
81537 +/**************************************************************************//**
81538 + @Description Enumeration type for selecting extraction by header types
81539 +*//***************************************************************************/
81540 +typedef enum e_FmPcdExtractByHdrType {
81541 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81542 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81543 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81544 +} e_FmPcdExtractByHdrType;
81545 +
81546 +/**************************************************************************//**
81547 + @Description Enumeration type for selecting extraction source
81548 + (when it is not the header)
81549 +*//***************************************************************************/
81550 +typedef enum e_FmPcdExtractFrom {
81551 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81552 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81553 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81554 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81555 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81556 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81557 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81558 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81559 +} e_FmPcdExtractFrom;
81560 +
81561 +/**************************************************************************//**
81562 + @Description Enumeration type for selecting extraction type
81563 +*//***************************************************************************/
81564 +typedef enum e_FmPcdExtractType {
81565 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81566 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81567 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81568 +} e_FmPcdExtractType;
81569 +
81570 +/**************************************************************************//**
81571 + @Description Enumeration type for selecting default extraction value
81572 +*//***************************************************************************/
81573 +typedef enum e_FmPcdKgExtractDfltSelect {
81574 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81575 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81576 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81577 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81578 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81579 +} e_FmPcdKgExtractDfltSelect;
81580 +
81581 +/**************************************************************************//**
81582 + @Description Enumeration type defining all default groups - each group shares
81583 + a default value, one of four user-initialized values.
81584 +*//***************************************************************************/
81585 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81586 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81587 + e_FM_PCD_KG_TCI, /**< TCI field */
81588 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81589 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81590 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81591 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81592 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81593 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81594 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81595 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81596 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81597 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81598 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81599 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81600 + any data extraction that is not the full
81601 + field described above */
81602 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81603 + any data extraction without validation */
81604 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81605 + extraction from parser result or
81606 + direct use of default value */
81607 +} e_FmPcdKgKnownFieldsDfltTypes;
81608 +
81609 +/**************************************************************************//**
81610 + @Description Enumeration type for defining header index for scenarios with
81611 + multiple (tunneled) headers
81612 +*//***************************************************************************/
81613 +typedef enum e_FmPcdHdrIndex {
81614 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81615 + to specify regular IP (not tunneled). */
81616 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81617 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81618 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81619 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81620 +} e_FmPcdHdrIndex;
81621 +
81622 +/**************************************************************************//**
81623 + @Description Enumeration type for selecting the policer profile functional type
81624 +*//***************************************************************************/
81625 +typedef enum e_FmPcdProfileTypeSelection {
81626 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81627 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81628 +} e_FmPcdProfileTypeSelection;
81629 +
81630 +/**************************************************************************//**
81631 + @Description Enumeration type for selecting the policer profile algorithm
81632 +*//***************************************************************************/
81633 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81634 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81635 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81636 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81637 +} e_FmPcdPlcrAlgorithmSelection;
81638 +
81639 +/**************************************************************************//**
81640 + @Description Enumeration type for selecting a policer profile color mode
81641 +*//***************************************************************************/
81642 +typedef enum e_FmPcdPlcrColorMode {
81643 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81644 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81645 +} e_FmPcdPlcrColorMode;
81646 +
81647 +/**************************************************************************//**
81648 + @Description Enumeration type for selecting a policer profile color
81649 +*//***************************************************************************/
81650 +typedef enum e_FmPcdPlcrColor {
81651 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81652 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81653 + e_FM_PCD_PLCR_RED, /**< Red color code */
81654 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81655 +} e_FmPcdPlcrColor;
81656 +
81657 +/**************************************************************************//**
81658 + @Description Enumeration type for selecting the policer profile packet frame length selector
81659 +*//***************************************************************************/
81660 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81661 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81662 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81663 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81664 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81665 +} e_FmPcdPlcrFrameLengthSelect;
81666 +
81667 +/**************************************************************************//**
81668 + @Description Enumeration type for selecting roll-back frame
81669 +*//***************************************************************************/
81670 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81671 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81672 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81673 +} e_FmPcdPlcrRollBackFrameSelect;
81674 +
81675 +/**************************************************************************//**
81676 + @Description Enumeration type for selecting the policer profile packet or byte mode
81677 +*//***************************************************************************/
81678 +typedef enum e_FmPcdPlcrRateMode {
81679 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81680 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81681 +} e_FmPcdPlcrRateMode;
81682 +
81683 +/**************************************************************************//**
81684 + @Description Enumeration type for defining action of frame
81685 +*//***************************************************************************/
81686 +typedef enum e_FmPcdDoneAction {
81687 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81688 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81689 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81690 + flag will be set for this frame. */
81691 +} e_FmPcdDoneAction;
81692 +
81693 +/**************************************************************************//**
81694 + @Description Enumeration type for selecting the policer counter
81695 +*//***************************************************************************/
81696 +typedef enum e_FmPcdPlcrProfileCounters {
81697 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81698 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81699 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81700 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81701 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81702 +} e_FmPcdPlcrProfileCounters;
81703 +
81704 +/**************************************************************************//**
81705 + @Description Enumeration type for selecting the PCD action after extraction
81706 +*//***************************************************************************/
81707 +typedef enum e_FmPcdAction {
81708 + e_FM_PCD_ACTION_NONE, /**< NONE */
81709 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81710 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81711 +} e_FmPcdAction;
81712 +
81713 +/**************************************************************************//**
81714 + @Description Enumeration type for selecting type of insert manipulation
81715 +*//***************************************************************************/
81716 +typedef enum e_FmPcdManipHdrInsrtType {
81717 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81718 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81719 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81720 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81721 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81722 +} e_FmPcdManipHdrInsrtType;
81723 +
81724 +/**************************************************************************//**
81725 + @Description Enumeration type for selecting type of remove manipulation
81726 +*//***************************************************************************/
81727 +typedef enum e_FmPcdManipHdrRmvType {
81728 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81729 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81730 +} e_FmPcdManipHdrRmvType;
81731 +
81732 +/**************************************************************************//**
81733 + @Description Enumeration type for selecting specific L2 fields removal
81734 +*//***************************************************************************/
81735 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81736 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81737 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81738 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81739 + the header which follows the MPLS header */
81740 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81741 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81742 +} e_FmPcdManipHdrRmvSpecificL2;
81743 +
81744 +/**************************************************************************//**
81745 + @Description Enumeration type for selecting specific fields updates
81746 +*//***************************************************************************/
81747 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81748 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81749 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81750 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81751 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81752 +} e_FmPcdManipHdrFieldUpdateType;
81753 +
81754 +/**************************************************************************//**
81755 + @Description Enumeration type for selecting VLAN updates
81756 +*//***************************************************************************/
81757 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81758 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81759 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81760 +} e_FmPcdManipHdrFieldUpdateVlan;
81761 +
81762 +/**************************************************************************//**
81763 + @Description Enumeration type for selecting specific L2 header insertion
81764 +*//***************************************************************************/
81765 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81766 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81767 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81768 +} e_FmPcdManipHdrInsrtSpecificL2;
81769 +
81770 +#if (DPAA_VERSION >= 11)
81771 +/**************************************************************************//**
81772 + @Description Enumeration type for selecting QoS mapping mode
81773 +
81774 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81775 + User should instruct the port to read the hash-result
81776 +*//***************************************************************************/
81777 +typedef enum e_FmPcdManipHdrQosMappingMode {
81778 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81779 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81780 +} e_FmPcdManipHdrQosMappingMode;
81781 +
81782 +/**************************************************************************//**
81783 + @Description Enumeration type for selecting QoS source
81784 +
81785 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81786 + User should left room for the hash-result on input/output buffer
81787 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81788 +*//***************************************************************************/
81789 +typedef enum e_FmPcdManipHdrQosSrc {
81790 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81791 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81792 +} e_FmPcdManipHdrQosSrc;
81793 +#endif /* (DPAA_VERSION >= 11) */
81794 +
81795 +/**************************************************************************//**
81796 + @Description Enumeration type for selecting type of header insertion
81797 +*//***************************************************************************/
81798 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81799 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81800 +#if (DPAA_VERSION >= 11)
81801 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81802 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81803 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81804 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81805 +#endif /* (DPAA_VERSION >= 11) */
81806 +} e_FmPcdManipHdrInsrtByHdrType;
81807 +
81808 +/**************************************************************************//**
81809 + @Description Enumeration type for selecting specific customCommand
81810 +*//***************************************************************************/
81811 +typedef enum e_FmPcdManipHdrCustomType {
81812 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81813 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81814 +} e_FmPcdManipHdrCustomType;
81815 +
81816 +/**************************************************************************//**
81817 + @Description Enumeration type for selecting specific customCommand
81818 +*//***************************************************************************/
81819 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81820 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81821 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81822 +} e_FmPcdManipHdrCustomIpReplace;
81823 +
81824 +/**************************************************************************//**
81825 + @Description Enumeration type for selecting type of header removal
81826 +*//***************************************************************************/
81827 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81828 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81829 +#if (DPAA_VERSION >= 11)
81830 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81831 +#endif /* (DPAA_VERSION >= 11) */
81832 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81833 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81834 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81835 +} e_FmPcdManipHdrRmvByHdrType;
81836 +
81837 +/**************************************************************************//**
81838 + @Description Enumeration type for selecting type of timeout mode
81839 +*//***************************************************************************/
81840 +typedef enum e_FmPcdManipReassemTimeOutMode {
81841 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81842 + from the first fragment to the last */
81843 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81844 +} e_FmPcdManipReassemTimeOutMode;
81845 +
81846 +/**************************************************************************//**
81847 + @Description Enumeration type for selecting type of WaysNumber mode
81848 +*//***************************************************************************/
81849 +typedef enum e_FmPcdManipReassemWaysNumber {
81850 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
81851 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
81852 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
81853 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
81854 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
81855 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
81856 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
81857 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
81858 +} e_FmPcdManipReassemWaysNumber;
81859 +
81860 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81861 +/**************************************************************************//**
81862 + @Description Enumeration type for selecting type of statistics mode
81863 +*//***************************************************************************/
81864 +typedef enum e_FmPcdStatsType {
81865 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
81866 +} e_FmPcdStatsType;
81867 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81868 +
81869 +/**************************************************************************//**
81870 + @Description Enumeration type for selecting manipulation type
81871 +*//***************************************************************************/
81872 +typedef enum e_FmPcdManipType {
81873 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
81874 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
81875 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
81876 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
81877 +} e_FmPcdManipType;
81878 +
81879 +/**************************************************************************//**
81880 + @Description Enumeration type for selecting type of statistics mode
81881 +*//***************************************************************************/
81882 +typedef enum e_FmPcdCcStatsMode {
81883 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
81884 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
81885 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
81886 +#if (DPAA_VERSION >= 11)
81887 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
81888 + This mode is supported only on B4860 device */
81889 +#endif /* (DPAA_VERSION >= 11) */
81890 +} e_FmPcdCcStatsMode;
81891 +
81892 +/**************************************************************************//**
81893 + @Description Enumeration type for determining the action in case an IP packet
81894 + is larger than MTU but its DF (Don't Fragment) bit is set.
81895 +*//***************************************************************************/
81896 +typedef enum e_FmPcdManipDontFragAction {
81897 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
81898 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
81899 + /**< Obsolete, cannot enqueue to error queue;
81900 + In practice, selects to discard packets;
81901 + Will be removed in the future */
81902 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
81903 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
81904 +} e_FmPcdManipDontFragAction;
81905 +
81906 +/**************************************************************************//**
81907 + @Description Enumeration type for selecting type of special offload manipulation
81908 +*//***************************************************************************/
81909 +typedef enum e_FmPcdManipSpecialOffloadType {
81910 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
81911 +#if (DPAA_VERSION >= 11)
81912 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
81913 +#endif /* (DPAA_VERSION >= 11) */
81914 +} e_FmPcdManipSpecialOffloadType;
81915 +
81916 +
81917 +/**************************************************************************//**
81918 + @Description A Union of protocol dependent special options
81919 +*//***************************************************************************/
81920 +typedef union u_FmPcdHdrProtocolOpt {
81921 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
81922 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
81923 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
81924 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
81925 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
81926 +#if (DPAA_VERSION >= 11)
81927 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
81928 +#endif /* (DPAA_VERSION >= 11) */
81929 +} u_FmPcdHdrProtocolOpt;
81930 +
81931 +/**************************************************************************//**
81932 + @Description A union holding protocol fields
81933 +
81934 +
81935 + Fields supported as "full fields":
81936 + HEADER_TYPE_ETH:
81937 + NET_HEADER_FIELD_ETH_DA
81938 + NET_HEADER_FIELD_ETH_SA
81939 + NET_HEADER_FIELD_ETH_TYPE
81940 +
81941 + HEADER_TYPE_LLC_SNAP:
81942 + NET_HEADER_FIELD_LLC_SNAP_TYPE
81943 +
81944 + HEADER_TYPE_VLAN:
81945 + NET_HEADER_FIELD_VLAN_TCI
81946 + (index may apply:
81947 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81948 + e_FM_PCD_HDR_INDEX_LAST)
81949 +
81950 + HEADER_TYPE_MPLS:
81951 + NET_HEADER_FIELD_MPLS_LABEL_STACK
81952 + (index may apply:
81953 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81954 + e_FM_PCD_HDR_INDEX_2,
81955 + e_FM_PCD_HDR_INDEX_LAST)
81956 +
81957 + HEADER_TYPE_IPv4:
81958 + NET_HEADER_FIELD_IPv4_SRC_IP
81959 + NET_HEADER_FIELD_IPv4_DST_IP
81960 + NET_HEADER_FIELD_IPv4_PROTO
81961 + NET_HEADER_FIELD_IPv4_TOS
81962 + (index may apply:
81963 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81964 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81965 +
81966 + HEADER_TYPE_IPv6:
81967 + NET_HEADER_FIELD_IPv6_SRC_IP
81968 + NET_HEADER_FIELD_IPv6_DST_IP
81969 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81970 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
81971 + (index may apply:
81972 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81973 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81974 +
81975 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
81976 + the last next header indication, meaning the next L4, which may be
81977 + present at the Ipv6 last extension. On earlier revisions this field
81978 + applies to the Next-Header field of the main IPv6 header)
81979 +
81980 + HEADER_TYPE_IP:
81981 + NET_HEADER_FIELD_IP_PROTO
81982 + (index may apply:
81983 + e_FM_PCD_HDR_INDEX_LAST)
81984 + NET_HEADER_FIELD_IP_DSCP
81985 + (index may apply:
81986 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
81987 + HEADER_TYPE_GRE:
81988 + NET_HEADER_FIELD_GRE_TYPE
81989 +
81990 + HEADER_TYPE_MINENCAP
81991 + NET_HEADER_FIELD_MINENCAP_SRC_IP
81992 + NET_HEADER_FIELD_MINENCAP_DST_IP
81993 + NET_HEADER_FIELD_MINENCAP_TYPE
81994 +
81995 + HEADER_TYPE_TCP:
81996 + NET_HEADER_FIELD_TCP_PORT_SRC
81997 + NET_HEADER_FIELD_TCP_PORT_DST
81998 + NET_HEADER_FIELD_TCP_FLAGS
81999 +
82000 + HEADER_TYPE_UDP:
82001 + NET_HEADER_FIELD_UDP_PORT_SRC
82002 + NET_HEADER_FIELD_UDP_PORT_DST
82003 +
82004 + HEADER_TYPE_UDP_LITE:
82005 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
82006 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
82007 +
82008 + HEADER_TYPE_IPSEC_AH:
82009 + NET_HEADER_FIELD_IPSEC_AH_SPI
82010 + NET_HEADER_FIELD_IPSEC_AH_NH
82011 +
82012 + HEADER_TYPE_IPSEC_ESP:
82013 + NET_HEADER_FIELD_IPSEC_ESP_SPI
82014 +
82015 + HEADER_TYPE_SCTP:
82016 + NET_HEADER_FIELD_SCTP_PORT_SRC
82017 + NET_HEADER_FIELD_SCTP_PORT_DST
82018 +
82019 + HEADER_TYPE_DCCP:
82020 + NET_HEADER_FIELD_DCCP_PORT_SRC
82021 + NET_HEADER_FIELD_DCCP_PORT_DST
82022 +
82023 + HEADER_TYPE_PPPoE:
82024 + NET_HEADER_FIELD_PPPoE_PID
82025 + NET_HEADER_FIELD_PPPoE_SID
82026 +
82027 + *****************************************************************
82028 + Fields supported as "from fields":
82029 + HEADER_TYPE_ETH (with or without validation):
82030 + NET_HEADER_FIELD_ETH_TYPE
82031 +
82032 + HEADER_TYPE_VLAN (with or without validation):
82033 + NET_HEADER_FIELD_VLAN_TCI
82034 + (index may apply:
82035 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82036 + e_FM_PCD_HDR_INDEX_LAST)
82037 +
82038 + HEADER_TYPE_IPv4 (without validation):
82039 + NET_HEADER_FIELD_IPv4_PROTO
82040 + (index may apply:
82041 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82042 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82043 +
82044 + HEADER_TYPE_IPv6 (without validation):
82045 + NET_HEADER_FIELD_IPv6_NEXT_HDR
82046 + (index may apply:
82047 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82048 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82049 +
82050 +*//***************************************************************************/
82051 +typedef union t_FmPcdFields {
82052 + headerFieldEth_t eth; /**< Ethernet */
82053 + headerFieldVlan_t vlan; /**< VLAN */
82054 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
82055 + headerFieldPppoe_t pppoe; /**< PPPoE */
82056 + headerFieldMpls_t mpls; /**< MPLS */
82057 + headerFieldIp_t ip; /**< IP */
82058 + headerFieldIpv4_t ipv4; /**< IPv4 */
82059 + headerFieldIpv6_t ipv6; /**< IPv6 */
82060 + headerFieldUdp_t udp; /**< UDP */
82061 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
82062 + headerFieldTcp_t tcp; /**< TCP */
82063 + headerFieldSctp_t sctp; /**< SCTP */
82064 + headerFieldDccp_t dccp; /**< DCCP */
82065 + headerFieldGre_t gre; /**< GRE */
82066 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
82067 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
82068 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
82069 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
82070 +} t_FmPcdFields;
82071 +
82072 +/**************************************************************************//**
82073 + @Description Parameters for defining header extraction for key generation
82074 +*//***************************************************************************/
82075 +typedef struct t_FmPcdFromHdr {
82076 + uint8_t size; /**< Size in byte */
82077 + uint8_t offset; /**< Byte offset */
82078 +} t_FmPcdFromHdr;
82079 +
82080 +/**************************************************************************//**
82081 + @Description Parameters for defining field extraction for key generation
82082 +*//***************************************************************************/
82083 +typedef struct t_FmPcdFromField {
82084 + t_FmPcdFields field; /**< Field selection */
82085 + uint8_t size; /**< Size in byte */
82086 + uint8_t offset; /**< Byte offset */
82087 +} t_FmPcdFromField;
82088 +
82089 +/**************************************************************************//**
82090 + @Description Parameters for defining a single network environment unit
82091 +
82092 + A distinction unit should be defined if it will later be used
82093 + by one or more PCD engines to distinguish between flows.
82094 +*//***************************************************************************/
82095 +typedef struct t_FmPcdDistinctionUnit {
82096 + struct {
82097 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
82098 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
82099 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
82100 +} t_FmPcdDistinctionUnit;
82101 +
82102 +/**************************************************************************//**
82103 + @Description Parameters for defining all different distinction units supported
82104 + by a specific PCD Network Environment Characteristics module.
82105 +
82106 + Each unit represent a protocol or a group of protocols that may
82107 + be used later by the different PCD engines to distinguish
82108 + between flows.
82109 +*//***************************************************************************/
82110 +typedef struct t_FmPcdNetEnvParams {
82111 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
82112 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
82113 + different units to be identified */
82114 +} t_FmPcdNetEnvParams;
82115 +
82116 +/**************************************************************************//**
82117 + @Description Parameters for defining a single extraction action when
82118 + creating a key
82119 +*//***************************************************************************/
82120 +typedef struct t_FmPcdExtractEntry {
82121 + e_FmPcdExtractType type; /**< Extraction type select */
82122 + union {
82123 + struct {
82124 + e_NetHeaderType hdr; /**< Header selection */
82125 + bool ignoreProtocolValidation;
82126 + /**< Ignore protocol validation */
82127 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82128 + IP. Otherwise should be cleared. */
82129 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
82130 + union {
82131 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
82132 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
82133 + t_FmPcdFields fullField; /**< Extract full filed parameters */
82134 + } extractByHdrType;
82135 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82136 + struct {
82137 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
82138 + e_FmPcdAction action; /**< Relevant for CC Only */
82139 + uint16_t icIndxMask; /**< Relevant only for CC when
82140 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
82141 + Note that the number of bits that are set within
82142 + this mask must be log2 of the CC-node 'numOfKeys'.
82143 + Note that the mask cannot be set on the lower bits. */
82144 + uint8_t offset; /**< Byte offset */
82145 + uint8_t size; /**< Size in byte */
82146 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82147 + };
82148 +} t_FmPcdExtractEntry;
82149 +
82150 +/**************************************************************************//**
82151 + @Description Parameters for defining masks for each extracted field in the key.
82152 +*//***************************************************************************/
82153 +typedef struct t_FmPcdKgExtractMask {
82154 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
82155 + uint8_t offset; /**< Byte offset */
82156 + uint8_t mask; /**< A byte mask (selected bits will be used) */
82157 +} t_FmPcdKgExtractMask;
82158 +
82159 +/**************************************************************************//**
82160 + @Description Parameters for defining default selection per groups of fields
82161 +*//***************************************************************************/
82162 +typedef struct t_FmPcdKgExtractDflt {
82163 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
82164 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
82165 +} t_FmPcdKgExtractDflt;
82166 +
82167 +/**************************************************************************//**
82168 + @Description Parameters for defining key extraction and hashing
82169 +*//***************************************************************************/
82170 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
82171 + uint32_t privateDflt0; /**< Scheme default register 0 */
82172 + uint32_t privateDflt1; /**< Scheme default register 1 */
82173 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
82174 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
82175 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
82176 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
82177 + /**< For each extraction used in this scheme, specify the required
82178 + default register to be used when header is not found.
82179 + types not specified in this array will get undefined value. */
82180 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
82181 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
82182 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
82183 + result. 0 means using the 24 LSB's, otherwise use the
82184 + 24 LSB's after shifting right.*/
82185 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
82186 + of queues for the key and hash functionality */
82187 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
82188 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
82189 + destination fields on all layers; If TRUE, driver will check that for
82190 + all layers, if SRC extraction is selected, DST extraction must also be
82191 + selected, and vice versa. */
82192 +} t_FmPcdKgKeyExtractAndHashParams;
82193 +
82194 +/**************************************************************************//**
82195 + @Description Parameters for defining a single FQID mask (extracted OR).
82196 +*//***************************************************************************/
82197 +typedef struct t_FmPcdKgExtractedOrParams {
82198 + e_FmPcdExtractType type; /**< Extraction type select */
82199 + union {
82200 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82201 + e_NetHeaderType hdr;
82202 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82203 + IP. Otherwise should be cleared.*/
82204 + bool ignoreProtocolValidation;
82205 + /**< continue extraction even if protocol is not recognized */
82206 + } extractByHdr; /**< Header to extract by */
82207 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82208 + };
82209 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
82210 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
82211 + field not found */
82212 + uint8_t mask; /**< Extraction mask (specified bits are used) */
82213 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
82214 + the extracted byte; Assume byte is placed as the 8 MSB's in
82215 + a 32 bit word where the lower bits
82216 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
82217 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
82218 + extracted byte will effect the 8 LSB's of the FQID,
82219 + if bitOffsetInFqid=31 than the byte's MSB will effect
82220 + the FQID's LSB; 0 means - no effect on FQID;
82221 + Note that one, and only one of
82222 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82223 + extracted byte must effect either FQID or Policer profile).*/
82224 + uint8_t bitOffsetInPlcrProfile;
82225 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
82226 + effect using the extracted byte; Assume byte is placed
82227 + as the 8 MSB's in a 16 bit word where the lower bits
82228 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
82229 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
82230 + than the extracted byte will effect the whole policer profile id,
82231 + if bitOffsetInFqid=15 than the byte's MSB will effect
82232 + the Policer Profile id's LSB;
82233 + 0 means - no effect on policer profile; Note that one, and only one of
82234 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82235 + extracted byte must effect either FQID or Policer profile).*/
82236 +} t_FmPcdKgExtractedOrParams;
82237 +
82238 +/**************************************************************************//**
82239 + @Description Parameters for configuring a scheme counter
82240 +*//***************************************************************************/
82241 +typedef struct t_FmPcdKgSchemeCounter {
82242 + bool update; /**< FALSE to keep the current counter state
82243 + and continue from that point, TRUE to update/reset
82244 + the counter when the scheme is written. */
82245 + uint32_t value; /**< If update=TRUE, this value will be written into the
82246 + counter. clear this field to reset the counter. */
82247 +} t_FmPcdKgSchemeCounter;
82248 +
82249 +/**************************************************************************//**
82250 + @Description Parameters for configuring a policer profile for a KeyGen scheme
82251 + (when policer is the next engine after this scheme).
82252 +*//***************************************************************************/
82253 +typedef struct t_FmPcdKgPlcrProfile {
82254 + bool sharedProfile; /**< TRUE if this profile is shared between ports
82255 + (managed by master partition); Must not be TRUE
82256 + if profile is after Coarse Classification*/
82257 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
82258 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
82259 + together with fqidOffsetShift and numOfProfiles
82260 + parameters, to define a range of profiles from
82261 + which the KeyGen result will determine the
82262 + destination policer profile. */
82263 + union {
82264 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
82265 + should indicate the policer profile offset within the
82266 + port's policer profiles or shared window. */
82267 + struct {
82268 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82269 + final FQID - without the FQID base). */
82270 + uint8_t fqidOffsetRelativeProfileIdBase;
82271 + /**< The base of the FMan Port's relative Storage-Profile ID;
82272 + this value will be "OR'ed" with the KeyGen create FQID
82273 + offset (i.e. not the final FQID - without the FQID base);
82274 + the final result should indicate the Storage-Profile offset
82275 + within the FMan Port's relative Storage-Profiles window/
82276 + (or the SHARED window depends on 'sharedProfile'). */
82277 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
82278 + } indirectProfile; /**< Indirect profile parameters */
82279 + } profileSelect; /**< Direct/indirect profile selection and parameters */
82280 +} t_FmPcdKgPlcrProfile;
82281 +
82282 +#if (DPAA_VERSION >= 11)
82283 +/**************************************************************************//**
82284 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
82285 +*//***************************************************************************/
82286 +typedef struct t_FmPcdKgStorageProfile {
82287 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
82288 + profile id;
82289 + If FALSE, fqidOffsetRelativeProfileIdBase is used
82290 + together with fqidOffsetShift and numOfProfiles
82291 + parameters to define a range of profiles from which
82292 + the KeyGen result will determine the destination
82293 + storage profile. */
82294 + union {
82295 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
82296 + should indicate the storage profile offset within the
82297 + port's storage profiles window. */
82298 + struct {
82299 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82300 + final FQID - without the FQID base). */
82301 + uint8_t fqidOffsetRelativeProfileIdBase;
82302 + /**< The base of the FMan Port's relative Storage-Profile ID;
82303 + this value will be "OR'ed" with the KeyGen create FQID
82304 + offset (i.e. not the final FQID - without the FQID base);
82305 + the final result should indicate the Storage-Profile offset
82306 + within the FMan Port's relative Storage-Profiles window. */
82307 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
82308 + } indirectProfile; /**< Indirect profile parameters. */
82309 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
82310 +} t_FmPcdKgStorageProfile;
82311 +#endif /* (DPAA_VERSION >= 11) */
82312 +
82313 +/**************************************************************************//**
82314 + @Description Parameters for defining CC as the next engine after KeyGen
82315 +*//***************************************************************************/
82316 +typedef struct t_FmPcdKgCc {
82317 + t_Handle h_CcTree; /**< A handle to a CC Tree */
82318 + uint8_t grpId; /**< CC group id within the CC tree */
82319 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
82320 + policing is required. */
82321 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
82322 + selected profile is the one set at port initialization. */
82323 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
82324 + bypassPlcrProfileGeneration = FALSE */
82325 +} t_FmPcdKgCc;
82326 +
82327 +/**************************************************************************//**
82328 + @Description Parameters for defining initializing a KeyGen scheme
82329 +*//***************************************************************************/
82330 +typedef struct t_FmPcdKgSchemeParams {
82331 + bool modify; /**< TRUE to change an existing scheme */
82332 + union
82333 + {
82334 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
82335 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
82336 + } id;
82337 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
82338 + for match vector; KeyGen will ignore it when matching */
82339 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
82340 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82341 + by FM_PCD_NetEnvCharacteristicsSet() */
82342 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
82343 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
82344 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
82345 + } netEnvParams;
82346 + bool useHash; /**< use the KeyGen Hash functionality */
82347 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
82348 + /**< used only if useHash = TRUE */
82349 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
82350 + In such a case FQID after KeyGen will be the default FQID
82351 + defined for the relevant port, or the FQID defined by CC
82352 + in cases where CC was the previous engine. */
82353 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82354 + If hash is used and an even distribution is expected
82355 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82356 + hashDistributionNumOfFqids. */
82357 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82358 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82359 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82360 + registers are shared between qidMasks
82361 + functionality and some of the extraction
82362 + actions; Normally only some will be used
82363 + for qidMask. Driver will return error if
82364 + resource is full at initialization time. */
82365 +
82366 +#if (DPAA_VERSION >= 11)
82367 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82368 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82369 +#endif /* (DPAA_VERSION >= 11) */
82370 +
82371 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82372 + union { /**< depends on nextEngine */
82373 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82374 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82375 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82376 + } kgNextEngineParams;
82377 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82378 + the scheme counter */
82379 +} t_FmPcdKgSchemeParams;
82380 +
82381 +/**************************************************************************//**
82382 + @Collection Definitions for CC statistics
82383 +*//***************************************************************************/
82384 +#if (DPAA_VERSION >= 11)
82385 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82386 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82387 +#endif /* (DPAA_VERSION >= 11) */
82388 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82389 +/* @} */
82390 +
82391 +/**************************************************************************//**
82392 + @Description Parameters for defining CC as the next engine after a CC node.
82393 +*//***************************************************************************/
82394 +typedef struct t_FmPcdCcNextCcParams {
82395 + t_Handle h_CcNode; /**< A handle of the next CC node */
82396 +} t_FmPcdCcNextCcParams;
82397 +
82398 +#if (DPAA_VERSION >= 11)
82399 +/**************************************************************************//**
82400 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82401 +*//***************************************************************************/
82402 +typedef struct t_FmPcdCcNextFrParams {
82403 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82404 +} t_FmPcdCcNextFrParams;
82405 +#endif /* (DPAA_VERSION >= 11) */
82406 +
82407 +/**************************************************************************//**
82408 + @Description Parameters for defining Policer as the next engine after a CC node.
82409 +*//***************************************************************************/
82410 +typedef struct t_FmPcdCcNextPlcrParams {
82411 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82412 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82413 + TRUE if this profile is shared between ports */
82414 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82415 + (otherwise profile id is taken from KeyGen);
82416 + This parameter should indicate the policer
82417 + profile offset within the port's
82418 + policer profiles or from SHARED window.*/
82419 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82420 + FQID for enqueuing the frame;
82421 + In earlier chips if policer next engine is KEYGEN,
82422 + this parameter can be 0, because the KEYGEN
82423 + always decides the enqueue FQID.*/
82424 +#if (DPAA_VERSION >= 11)
82425 + uint8_t newRelativeStorageProfileId;
82426 + /**< Indicates the relative storage profile offset within
82427 + the port's storage profiles window;
82428 + Relevant only if the port was configured with VSP. */
82429 +#endif /* (DPAA_VERSION >= 11) */
82430 +} t_FmPcdCcNextPlcrParams;
82431 +
82432 +/**************************************************************************//**
82433 + @Description Parameters for defining enqueue as the next action after a CC node.
82434 +*//***************************************************************************/
82435 +typedef struct t_FmPcdCcNextEnqueueParams {
82436 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82437 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82438 + relevant if action = e_FM_PCD_ENQ_FRAME */
82439 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82440 + (otherwise FQID is taken from KeyGen),
82441 + relevant if action = e_FM_PCD_ENQ_FRAME */
82442 +#if (DPAA_VERSION >= 11)
82443 + uint8_t newRelativeStorageProfileId;
82444 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82445 + storage profile offset within the port's storage profiles
82446 + window; Relevant only if the port was configured with VSP. */
82447 +#endif /* (DPAA_VERSION >= 11) */
82448 +} t_FmPcdCcNextEnqueueParams;
82449 +
82450 +/**************************************************************************//**
82451 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82452 +*//***************************************************************************/
82453 +typedef struct t_FmPcdCcNextKgParams {
82454 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82455 + Note - this parameters irrelevant for earlier chips */
82456 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82457 + (otherwise FQID is taken from KeyGen),
82458 + Note - this parameters irrelevant for earlier chips */
82459 +#if (DPAA_VERSION >= 11)
82460 + uint8_t newRelativeStorageProfileId;
82461 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82462 + storage profile offset within the port's storage profiles
82463 + window; Relevant only if the port was configured with VSP. */
82464 +#endif /* (DPAA_VERSION >= 11) */
82465 +
82466 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82467 +} t_FmPcdCcNextKgParams;
82468 +
82469 +/**************************************************************************//**
82470 + @Description Parameters for defining the next engine after a CC node.
82471 +*//***************************************************************************/
82472 +typedef struct t_FmPcdCcNextEngineParams {
82473 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82474 + according to nextEngine definition */
82475 + union {
82476 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82477 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82478 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82479 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82480 +#if (DPAA_VERSION >= 11)
82481 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82482 +#endif /* (DPAA_VERSION >= 11) */
82483 + } params; /**< union used for all the next-engine parameters options */
82484 +
82485 + t_Handle h_Manip; /**< Handle to Manipulation object.
82486 + Relevant if next engine is of type result
82487 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82488 +
82489 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82490 + for each frame passing through this
82491 + Coarse Classification entry. */
82492 +} t_FmPcdCcNextEngineParams;
82493 +
82494 +/**************************************************************************//**
82495 + @Description Parameters for defining a single CC key
82496 +*//***************************************************************************/
82497 +typedef struct t_FmPcdCcKeyParams {
82498 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82499 + pointer to the key of the size defined in keySize */
82500 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82501 + pointer to the Mask per key of the size defined
82502 + in keySize. p_Key and p_Mask (if defined) has to be
82503 + of the same size defined in the keySize;
82504 + NOTE that if this value is equal for all entries whithin
82505 + this table, the driver will automatically use global-mask
82506 + (i.e. one common mask for all entries) instead of private
82507 + one; that is done in order to spare some memory and for
82508 + better performance. */
82509 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82510 + /**< parameters for the next for the defined Key in
82511 + the p_Key */
82512 +} t_FmPcdCcKeyParams;
82513 +
82514 +/**************************************************************************//**
82515 + @Description Parameters for defining CC keys parameters
82516 + The driver supports two methods for CC node allocation: dynamic and static.
82517 + Static mode was created in order to prevent runtime alloc/free
82518 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82519 + the driver automatically allocates the memory according to
82520 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82521 + size that may be used for this CC-Node taking into consideration
82522 + 'maskSupport' and 'statisticsMode' parameters.
82523 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82524 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82525 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82526 + all required structures are allocated according to 'numOfKeys'
82527 + parameter. During runtime modification, these structures are
82528 + re-allocated according to the updated number of keys.
82529 +
82530 + Please note that 'action' and 'icIndxMask' mentioned in the
82531 + specific parameter explanations are passed in the extraction
82532 + parameters of the node (fields of extractCcParams.extractNonHdr).
82533 +*//***************************************************************************/
82534 +typedef struct t_KeysParams {
82535 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82536 + A value of zero may be used for dynamic memory allocation. */
82537 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82538 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82539 + Should be TRUE to reserve table memory for key masks, even if
82540 + initial keys do not contain masks, or if the node was initialized
82541 + as 'empty' (without keys); this will allow user to add keys with
82542 + masks at runtime.
82543 + NOTE that if user want to use only global-masks (i.e. one common mask
82544 + for all the entries within this table, this parameter should set to 'FALSE'. */
82545 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82546 + To enable statistics gathering, statistics should be enabled per
82547 + every key, using 'statisticsEn' in next engine parameters structure
82548 + of that key;
82549 + If 'maxNumOfKeys' is set, all required structures will be
82550 + preallocated for all keys. */
82551 +#if (DPAA_VERSION >= 11)
82552 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82553 + /**< Relevant only for 'RMON' statistics mode
82554 + (this feature is supported only on B4860 device);
82555 + Holds a list of programmable thresholds - for each received frame,
82556 + its length in bytes is examined against these range thresholds and
82557 + the appropriate counter is incremented by 1 - for example, to belong
82558 + to range i, the following should hold:
82559 + range i-1 threshold < frame length <= range i threshold
82560 + Each range threshold must be larger then its preceding range
82561 + threshold, and last range threshold must be 0xFFFF. */
82562 +#endif /* (DPAA_VERSION >= 11) */
82563 + uint16_t numOfKeys; /**< Number of initial keys;
82564 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82565 + this field should be power-of-2 of the number of bits that are
82566 + set in 'icIndxMask'. */
82567 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82568 + to be the standard size of the selected key; For other extraction
82569 + types, 'keySize' has to be as size of extraction; When 'action' =
82570 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82571 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82572 + /**< An array with 'numOfKeys' entries, each entry specifies the
82573 + corresponding key parameters;
82574 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82575 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82576 + for the 'miss' entry. */
82577 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82578 + /**< Parameters for defining the next engine when a key is not matched;
82579 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82580 +} t_KeysParams;
82581 +
82582 +
82583 +/**************************************************************************//**
82584 + @Description Parameters for defining a CC node
82585 +*//***************************************************************************/
82586 +typedef struct t_FmPcdCcNodeParams {
82587 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82588 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82589 +} t_FmPcdCcNodeParams;
82590 +
82591 +/**************************************************************************//**
82592 + @Description Parameters for defining a hash table
82593 +*//***************************************************************************/
82594 +typedef struct t_FmPcdHashTableParams {
82595 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82596 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82597 + requested statistics mode will be allocated according to maxNumOfKeys. */
82598 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82599 + that leads to this hash-table. */
82600 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82601 + The number-of-sets for this hash will be calculated
82602 + as (2^(number of bits set in 'hashResMask'));
82603 + The 4 lower bits must be cleared. */
82604 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82605 + 2-bytes to be used as hash index. */
82606 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82607 +
82608 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82609 +
82610 +} t_FmPcdHashTableParams;
82611 +
82612 +/**************************************************************************//**
82613 + @Description Parameters for defining a CC tree group.
82614 +
82615 + This structure defines a CC group in terms of NetEnv units
82616 + and the action to be taken in each case. The unitIds list must
82617 + be given in order from low to high indices.
82618 +
82619 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82620 + structures where each defines the next action to be taken for
82621 + each units combination. for example:
82622 + numOfDistinctionUnits = 2
82623 + unitIds = {1,3}
82624 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82625 + unit 1 - not found; unit 3 - not found;
82626 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82627 + unit 1 - not found; unit 3 - found;
82628 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82629 + unit 1 - found; unit 3 - not found;
82630 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82631 + unit 1 - found; unit 3 - found;
82632 +*//***************************************************************************/
82633 +typedef struct t_FmPcdCcGrpParams {
82634 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82635 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82636 + /**< Indices of the units as defined in
82637 + FM_PCD_NetEnvCharacteristicsSet() */
82638 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82639 + /**< Maximum entries per group is 16 */
82640 +} t_FmPcdCcGrpParams;
82641 +
82642 +/**************************************************************************//**
82643 + @Description Parameters for defining CC tree groups
82644 +*//***************************************************************************/
82645 +typedef struct t_FmPcdCcTreeParams {
82646 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82647 + by FM_PCD_NetEnvCharacteristicsSet() */
82648 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82649 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82650 + /**< Parameters for each group. */
82651 +} t_FmPcdCcTreeParams;
82652 +
82653 +
82654 +/**************************************************************************//**
82655 + @Description CC key statistics structure
82656 +*//***************************************************************************/
82657 +typedef struct t_FmPcdCcKeyStatistics {
82658 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82659 + were matched by this key. */
82660 + uint32_t frameCount; /**< This counter reflects count of frames that
82661 + were matched by this key. */
82662 +#if (DPAA_VERSION >= 11)
82663 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82664 + /**< These counters reflect how many frames matched
82665 + this key in 'RMON' statistics mode:
82666 + Each counter holds the number of frames of a
82667 + specific frames length range, according to the
82668 + ranges provided at initialization. */
82669 +#endif /* (DPAA_VERSION >= 11) */
82670 +} t_FmPcdCcKeyStatistics;
82671 +
82672 +/**************************************************************************//**
82673 + @Description Parameters for defining policer byte rate
82674 +*//***************************************************************************/
82675 +typedef struct t_FmPcdPlcrByteRateModeParams {
82676 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82677 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82678 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82679 +} t_FmPcdPlcrByteRateModeParams;
82680 +
82681 +/**************************************************************************//**
82682 + @Description Parameters for defining the policer profile (based on
82683 + RFC-2698 or RFC-4115 attributes).
82684 +*//***************************************************************************/
82685 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82686 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82687 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82688 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82689 + uint32_t committedBurstSize; /**< Bytes/Packets */
82690 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82691 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82692 +} t_FmPcdPlcrNonPassthroughAlgParams;
82693 +
82694 +/**************************************************************************//**
82695 + @Description Parameters for defining the next engine after policer
82696 +*//***************************************************************************/
82697 +typedef union u_FmPcdPlcrNextEngineParams {
82698 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82699 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82700 + is Policer, must be a SHARED profile */
82701 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82702 +} u_FmPcdPlcrNextEngineParams;
82703 +
82704 +/**************************************************************************//**
82705 + @Description Parameters for defining the policer profile entry
82706 +*//***************************************************************************/
82707 +typedef struct t_FmPcdPlcrProfileParams {
82708 + bool modify; /**< TRUE to change an existing profile */
82709 + union {
82710 + struct {
82711 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82712 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82713 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82714 + } newParams; /**< use it when modify = FALSE */
82715 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82716 + } id;
82717 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82718 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82719 +
82720 + union {
82721 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82722 + any incoming packet with the default value. */
82723 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82724 + pre-color value of 2'b11. */
82725 + } color;
82726 +
82727 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82728 +
82729 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82730 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82731 +
82732 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82733 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82734 +
82735 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82736 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82737 +
82738 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82739 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82740 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82741 +} t_FmPcdPlcrProfileParams;
82742 +
82743 +/**************************************************************************//**
82744 + @Description Parameters for selecting a location for requested manipulation
82745 +*//***************************************************************************/
82746 +typedef struct t_FmManipHdrInfo {
82747 + e_NetHeaderType hdr; /**< Header selection */
82748 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82749 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82750 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82751 +} t_FmManipHdrInfo;
82752 +
82753 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82754 +/**************************************************************************//**
82755 + @Description Parameters for defining an insertion manipulation
82756 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82757 +*//***************************************************************************/
82758 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82759 + uint8_t size; /**< Size of insert template to the start of the frame. */
82760 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82761 + /**< Array of the insertion template. */
82762 +
82763 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82764 + struct {
82765 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82766 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82767 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82768 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82769 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82770 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82771 + 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.*/
82772 + struct {
82773 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82774 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82775 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82776 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82777 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82778 +
82779 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82780 + struct {
82781 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82782 + VPri only 3 bits, it has to be adjusted to the right*/
82783 + } modifyOuterVlanParams;
82784 +} t_FmPcdManipHdrInsrtByTemplateParams;
82785 +
82786 +/**************************************************************************//**
82787 + @Description Parameters for defining CAPWAP fragmentation
82788 +*//***************************************************************************/
82789 +typedef struct t_CapwapFragmentationParams {
82790 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82791 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82792 + and all other fragments exclude the CAPWAP options field,
82793 + FALSE - all fragments include CAPWAP header options field. */
82794 +} t_CapwapFragmentationParams;
82795 +
82796 +/**************************************************************************//**
82797 + @Description Parameters for defining CAPWAP reassembly
82798 +*//***************************************************************************/
82799 +typedef struct t_CapwapReassemblyParams {
82800 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82801 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82802 + maxNumFramesInProcess has to be in the range of 4 - 512,
82803 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82804 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82805 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82806 + and all processed fragments will be enqueued with error indication;
82807 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82808 +
82809 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82810 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82811 + uint32_t timeoutRoutineRequestTime;
82812 + /**< Represents the time interval in microseconds between consecutive
82813 + timeout routine requests It has to be power of 2. */
82814 + uint32_t timeoutThresholdForReassmProcess;
82815 + /**< Time interval (microseconds) for marking frames in process as too old;
82816 + Frames in process are those for which at least one fragment was received
82817 + but not all fragments. */
82818 +
82819 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82820 +} t_CapwapReassemblyParams;
82821 +
82822 +/**************************************************************************//**
82823 + @Description Parameters for defining fragmentation/reassembly manipulation
82824 +*//***************************************************************************/
82825 +typedef struct t_FmPcdManipFragOrReasmParams {
82826 + bool frag; /**< TRUE if using the structure for fragmentation,
82827 + otherwise this structure is used for reassembly */
82828 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82829 + Same LIODN number is used for these buffers as for
82830 + the received frames buffers, so buffers of this pool
82831 + need to be allocated in the same memory area as the
82832 + received buffers. If the received buffers arrive
82833 + from different sources, the Scatter/Gather BP id
82834 + should be mutual to all these sources. */
82835 + e_NetHeaderType hdr; /**< Header selection */
82836 + union {
82837 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82838 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82839 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82840 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82841 + } u;
82842 +} t_FmPcdManipFragOrReasmParams;
82843 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82844 +
82845 +
82846 +/**************************************************************************//**
82847 + @Description Parameters for defining header removal by header type
82848 +*//***************************************************************************/
82849 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
82850 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
82851 + union {
82852 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82853 + struct {
82854 + bool include; /**< If FALSE, remove until the specified header (not including the header);
82855 + If TRUE, remove also the specified header. */
82856 + t_FmManipHdrInfo hdrInfo;
82857 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82858 +#endif /* (DPAA_VERSION >= 11) || ... */
82859 +#if (DPAA_VERSION >= 11)
82860 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82861 +#endif /* (DPAA_VERSION >= 11) */
82862 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
82863 + Defines which L2 headers to remove. */
82864 + } u;
82865 +} t_FmPcdManipHdrRmvByHdrParams;
82866 +
82867 +/**************************************************************************//**
82868 + @Description Parameters for configuring IP fragmentation manipulation
82869 +
82870 + Restrictions:
82871 + - IP Fragmentation output fragments must not be forwarded to application directly.
82872 + - Maximum number of fragments per frame is 16.
82873 + - Fragmentation of IP fragments is not supported.
82874 + - IPv4 packets containing header Option fields are fragmented by copying all option
82875 + fields to each fragment, regardless of the copy bit value.
82876 + - Transmit confirmation is not supported.
82877 + - Fragmentation after SEC can't handle S/G frames.
82878 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82879 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82880 + - Only BMan buffers shall be used for frames to be fragmented.
82881 + - IPF does not support VSP. Therefore, on the same port where we have IPF
82882 + we cannot support VSP.
82883 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82884 + does not support VSP. Therefore, on the same port where we have IPF we
82885 + cannot support VSP.
82886 +*//***************************************************************************/
82887 +typedef struct t_FmPcdManipFragIpParams {
82888 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82889 + IP fragmentation will be executed.*/
82890 +#if (DPAA_VERSION == 10)
82891 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
82892 +#endif /* (DPAA_VERSION == 10) */
82893 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82894 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82895 + received frame's buffer. */
82896 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82897 + This parameters is relevant when 'sgBpidEn=TRUE';
82898 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82899 + of this pool need to be allocated in the same memory area as the received buffers.
82900 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82901 + mutual to all these sources. */
82902 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
82903 + than MTU and its DF bit is set, then this field will
82904 + determine the action to be taken.*/
82905 +} t_FmPcdManipFragIpParams;
82906 +
82907 +/**************************************************************************//**
82908 + @Description Parameters for configuring IP reassembly manipulation.
82909 +
82910 + This is a common structure for both IPv4 and IPv6 reassembly
82911 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
82912 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
82913 +
82914 + Restrictions:
82915 + - Application must define at least one scheme to catch the reassembled frames.
82916 + - Maximum number of fragments per frame is 16.
82917 + - Reassembly of IPv4 fragments containing Option fields is supported.
82918 +
82919 +*//***************************************************************************/
82920 +typedef struct t_FmPcdManipReassemIpParams {
82921 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
82922 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
82923 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
82924 + NOTE: The following comment is relevant only for FMAN v2 devices:
82925 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
82926 + the user schemes id to ensure that the reassembly schemes will be first match;
82927 + Rest schemes, if defined, should have higher relative scheme ID. */
82928 +#if (DPAA_VERSION >= 11)
82929 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
82930 + profile than the opening fragment (Non-Consistent-SP state)
82931 + then one of two possible scenarios occurs:
82932 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
82933 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
82934 +#else
82935 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
82936 +#endif /* (DPAA_VERSION >= 11) */
82937 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82938 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82939 + uint16_t minFragSize[2]; /**< Minimum fragment size:
82940 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
82941 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
82942 + /**< Number of frames per hash entry needed for reassembly process:
82943 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
82944 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
82945 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
82946 + Must be power of 2;
82947 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82948 + maxNumFramesInProcess has to be in the range of 4 - 512;
82949 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82950 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82951 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82952 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82953 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82954 + uint32_t timeoutThresholdForReassmProcess;
82955 + /**< Represents the time interval in microseconds which defines
82956 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82957 +} t_FmPcdManipReassemIpParams;
82958 +
82959 +/**************************************************************************//**
82960 + @Description structure for defining IPSEC manipulation
82961 +*//***************************************************************************/
82962 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
82963 + bool decryption; /**< TRUE if being used in decryption direction;
82964 + FALSE if being used in encryption direction. */
82965 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
82966 + (direction depends on the 'decryption' field). */
82967 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
82968 + (direction depends on the 'decryption' field). */
82969 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
82970 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
82971 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
82972 + It is specifies the length of the outer IP header that was configured in the
82973 + corresponding SA. */
82974 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
82975 + The value must be a multiplication of 16 */
82976 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
82977 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
82978 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
82979 +} t_FmPcdManipSpecialOffloadIPSecParams;
82980 +
82981 +#if (DPAA_VERSION >= 11)
82982 +/**************************************************************************//**
82983 + @Description Parameters for configuring CAPWAP fragmentation manipulation
82984 +
82985 + Restrictions:
82986 + - Maximum number of fragments per frame is 16.
82987 + - Transmit confirmation is not supported.
82988 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82989 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82990 + - Only BMan buffers shall be used for frames to be fragmented.
82991 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82992 + does not support VSP. Therefore, on the same port where we have IPF we
82993 + cannot support VSP.
82994 +*//***************************************************************************/
82995 +typedef struct t_FmPcdManipFragCapwapParams {
82996 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82997 + CAPWAP fragmentation will be executed.*/
82998 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82999 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
83000 + received frame's buffer. */
83001 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
83002 + This parameters is relevant when 'sgBpidEn=TRUE';
83003 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
83004 + of this pool need to be allocated in the same memory area as the received buffers.
83005 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
83006 + mutual to all these sources. */
83007 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
83008 + When this mode is enabled then only the first fragment include the CAPWAP header options
83009 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
83010 + options field (CAPWAP header is updated accordingly).*/
83011 +} t_FmPcdManipFragCapwapParams;
83012 +
83013 +/**************************************************************************//**
83014 + @Description Parameters for configuring CAPWAP reassembly manipulation.
83015 +
83016 + Restrictions:
83017 + - Application must define one scheme to catch the reassembled frames.
83018 + - Maximum number of fragments per frame is 16.
83019 +
83020 +*//***************************************************************************/
83021 +typedef struct t_FmPcdManipReassemCapwapParams {
83022 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
83023 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
83024 + Rest schemes, if defined, should have higher relative scheme ID. */
83025 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
83026 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
83027 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
83028 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
83029 + considered as a valid length;
83030 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
83031 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
83032 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
83033 + /**< Number of frames per hash entry needed for reassembly process */
83034 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
83035 + Must be power of 2;
83036 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
83037 + maxNumFramesInProcess has to be in the range of 4 - 512;
83038 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
83039 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
83040 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
83041 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
83042 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
83043 + uint32_t timeoutThresholdForReassmProcess;
83044 + /**< Represents the time interval in microseconds which defines
83045 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
83046 +} t_FmPcdManipReassemCapwapParams;
83047 +
83048 +/**************************************************************************//**
83049 + @Description structure for defining CAPWAP manipulation
83050 +*//***************************************************************************/
83051 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
83052 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
83053 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
83054 +} t_FmPcdManipSpecialOffloadCapwapParams;
83055 +
83056 +#endif /* (DPAA_VERSION >= 11) */
83057 +
83058 +
83059 +/**************************************************************************//**
83060 + @Description Parameters for defining special offload manipulation
83061 +*//***************************************************************************/
83062 +typedef struct t_FmPcdManipSpecialOffloadParams {
83063 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
83064 + union
83065 + {
83066 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
83067 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
83068 +#if (DPAA_VERSION >= 11)
83069 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
83070 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
83071 +#endif /* (DPAA_VERSION >= 11) */
83072 + } u;
83073 +} t_FmPcdManipSpecialOffloadParams;
83074 +
83075 +/**************************************************************************//**
83076 + @Description Parameters for defining insertion manipulation
83077 +*//***************************************************************************/
83078 +typedef struct t_FmPcdManipHdrInsrt {
83079 + uint8_t size; /**< size of inserted section */
83080 + uint8_t *p_Data; /**< data to be inserted */
83081 +} t_FmPcdManipHdrInsrt;
83082 +
83083 +
83084 +/**************************************************************************//**
83085 + @Description Parameters for defining generic removal manipulation
83086 +*//***************************************************************************/
83087 +typedef struct t_FmPcdManipHdrRmvGenericParams {
83088 + uint8_t offset; /**< Offset from beginning of header to the start
83089 + location of the removal */
83090 + uint8_t size; /**< Size of removed section */
83091 +} t_FmPcdManipHdrRmvGenericParams;
83092 +
83093 +/**************************************************************************//**
83094 + @Description Parameters for defining generic insertion manipulation
83095 +*//***************************************************************************/
83096 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
83097 + uint8_t offset; /**< Offset from beginning of header to the start
83098 + location of the insertion */
83099 + uint8_t size; /**< Size of inserted section */
83100 + bool replace; /**< TRUE to override (replace) existing data at
83101 + 'offset', FALSE to insert */
83102 + uint8_t *p_Data; /**< Pointer to data to be inserted */
83103 +} t_FmPcdManipHdrInsrtGenericParams;
83104 +
83105 +/**************************************************************************//**
83106 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
83107 +*//***************************************************************************/
83108 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
83109 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
83110 + /**< A table of VPri values for each DSCP value;
83111 + The index is the DSCP value (0-0x3F) and the
83112 + value is the corresponding VPRI (0-15). */
83113 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
83114 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
83115 + this field is the Q Tag default value if the
83116 + IP header is not found. */
83117 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
83118 +
83119 +/**************************************************************************//**
83120 + @Description Parameters for defining header manipulation VLAN fields updates
83121 +*//***************************************************************************/
83122 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
83123 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
83124 + union {
83125 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
83126 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
83127 + is the new VLAN pri. */
83128 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
83129 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
83130 + } u;
83131 +} t_FmPcdManipHdrFieldUpdateVlan;
83132 +
83133 +/**************************************************************************//**
83134 + @Description Parameters for defining header manipulation IPV4 fields updates
83135 +*//***************************************************************************/
83136 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
83137 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83138 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
83139 + HDR_MANIP_IPV4_TOS */
83140 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
83141 + contains HDR_MANIP_IPV4_ID */
83142 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
83143 + contains HDR_MANIP_IPV4_SRC */
83144 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
83145 + contains HDR_MANIP_IPV4_DST */
83146 +} t_FmPcdManipHdrFieldUpdateIpv4;
83147 +
83148 +/**************************************************************************//**
83149 + @Description Parameters for defining header manipulation IPV6 fields updates
83150 +*//***************************************************************************/
83151 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
83152 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83153 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
83154 + HDR_MANIP_IPV6_TC */
83155 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83156 + /**< 16 byte new IP SRC; Relevant only if validUpdates
83157 + contains HDR_MANIP_IPV6_SRC */
83158 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83159 + /**< 16 byte new IP DST; Relevant only if validUpdates
83160 + contains HDR_MANIP_IPV6_DST */
83161 +} t_FmPcdManipHdrFieldUpdateIpv6;
83162 +
83163 +/**************************************************************************//**
83164 + @Description Parameters for defining header manipulation TCP/UDP fields updates
83165 +*//***************************************************************************/
83166 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
83167 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83168 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
83169 + contains HDR_MANIP_TCP_UDP_SRC */
83170 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
83171 + contains HDR_MANIP_TCP_UDP_DST */
83172 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
83173 +
83174 +/**************************************************************************//**
83175 + @Description Parameters for defining header manipulation fields updates
83176 +*//***************************************************************************/
83177 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
83178 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
83179 + union {
83180 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
83181 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
83182 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
83183 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
83184 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
83185 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
83186 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
83187 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
83188 + } u;
83189 +} t_FmPcdManipHdrFieldUpdateParams;
83190 +
83191 +
83192 +
83193 +/**************************************************************************//**
83194 + @Description Parameters for defining custom header manipulation for generic field replacement
83195 +*//***************************************************************************/
83196 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
83197 + uint8_t srcOffset; /**< Location of new data - Offset from
83198 + Parse Result (>= 16, srcOffset+size <= 32, ) */
83199 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
83200 + start of frame (dstOffset + size <= 256). */
83201 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
83202 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
83203 + replacement (1 - bit will be replaced);
83204 + Clear to use field as is. */
83205 + uint8_t maskOffset; /**< Relevant if mask != 0;
83206 + Mask offset within the replaces "size" */
83207 +} t_FmPcdManipHdrCustomGenFieldReplace;
83208 +
83209 +/**************************************************************************//**
83210 + @Description Parameters for defining custom header manipulation for IP replacement
83211 +*//***************************************************************************/
83212 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
83213 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
83214 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
83215 + bool updateIpv4Id; /**< Relevant when replaceType =
83216 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
83217 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
83218 + updateIpv4Id = TRUE */
83219 + uint8_t hdrSize; /**< The size of the new IP header */
83220 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
83221 + /**< The new IP header */
83222 +} t_FmPcdManipHdrCustomIpHdrReplace;
83223 +
83224 +/**************************************************************************//**
83225 + @Description Parameters for defining custom header manipulation
83226 +*//***************************************************************************/
83227 +typedef struct t_FmPcdManipHdrCustomParams {
83228 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
83229 + union {
83230 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
83231 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
83232 + } u;
83233 +} t_FmPcdManipHdrCustomParams;
83234 +
83235 +/**************************************************************************//**
83236 + @Description Parameters for defining specific L2 insertion manipulation
83237 +*//***************************************************************************/
83238 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
83239 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
83240 + bool update; /**< TRUE to update MPLS header */
83241 + uint8_t size; /**< size of inserted section */
83242 + uint8_t *p_Data; /**< data to be inserted */
83243 +} t_FmPcdManipHdrInsrtSpecificL2Params;
83244 +
83245 +#if (DPAA_VERSION >= 11)
83246 +/**************************************************************************//**
83247 + @Description Parameters for defining IP insertion manipulation
83248 +*//***************************************************************************/
83249 +typedef struct t_FmPcdManipHdrInsrtIpParams {
83250 + bool calcL4Checksum; /**< Calculate L4 checksum. */
83251 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
83252 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
83253 + the inserted header */
83254 + uint16_t id; /**< 16 bit New IP ID */
83255 + bool dontFragOverwrite;
83256 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
83257 + * This byte is configured to be overwritten when RPD is set. */
83258 + uint8_t lastDstOffset;
83259 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
83260 + * in order to calculate UDP checksum pseudo header;
83261 + * Otherwise set it to '0'. */
83262 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
83263 +} t_FmPcdManipHdrInsrtIpParams;
83264 +#endif /* (DPAA_VERSION >= 11) */
83265 +
83266 +/**************************************************************************//**
83267 + @Description Parameters for defining header insertion manipulation by header type
83268 +*//***************************************************************************/
83269 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
83270 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
83271 + union {
83272 +
83273 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
83274 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
83275 + Selects which L2 headers to insert */
83276 +#if (DPAA_VERSION >= 11)
83277 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
83278 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
83279 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
83280 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
83281 +#endif /* (DPAA_VERSION >= 11) */
83282 + } u;
83283 +} t_FmPcdManipHdrInsrtByHdrParams;
83284 +
83285 +/**************************************************************************//**
83286 + @Description Parameters for defining header insertion manipulation
83287 +*//***************************************************************************/
83288 +typedef struct t_FmPcdManipHdrInsrtParams {
83289 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
83290 + union {
83291 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
83292 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
83293 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
83294 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
83295 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83296 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
83297 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
83298 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83299 + } u;
83300 +} t_FmPcdManipHdrInsrtParams;
83301 +
83302 +/**************************************************************************//**
83303 + @Description Parameters for defining header removal manipulation
83304 +*//***************************************************************************/
83305 +typedef struct t_FmPcdManipHdrRmvParams {
83306 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
83307 + union {
83308 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
83309 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
83310 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
83311 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
83312 + } u;
83313 +} t_FmPcdManipHdrRmvParams;
83314 +
83315 +/**************************************************************************//**
83316 + @Description Parameters for defining header manipulation node
83317 +*//***************************************************************************/
83318 +typedef struct t_FmPcdManipHdrParams {
83319 + bool rmv; /**< TRUE, to define removal manipulation */
83320 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
83321 +
83322 + bool insrt; /**< TRUE, to define insertion manipulation */
83323 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
83324 +
83325 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
83326 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
83327 +
83328 + bool custom; /**< TRUE, to define custom manipulation */
83329 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
83330 +
83331 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
83332 + Restrictions:
83333 + 1. MUST be set if the next engine after the CC is not another CC node
83334 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
83335 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
83336 + also never pointed as h_NextManip of other manipulation nodes)
83337 + 2. MUST be set if the next engine after the CC is another CC node, and
83338 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
83339 +} t_FmPcdManipHdrParams;
83340 +
83341 +/**************************************************************************//**
83342 + @Description Parameters for defining fragmentation manipulation
83343 +*//***************************************************************************/
83344 +typedef struct t_FmPcdManipFragParams {
83345 + e_NetHeaderType hdr; /**< Header selection */
83346 + union {
83347 +#if (DPAA_VERSION >= 11)
83348 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
83349 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83350 +#endif /* (DPAA_VERSION >= 11) */
83351 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83352 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83353 + } u;
83354 +} t_FmPcdManipFragParams;
83355 +
83356 +/**************************************************************************//**
83357 + @Description Parameters for defining reassembly manipulation
83358 +*//***************************************************************************/
83359 +typedef struct t_FmPcdManipReassemParams {
83360 + e_NetHeaderType hdr; /**< Header selection */
83361 + union {
83362 +#if (DPAA_VERSION >= 11)
83363 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83364 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83365 +#endif /* (DPAA_VERSION >= 11) */
83366 +
83367 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83368 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83369 + } u;
83370 +} t_FmPcdManipReassemParams;
83371 +
83372 +/**************************************************************************//**
83373 + @Description Parameters for defining a manipulation node
83374 +*//***************************************************************************/
83375 +typedef struct t_FmPcdManipParams {
83376 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83377 + union{
83378 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83379 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83380 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83381 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83382 + } u;
83383 +
83384 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83385 + Handle to another (previously defined) manipulation node;
83386 + Allows concatenation of manipulation actions;
83387 + This parameter is optional and may be NULL. */
83388 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83389 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83390 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83391 + relevant if fragOrReasm = TRUE */
83392 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83393 +} t_FmPcdManipParams;
83394 +
83395 +/**************************************************************************//**
83396 + @Description Structure for retrieving IP reassembly statistics
83397 +*//***************************************************************************/
83398 +typedef struct t_FmPcdManipReassemIpStats {
83399 + /* common counters for both IPv4 and IPv6 */
83400 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83401 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83402 + a Reassembly Frame Descriptor */
83403 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83404 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83405 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83406 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83407 +#if (DPAA_VERSION >= 11)
83408 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83409 + successfully reassembled frames */
83410 +#endif /* (DPAA_VERSION >= 11) */
83411 + struct {
83412 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83413 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83414 + have been processed for all frames */
83415 + uint32_t processedFragments; /**< Counts the number of processed fragments
83416 + (valid and error fragments) for all frames */
83417 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83418 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83419 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83420 + to access an IP-Reassembly Automatic Learning Hash set */
83421 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83422 + exceeds 16 */
83423 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83424 +} t_FmPcdManipReassemIpStats;
83425 +
83426 +/**************************************************************************//**
83427 + @Description Structure for retrieving IP fragmentation statistics
83428 +*//***************************************************************************/
83429 +typedef struct t_FmPcdManipFragIpStats {
83430 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83431 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83432 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83433 +} t_FmPcdManipFragIpStats;
83434 +
83435 +#if (DPAA_VERSION >= 11)
83436 +/**************************************************************************//**
83437 + @Description Structure for retrieving CAPWAP reassembly statistics
83438 +*//***************************************************************************/
83439 +typedef struct t_FmPcdManipReassemCapwapStats {
83440 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83441 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83442 + a Reassembly Frame Descriptor */
83443 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83444 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83445 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83446 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83447 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83448 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83449 + have been processed for all frames */
83450 + uint32_t processedFragments; /**< Counts the number of processed fragments
83451 + (valid and error fragments) for all frames */
83452 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83453 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83454 + to access an Reassembly Automatic Learning Hash set */
83455 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83456 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83457 + exceeds 16 */
83458 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83459 + length exceeds MaxReassembledFrameLength value */
83460 +} t_FmPcdManipReassemCapwapStats;
83461 +
83462 +/**************************************************************************//**
83463 + @Description Structure for retrieving CAPWAP fragmentation statistics
83464 +*//***************************************************************************/
83465 +typedef struct t_FmPcdManipFragCapwapStats {
83466 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83467 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83468 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83469 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83470 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83471 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83472 +} t_FmPcdManipFragCapwapStats;
83473 +#endif /* (DPAA_VERSION >= 11) */
83474 +
83475 +/**************************************************************************//**
83476 + @Description Structure for retrieving reassembly statistics
83477 +*//***************************************************************************/
83478 +typedef struct t_FmPcdManipReassemStats {
83479 + union {
83480 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83481 +#if (DPAA_VERSION >= 11)
83482 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83483 +#endif /* (DPAA_VERSION >= 11) */
83484 + } u;
83485 +} t_FmPcdManipReassemStats;
83486 +
83487 +/**************************************************************************//**
83488 + @Description Structure for retrieving fragmentation statistics
83489 +*//***************************************************************************/
83490 +typedef struct t_FmPcdManipFragStats {
83491 + union {
83492 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83493 +#if (DPAA_VERSION >= 11)
83494 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83495 +#endif /* (DPAA_VERSION >= 11) */
83496 + } u;
83497 +} t_FmPcdManipFragStats;
83498 +
83499 +/**************************************************************************//**
83500 + @Description Structure for selecting manipulation statistics
83501 +*//***************************************************************************/
83502 +typedef struct t_FmPcdManipStats {
83503 + union {
83504 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83505 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83506 + } u;
83507 +} t_FmPcdManipStats;
83508 +
83509 +#if (DPAA_VERSION >= 11)
83510 +/**************************************************************************//**
83511 + @Description Parameters for defining frame replicator group and its members
83512 +*//***************************************************************************/
83513 +typedef struct t_FmPcdFrmReplicGroupParams {
83514 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83515 + Must be at least 2. */
83516 + uint8_t numOfEntries; /**< Number of members in the group;
83517 + Must be at least 1. */
83518 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83519 + /**< Array of members' parameters */
83520 +} t_FmPcdFrmReplicGroupParams;
83521 +#endif /* (DPAA_VERSION >= 11) */
83522 +
83523 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83524 +/**************************************************************************//**
83525 + @Description structure for defining statistics node
83526 +*//***************************************************************************/
83527 +typedef struct t_FmPcdStatsParams {
83528 + e_FmPcdStatsType type; /**< type of statistics node */
83529 +} t_FmPcdStatsParams;
83530 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83531 +
83532 +/**************************************************************************//**
83533 + @Function FM_PCD_NetEnvCharacteristicsSet
83534 +
83535 + @Description Define a set of Network Environment Characteristics.
83536 +
83537 + When setting an environment it is important to understand its
83538 + application. It is not meant to describe the flows that will run
83539 + on the ports using this environment, but what the user means TO DO
83540 + with the PCD mechanisms in order to parse-classify-distribute those
83541 + frames.
83542 + By specifying a distinction unit, the user means it would use that option
83543 + for distinction between frames at either a KeyGen scheme or a coarse
83544 + classification action descriptor. Using interchangeable headers to define a
83545 + unit means that the user is indifferent to which of the interchangeable
83546 + headers is present in the frame, and wants the distinction to be based
83547 + on the presence of either one of them.
83548 +
83549 + Depending on context, there are limitations to the use of environments. A
83550 + port using the PCD functionality is bound to an environment. Some or even
83551 + all ports may share an environment but also an environment per port is
83552 + possible. When initializing a scheme, a classification plan group (see below),
83553 + or a coarse classification tree, one of the initialized environments must be
83554 + stated and related to. When a port is bound to a scheme, a classification
83555 + plan group, or a coarse classification tree, it MUST be bound to the same
83556 + environment.
83557 +
83558 + The different PCD modules, may relate (for flows definition) ONLY on
83559 + distinction units as defined by their environment. When initializing a
83560 + scheme for example, it may not choose to select IPV4 as a match for
83561 + recognizing flows unless it was defined in the relating environment. In
83562 + fact, to guide the user through the configuration of the PCD, each module's
83563 + characterization in terms of flows is not done using protocol names, but using
83564 + environment indexes.
83565 +
83566 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83567 + and later used for match vector, classification plan vectors and coarse classification
83568 + indexing.
83569 +
83570 + @Param[in] h_FmPcd FM PCD module descriptor.
83571 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83572 + the network environment.
83573 +
83574 + @Return A handle to the initialized object on success; NULL code otherwise.
83575 +
83576 + @Cautions Allowed only following FM_PCD_Init().
83577 +*//***************************************************************************/
83578 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83579 +
83580 +/**************************************************************************//**
83581 + @Function FM_PCD_NetEnvCharacteristicsDelete
83582 +
83583 + @Description Deletes a set of Network Environment Characteristics.
83584 +
83585 + @Param[in] h_NetEnv A handle to the Network environment.
83586 +
83587 + @Return E_OK on success; Error code otherwise.
83588 +*//***************************************************************************/
83589 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83590 +
83591 +/**************************************************************************//**
83592 + @Function FM_PCD_KgSchemeSet
83593 +
83594 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83595 + This routine should be called for adding or modifying a scheme.
83596 + When a scheme needs modifying, the API requires that it will be
83597 + rewritten. In such a case 'modify' should be TRUE. If the
83598 + routine is called for a valid scheme and 'modify' is FALSE,
83599 + it will return error.
83600 +
83601 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83602 + Otherwise NULL (ignored by driver).
83603 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83604 +
83605 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83606 + When used as "modify" (rather than for setting a new scheme),
83607 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83608 + BUSY state.
83609 +
83610 + @Cautions Allowed only following FM_PCD_Init().
83611 +*//***************************************************************************/
83612 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83613 + t_FmPcdKgSchemeParams *p_SchemeParams);
83614 +
83615 +/**************************************************************************//**
83616 + @Function FM_PCD_KgSchemeDelete
83617 +
83618 + @Description Deleting an initialized scheme.
83619 +
83620 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83621 +
83622 + @Return E_OK on success; Error code otherwise.
83623 +
83624 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83625 +*//***************************************************************************/
83626 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83627 +
83628 +/**************************************************************************//**
83629 + @Function FM_PCD_KgSchemeGetCounter
83630 +
83631 + @Description Reads scheme packet counter.
83632 +
83633 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83634 +
83635 + @Return Counter's current value.
83636 +
83637 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83638 +*//***************************************************************************/
83639 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83640 +
83641 +/**************************************************************************//**
83642 + @Function FM_PCD_KgSchemeSetCounter
83643 +
83644 + @Description Writes scheme packet counter.
83645 +
83646 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83647 + @Param[in] value New scheme counter value - typically '0' for
83648 + resetting the counter.
83649 +
83650 + @Return E_OK on success; Error code otherwise.
83651 +
83652 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83653 +*//***************************************************************************/
83654 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83655 +
83656 +/**************************************************************************//**
83657 + @Function FM_PCD_PlcrProfileSet
83658 +
83659 + @Description Sets a profile entry in the policer profile table.
83660 + The routine overrides any existing value.
83661 +
83662 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83663 + @Param[in] p_Profile A structure of parameters for defining a
83664 + policer profile entry.
83665 +
83666 + @Return A handle to the initialized object on success; NULL code otherwise.
83667 + When used as "modify" (rather than for setting a new profile),
83668 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83669 + BUSY state.
83670 + @Cautions Allowed only following FM_PCD_Init().
83671 +*//***************************************************************************/
83672 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83673 + t_FmPcdPlcrProfileParams *p_Profile);
83674 +
83675 +/**************************************************************************//**
83676 + @Function FM_PCD_PlcrProfileDelete
83677 +
83678 + @Description Delete a profile entry in the policer profile table.
83679 + The routine set entry to invalid.
83680 +
83681 + @Param[in] h_Profile A handle to the profile.
83682 +
83683 + @Return E_OK on success; Error code otherwise.
83684 +
83685 + @Cautions Allowed only following FM_PCD_Init().
83686 +*//***************************************************************************/
83687 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83688 +
83689 +/**************************************************************************//**
83690 + @Function FM_PCD_PlcrProfileGetCounter
83691 +
83692 + @Description Sets an entry in the classification plan.
83693 + The routine overrides any existing value.
83694 +
83695 + @Param[in] h_Profile A handle to the profile.
83696 + @Param[in] counter Counter selector.
83697 +
83698 + @Return specific counter value.
83699 +
83700 + @Cautions Allowed only following FM_PCD_Init().
83701 +*//***************************************************************************/
83702 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83703 + e_FmPcdPlcrProfileCounters counter);
83704 +
83705 +/**************************************************************************//**
83706 + @Function FM_PCD_PlcrProfileSetCounter
83707 +
83708 + @Description Sets an entry in the classification plan.
83709 + The routine overrides any existing value.
83710 +
83711 + @Param[in] h_Profile A handle to the profile.
83712 + @Param[in] counter Counter selector.
83713 + @Param[in] value value to set counter with.
83714 +
83715 + @Return E_OK on success; Error code otherwise.
83716 +
83717 + @Cautions Allowed only following FM_PCD_Init().
83718 +*//***************************************************************************/
83719 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83720 + e_FmPcdPlcrProfileCounters counter,
83721 + uint32_t value);
83722 +
83723 +/**************************************************************************//**
83724 + @Function FM_PCD_CcRootBuild
83725 +
83726 + @Description This routine must be called to define a complete coarse
83727 + classification tree. This is the way to define coarse
83728 + classification to a certain flow - the KeyGen schemes
83729 + may point only to trees defined in this way.
83730 +
83731 + @Param[in] h_FmPcd FM PCD module descriptor.
83732 + @Param[in] p_Params A structure of parameters to define the tree.
83733 +
83734 + @Return A handle to the initialized object on success; NULL code otherwise.
83735 +
83736 + @Cautions Allowed only following FM_PCD_Init().
83737 +*//***************************************************************************/
83738 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83739 + t_FmPcdCcTreeParams *p_Params);
83740 +
83741 +/**************************************************************************//**
83742 + @Function FM_PCD_CcRootDelete
83743 +
83744 + @Description Deleting an built tree.
83745 +
83746 + @Param[in] h_CcTree A handle to a CC tree.
83747 +
83748 + @Return E_OK on success; Error code otherwise.
83749 +
83750 + @Cautions Allowed only following FM_PCD_Init().
83751 +*//***************************************************************************/
83752 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83753 +
83754 +/**************************************************************************//**
83755 + @Function FM_PCD_CcRootModifyNextEngine
83756 +
83757 + @Description Modify the Next Engine Parameters in the entry of the tree.
83758 +
83759 + @Param[in] h_CcTree A handle to the tree
83760 + @Param[in] grpId A Group index in the tree
83761 + @Param[in] index Entry index in the group defined by grpId
83762 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83763 +
83764 + @Return E_OK on success; Error code otherwise.
83765 +
83766 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83767 +*//***************************************************************************/
83768 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83769 + uint8_t grpId,
83770 + uint8_t index,
83771 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83772 +
83773 +/**************************************************************************//**
83774 + @Function FM_PCD_MatchTableSet
83775 +
83776 + @Description This routine should be called for each CC (coarse classification)
83777 + node. The whole CC tree should be built bottom up so that each
83778 + node points to already defined nodes.
83779 +
83780 + @Param[in] h_FmPcd FM PCD module descriptor.
83781 + @Param[in] p_Param A structure of parameters defining the CC node
83782 +
83783 + @Return A handle to the initialized object on success; NULL code otherwise.
83784 +
83785 + @Cautions Allowed only following FM_PCD_Init().
83786 +*//***************************************************************************/
83787 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83788 +
83789 +/**************************************************************************//**
83790 + @Function FM_PCD_MatchTableDelete
83791 +
83792 + @Description Deleting an built node.
83793 +
83794 + @Param[in] h_CcNode A handle to a CC node.
83795 +
83796 + @Return E_OK on success; Error code otherwise.
83797 +
83798 + @Cautions Allowed only following FM_PCD_Init().
83799 +*//***************************************************************************/
83800 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83801 +
83802 +/**************************************************************************//**
83803 + @Function FM_PCD_MatchTableModifyMissNextEngine
83804 +
83805 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83806 +
83807 + @Param[in] h_CcNode A handle to the node
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 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83814 + When configuring nextEngine = e_FM_PCD_CC, note that
83815 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83816 + from the currently changed table.
83817 +
83818 +*//***************************************************************************/
83819 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83820 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83821 +
83822 +/**************************************************************************//**
83823 + @Function FM_PCD_MatchTableRemoveKey
83824 +
83825 + @Description Remove the key (including next engine parameters of this key)
83826 + defined by the index of the relevant node.
83827 +
83828 + @Param[in] h_CcNode A handle to the node
83829 + @Param[in] keyIndex Key index for removing
83830 +
83831 + @Return E_OK on success; Error code otherwise.
83832 +
83833 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83834 + node and the nodes that lead to it.
83835 +*//***************************************************************************/
83836 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83837 +
83838 +/**************************************************************************//**
83839 + @Function FM_PCD_MatchTableAddKey
83840 +
83841 + @Description Add the key (including next engine parameters of this key in the
83842 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83843 + may be used by user that don't care about the position of the
83844 + key in the table - in that case, the key will be automatically
83845 + added by the driver in the last available entry.
83846 +
83847 + @Param[in] h_CcNode A handle to the node
83848 + @Param[in] keyIndex Key index for adding.
83849 + @Param[in] keySize Key size of added key
83850 + @Param[in] p_KeyParams A pointer to the parameters includes
83851 + new key with Next Engine Parameters
83852 +
83853 + @Return E_OK on success; Error code otherwise.
83854 +
83855 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83856 + node and the nodes that lead to it.
83857 +*//***************************************************************************/
83858 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
83859 + uint16_t keyIndex,
83860 + uint8_t keySize,
83861 + t_FmPcdCcKeyParams *p_KeyParams);
83862 +
83863 +/**************************************************************************//**
83864 + @Function FM_PCD_MatchTableModifyNextEngine
83865 +
83866 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
83867 +
83868 + @Param[in] h_CcNode A handle to the node
83869 + @Param[in] keyIndex Key index for Next Engine modifications
83870 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83871 +
83872 + @Return E_OK on success; Error code otherwise.
83873 +
83874 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83875 + When configuring nextEngine = e_FM_PCD_CC, note that
83876 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83877 + from the currently changed table.
83878 +
83879 +*//***************************************************************************/
83880 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
83881 + uint16_t keyIndex,
83882 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83883 +
83884 +/**************************************************************************//**
83885 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
83886 +
83887 + @Description Modify the key and Next Engine Parameters of this key in the
83888 + index defined by the keyIndex.
83889 +
83890 + @Param[in] h_CcNode A handle to the node
83891 + @Param[in] keyIndex Key index for adding
83892 + @Param[in] keySize Key size of added key
83893 + @Param[in] p_KeyParams A pointer to the parameters includes
83894 + modified key and modified Next Engine Parameters
83895 +
83896 + @Return E_OK on success; Error code otherwise.
83897 +
83898 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83899 + node and the nodes that lead to it.
83900 + When configuring nextEngine = e_FM_PCD_CC, note that
83901 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83902 + from the currently changed table.
83903 +*//***************************************************************************/
83904 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
83905 + uint16_t keyIndex,
83906 + uint8_t keySize,
83907 + t_FmPcdCcKeyParams *p_KeyParams);
83908 +
83909 +/**************************************************************************//**
83910 + @Function FM_PCD_MatchTableModifyKey
83911 +
83912 + @Description Modify the key in the index defined by the keyIndex.
83913 +
83914 + @Param[in] h_CcNode A handle to the node
83915 + @Param[in] keyIndex Key index for adding
83916 + @Param[in] keySize Key size of added key
83917 + @Param[in] p_Key A pointer to the new key
83918 + @Param[in] p_Mask A pointer to the new mask if relevant,
83919 + otherwise pointer to NULL
83920 +
83921 + @Return E_OK on success; Error code otherwise.
83922 +
83923 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83924 + node and the nodes that lead to it.
83925 +*//***************************************************************************/
83926 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
83927 + uint16_t keyIndex,
83928 + uint8_t keySize,
83929 + uint8_t *p_Key,
83930 + uint8_t *p_Mask);
83931 +
83932 +/**************************************************************************//**
83933 + @Function FM_PCD_MatchTableFindNRemoveKey
83934 +
83935 + @Description Remove the key (including next engine parameters of this key)
83936 + defined by the key and mask. Note that this routine will search
83937 + the node to locate the index of the required key (& mask) to remove.
83938 +
83939 + @Param[in] h_CcNode A handle to the node
83940 + @Param[in] keySize Key size of the one to remove.
83941 + @Param[in] p_Key A pointer to the requested key to remove.
83942 + @Param[in] p_Mask A pointer to the mask if relevant,
83943 + otherwise pointer to NULL
83944 +
83945 + @Return E_OK on success; Error code otherwise.
83946 +
83947 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83948 + node and the nodes that lead to it.
83949 +*//***************************************************************************/
83950 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
83951 + uint8_t keySize,
83952 + uint8_t *p_Key,
83953 + uint8_t *p_Mask);
83954 +
83955 +/**************************************************************************//**
83956 + @Function FM_PCD_MatchTableFindNModifyNextEngine
83957 +
83958 + @Description Modify the Next Engine Parameters in the relevant key entry of
83959 + the node. Note that this routine will search the node to locate
83960 + the index of the required key (& mask) to modify.
83961 +
83962 + @Param[in] h_CcNode A handle to the node
83963 + @Param[in] keySize Key size of the one to modify.
83964 + @Param[in] p_Key A pointer to the requested key to modify.
83965 + @Param[in] p_Mask A pointer to the mask if relevant,
83966 + otherwise pointer to NULL
83967 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83968 +
83969 + @Return E_OK on success; Error code otherwise.
83970 +
83971 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83972 + When configuring nextEngine = e_FM_PCD_CC, note that
83973 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83974 + from the currently changed table.
83975 +*//***************************************************************************/
83976 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
83977 + uint8_t keySize,
83978 + uint8_t *p_Key,
83979 + uint8_t *p_Mask,
83980 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83981 +
83982 +/**************************************************************************//**
83983 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
83984 +
83985 + @Description Modify the key and Next Engine Parameters of this key in the
83986 + index defined by the keyIndex. Note that this routine will search
83987 + the node to locate the index of the required key (& mask) to modify.
83988 +
83989 + @Param[in] h_CcNode A handle to the node
83990 + @Param[in] keySize Key size of the one to modify.
83991 + @Param[in] p_Key A pointer to the requested key to modify.
83992 + @Param[in] p_Mask A pointer to the mask if relevant,
83993 + otherwise pointer to NULL
83994 + @Param[in] p_KeyParams A pointer to the parameters includes
83995 + modified key and modified Next Engine Parameters
83996 +
83997 + @Return E_OK on success; Error code otherwise.
83998 +
83999 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84000 + node and the nodes that lead to it.
84001 + When configuring nextEngine = e_FM_PCD_CC, note that
84002 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84003 + from the currently changed table.
84004 +*//***************************************************************************/
84005 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
84006 + uint8_t keySize,
84007 + uint8_t *p_Key,
84008 + uint8_t *p_Mask,
84009 + t_FmPcdCcKeyParams *p_KeyParams);
84010 +
84011 +/**************************************************************************//**
84012 + @Function FM_PCD_MatchTableFindNModifyKey
84013 +
84014 + @Description Modify the key in the index defined by the keyIndex. Note that
84015 + this routine will search the node to locate the index of the
84016 + required key (& mask) to modify.
84017 +
84018 + @Param[in] h_CcNode A handle to the node
84019 + @Param[in] keySize Key size of the one to modify.
84020 + @Param[in] p_Key A pointer to the requested key to modify.
84021 + @Param[in] p_Mask A pointer to the mask if relevant,
84022 + otherwise pointer to NULL
84023 + @Param[in] p_NewKey A pointer to the new key
84024 + @Param[in] p_NewMask A pointer to the new mask if relevant,
84025 + otherwise pointer to NULL
84026 +
84027 + @Return E_OK on success; Error code otherwise.
84028 +
84029 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84030 + node and the nodes that lead to it.
84031 +*//***************************************************************************/
84032 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
84033 + uint8_t keySize,
84034 + uint8_t *p_Key,
84035 + uint8_t *p_Mask,
84036 + uint8_t *p_NewKey,
84037 + uint8_t *p_NewMask);
84038 +
84039 +/**************************************************************************//**
84040 + @Function FM_PCD_MatchTableGetKeyCounter
84041 +
84042 + @Description This routine may be used to get a counter of specific key in a CC
84043 + Node; This counter reflects how many frames passed that were matched
84044 + this key.
84045 +
84046 + @Param[in] h_CcNode A handle to the node
84047 + @Param[in] keyIndex Key index for adding
84048 +
84049 + @Return The specific key counter.
84050 +
84051 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84052 +*//***************************************************************************/
84053 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
84054 +
84055 +/**************************************************************************//**
84056 + @Function FM_PCD_MatchTableGetKeyStatistics
84057 +
84058 + @Description This routine may be used to get statistics counters of specific key
84059 + in a CC Node.
84060 +
84061 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84062 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84063 + these counters reflect how many frames passed that were matched
84064 + this key; The total frames count will be returned in the counter
84065 + of the first range (as only one frame length range was defined).
84066 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84067 + frame count will be separated to frame length counters, based on
84068 + provided frame length ranges.
84069 +
84070 + @Param[in] h_CcNode A handle to the node
84071 + @Param[in] keyIndex Key index for adding
84072 + @Param[out] p_KeyStatistics Key statistics counters
84073 +
84074 + @Return The specific key statistics.
84075 +
84076 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84077 +*//***************************************************************************/
84078 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
84079 + uint16_t keyIndex,
84080 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84081 +
84082 +/**************************************************************************//**
84083 + @Function FM_PCD_MatchTableGetMissStatistics
84084 +
84085 + @Description This routine may be used to get statistics counters of miss entry
84086 + in a CC Node.
84087 +
84088 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84089 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84090 + these counters reflect how many frames were not matched to any
84091 + existing key and therefore passed through the miss entry; The
84092 + total frames count will be returned in the counter of the
84093 + first range (as only one frame length range was defined).
84094 +
84095 + @Param[in] h_CcNode A handle to the node
84096 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84097 +
84098 + @Return The statistics for 'miss'.
84099 +
84100 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84101 +*//***************************************************************************/
84102 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
84103 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84104 +
84105 +/**************************************************************************//**
84106 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
84107 +
84108 + @Description This routine may be used to get statistics counters of specific key
84109 + in a CC Node.
84110 +
84111 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84112 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84113 + these counters reflect how many frames passed that were matched
84114 + this key; The total frames count will be returned in the counter
84115 + of the first range (as only one frame length range was defined).
84116 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84117 + frame count will be separated to frame length counters, based on
84118 + provided frame length ranges.
84119 + Note that this routine will search the node to locate the index
84120 + of the required key based on received key parameters.
84121 +
84122 + @Param[in] h_CcNode A handle to the node
84123 + @Param[in] keySize Size of the requested key
84124 + @Param[in] p_Key A pointer to the requested key
84125 + @Param[in] p_Mask A pointer to the mask if relevant,
84126 + otherwise pointer to NULL
84127 + @Param[out] p_KeyStatistics Key statistics counters
84128 +
84129 + @Return The specific key statistics.
84130 +
84131 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84132 +*//***************************************************************************/
84133 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
84134 + uint8_t keySize,
84135 + uint8_t *p_Key,
84136 + uint8_t *p_Mask,
84137 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84138 +
84139 +/**************************************************************************//*
84140 + @Function FM_PCD_MatchTableGetNextEngine
84141 +
84142 + @Description Gets NextEngine of the relevant keyIndex.
84143 +
84144 + @Param[in] h_CcNode A handle to the node.
84145 + @Param[in] keyIndex keyIndex in the relevant node.
84146 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
84147 + the relevant keyIndex of the CC Node
84148 + received as parameter to this function
84149 +
84150 + @Return E_OK on success; Error code otherwise.
84151 +
84152 + @Cautions Allowed only following FM_PCD_Init().
84153 +*//***************************************************************************/
84154 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
84155 + uint16_t keyIndex,
84156 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84157 +
84158 +/**************************************************************************//*
84159 + @Function FM_PCD_MatchTableGetIndexedHashBucket
84160 +
84161 + @Description This routine simulates KeyGen operation on the provided key and
84162 + calculates to which hash bucket it will be mapped.
84163 +
84164 + @Param[in] h_CcNode A handle to the node.
84165 + @Param[in] kgKeySize Key size as it was configured in the KG
84166 + scheme that leads to this hash.
84167 + @Param[in] p_KgKey Pointer to the key; must be like the key
84168 + that the KG is generated, i.e. the same
84169 + extraction and with mask if exist.
84170 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
84171 + scheme that leads to this hash.
84172 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
84173 + @Param[out] p_BucketIndex Index to the bucket of the provided key
84174 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
84175 + provided key.
84176 +
84177 + @Return E_OK on success; Error code otherwise.
84178 +
84179 + @Cautions Allowed only following FM_PCD_HashTableSet()
84180 +*//***************************************************************************/
84181 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
84182 + uint8_t kgKeySize,
84183 + uint8_t *p_KgKey,
84184 + uint8_t kgHashShift,
84185 + t_Handle *p_CcNodeBucketHandle,
84186 + uint8_t *p_BucketIndex,
84187 + uint16_t *p_LastIndex);
84188 +
84189 +/**************************************************************************//**
84190 + @Function FM_PCD_HashTableSet
84191 +
84192 + @Description This routine initializes a hash table structure.
84193 + KeyGen hash result determines the hash bucket.
84194 + Next, KeyGen key is compared against all keys of this
84195 + bucket (exact match).
84196 + Number of sets (number of buckets) of the hash equals to the
84197 + number of 1-s in 'hashResMask' in the provided parameters.
84198 + Number of hash table ways is then calculated by dividing
84199 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
84200 + number of keys that a hash bucket may hold.
84201 + The hash table is initialized empty and keys may be
84202 + added to it following the initialization. Keys masks are not
84203 + supported in current hash table implementation.
84204 + The initialized hash table can be integrated as a node in a
84205 + CC tree.
84206 +
84207 + @Param[in] h_FmPcd FM PCD module descriptor.
84208 + @Param[in] p_Param A structure of parameters defining the hash table
84209 +
84210 + @Return A handle to the initialized object on success; NULL code otherwise.
84211 +
84212 + @Cautions Allowed only following FM_PCD_Init().
84213 +*//***************************************************************************/
84214 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
84215 +
84216 +/**************************************************************************//**
84217 + @Function FM_PCD_HashTableDelete
84218 +
84219 + @Description This routine deletes the provided hash table and released all
84220 + its allocated resources.
84221 +
84222 + @Param[in] h_HashTbl A handle to a hash table
84223 +
84224 + @Return E_OK on success; Error code otherwise.
84225 +
84226 + @Cautions Allowed only following FM_PCD_HashTableSet().
84227 +*//***************************************************************************/
84228 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
84229 +
84230 +/**************************************************************************//**
84231 + @Function FM_PCD_HashTableAddKey
84232 +
84233 + @Description This routine adds the provided key (including next engine
84234 + parameters of this key) to the hash table.
84235 + The key is added as the last key of the bucket that it is
84236 + mapped to.
84237 +
84238 + @Param[in] h_HashTbl A handle to a hash table
84239 + @Param[in] keySize Key size of added key
84240 + @Param[in] p_KeyParams A pointer to the parameters includes
84241 + new key with next engine parameters; The pointer
84242 + to the key mask must be NULL, as masks are not
84243 + supported in hash table implementation.
84244 +
84245 + @Return E_OK on success; Error code otherwise.
84246 +
84247 + @Cautions Allowed only following FM_PCD_HashTableSet().
84248 +*//***************************************************************************/
84249 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
84250 + uint8_t keySize,
84251 + t_FmPcdCcKeyParams *p_KeyParams);
84252 +
84253 +/**************************************************************************//**
84254 + @Function FM_PCD_HashTableRemoveKey
84255 +
84256 + @Description This routine removes the requested key (including next engine
84257 + parameters of this key) from the hash table.
84258 +
84259 + @Param[in] h_HashTbl A handle to a hash table
84260 + @Param[in] keySize Key size of the one to remove.
84261 + @Param[in] p_Key A pointer to the requested key to remove.
84262 +
84263 + @Return E_OK on success; Error code otherwise.
84264 +
84265 + @Cautions Allowed only following FM_PCD_HashTableSet().
84266 +*//***************************************************************************/
84267 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
84268 + uint8_t keySize,
84269 + uint8_t *p_Key);
84270 +
84271 +/**************************************************************************//**
84272 + @Function FM_PCD_HashTableModifyNextEngine
84273 +
84274 + @Description This routine modifies the next engine for the provided key. The
84275 + key should be previously added to the hash table.
84276 +
84277 + @Param[in] h_HashTbl A handle to a hash table
84278 + @Param[in] keySize Key size of the key to modify.
84279 + @Param[in] p_Key A pointer to the requested key to modify.
84280 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84281 + parameters.
84282 +
84283 + @Return E_OK on success; Error code otherwise.
84284 +
84285 + @Cautions Allowed only following FM_PCD_HashTableSet().
84286 + When configuring nextEngine = e_FM_PCD_CC, note that
84287 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84288 + from the currently changed table.
84289 +*//***************************************************************************/
84290 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
84291 + uint8_t keySize,
84292 + uint8_t *p_Key,
84293 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84294 +
84295 +/**************************************************************************//**
84296 + @Function FM_PCD_HashTableModifyMissNextEngine
84297 +
84298 + @Description This routine modifies the next engine on key match miss.
84299 +
84300 + @Param[in] h_HashTbl A handle to a hash table
84301 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84302 + parameters.
84303 +
84304 + @Return E_OK on success; Error code otherwise.
84305 +
84306 + @Cautions Allowed only following FM_PCD_HashTableSet().
84307 + When configuring nextEngine = e_FM_PCD_CC, note that
84308 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84309 + from the currently changed table.
84310 +*//***************************************************************************/
84311 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
84312 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84313 +
84314 +/**************************************************************************//*
84315 + @Function FM_PCD_HashTableGetMissNextEngine
84316 +
84317 + @Description Gets NextEngine in case of key match miss.
84318 +
84319 + @Param[in] h_HashTbl A handle to a hash table
84320 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
84321 + hash table.
84322 +
84323 + @Return E_OK on success; Error code otherwise.
84324 +
84325 + @Cautions Allowed only following FM_PCD_HashTableSet().
84326 +*//***************************************************************************/
84327 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
84328 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84329 +
84330 +/**************************************************************************//**
84331 + @Function FM_PCD_HashTableFindNGetKeyStatistics
84332 +
84333 + @Description This routine may be used to get statistics counters of specific key
84334 + in a hash table.
84335 +
84336 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84337 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84338 + these counters reflect how many frames passed that were matched
84339 + this key; The total frames count will be returned in the counter
84340 + of the first range (as only one frame length range was defined).
84341 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84342 + frame count will be separated to frame length counters, based on
84343 + provided frame length ranges.
84344 + Note that this routine will identify the bucket of this key in
84345 + the hash table and will search the bucket to locate the index
84346 + of the required key based on received key parameters.
84347 +
84348 + @Param[in] h_HashTbl A handle to a hash table
84349 + @Param[in] keySize Size of the requested key
84350 + @Param[in] p_Key A pointer to the requested key
84351 + @Param[out] p_KeyStatistics Key statistics counters
84352 +
84353 + @Return The specific key statistics.
84354 +
84355 + @Cautions Allowed only following FM_PCD_HashTableSet().
84356 +*//***************************************************************************/
84357 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84358 + uint8_t keySize,
84359 + uint8_t *p_Key,
84360 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84361 +
84362 +/**************************************************************************//**
84363 + @Function FM_PCD_HashTableGetMissStatistics
84364 +
84365 + @Description This routine may be used to get statistics counters of 'miss'
84366 + entry of the a hash table.
84367 +
84368 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84369 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84370 + these counters reflect how many frames were not matched to any
84371 + existing key and therefore passed through the miss entry;
84372 +
84373 + @Param[in] h_HashTbl A handle to a hash table
84374 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84375 +
84376 + @Return The statistics for 'miss'.
84377 +
84378 + @Cautions Allowed only following FM_PCD_HashTableSet().
84379 +*//***************************************************************************/
84380 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84381 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84382 +
84383 +/**************************************************************************//**
84384 + @Function FM_PCD_ManipNodeSet
84385 +
84386 + @Description This routine should be called for defining a manipulation
84387 + node. A manipulation node must be defined before the CC node
84388 + that precedes it.
84389 +
84390 + @Param[in] h_FmPcd FM PCD module descriptor.
84391 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84392 +
84393 + @Return A handle to the initialized object on success; NULL code otherwise.
84394 +
84395 + @Cautions Allowed only following FM_PCD_Init().
84396 +*//***************************************************************************/
84397 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84398 +
84399 +/**************************************************************************//**
84400 + @Function FM_PCD_ManipNodeDelete
84401 +
84402 + @Description Delete an existing manipulation node.
84403 +
84404 + @Param[in] h_ManipNode A handle to a manipulation node.
84405 +
84406 + @Return E_OK on success; Error code otherwise.
84407 +
84408 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84409 +*//***************************************************************************/
84410 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84411 +
84412 +/**************************************************************************//**
84413 + @Function FM_PCD_ManipGetStatistics
84414 +
84415 + @Description Retrieve the manipulation statistics.
84416 +
84417 + @Param[in] h_ManipNode A handle to a manipulation node.
84418 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84419 +
84420 + @Return E_OK on success; Error code otherwise.
84421 +
84422 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84423 +*//***************************************************************************/
84424 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84425 +
84426 +/**************************************************************************//**
84427 + @Function FM_PCD_ManipNodeReplace
84428 +
84429 + @Description Change existing manipulation node to be according to new requirement.
84430 +
84431 + @Param[in] h_ManipNode A handle to a manipulation node.
84432 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84433 +
84434 + @Return E_OK on success; Error code otherwise.
84435 +
84436 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84437 +*//***************************************************************************/
84438 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84439 +
84440 +#if (DPAA_VERSION >= 11)
84441 +/**************************************************************************//**
84442 + @Function FM_PCD_FrmReplicSetGroup
84443 +
84444 + @Description Initialize a Frame Replicator group.
84445 +
84446 + @Param[in] h_FmPcd FM PCD module descriptor.
84447 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84448 + the frame replicator group.
84449 +
84450 + @Return A handle to the initialized object on success; NULL code otherwise.
84451 +
84452 + @Cautions Allowed only following FM_PCD_Init().
84453 +*//***************************************************************************/
84454 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84455 +
84456 +/**************************************************************************//**
84457 + @Function FM_PCD_FrmReplicDeleteGroup
84458 +
84459 + @Description Delete a Frame Replicator group.
84460 +
84461 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84462 +
84463 + @Return E_OK on success; Error code otherwise.
84464 +
84465 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84466 +*//***************************************************************************/
84467 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84468 +
84469 +/**************************************************************************//**
84470 + @Function FM_PCD_FrmReplicAddMember
84471 +
84472 + @Description Add the member in the index defined by the memberIndex.
84473 +
84474 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84475 + @Param[in] memberIndex member index for adding.
84476 + @Param[in] p_MemberParams A pointer to the new member parameters.
84477 +
84478 + @Return E_OK on success; Error code otherwise.
84479 +
84480 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84481 +*//***************************************************************************/
84482 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84483 + uint16_t memberIndex,
84484 + t_FmPcdCcNextEngineParams *p_MemberParams);
84485 +
84486 +/**************************************************************************//**
84487 + @Function FM_PCD_FrmReplicRemoveMember
84488 +
84489 + @Description Remove the member defined by the index from the relevant group.
84490 +
84491 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84492 + @Param[in] memberIndex member index for removing.
84493 +
84494 + @Return E_OK on success; Error code otherwise.
84495 +
84496 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84497 +*//***************************************************************************/
84498 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84499 + uint16_t memberIndex);
84500 +#endif /* (DPAA_VERSION >= 11) */
84501 +
84502 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84503 +/**************************************************************************//**
84504 + @Function FM_PCD_StatisticsSetNode
84505 +
84506 + @Description This routine should be called for defining a statistics node.
84507 +
84508 + @Param[in] h_FmPcd FM PCD module descriptor.
84509 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84510 +
84511 + @Return A handle to the initialized object on success; NULL code otherwise.
84512 +
84513 + @Cautions Allowed only following FM_PCD_Init().
84514 +*//***************************************************************************/
84515 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84516 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84517 +
84518 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84519 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84520 +/** @} */ /* end of FM_PCD_grp group */
84521 +/** @} */ /* end of FM_grp group */
84522 +
84523 +
84524 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84525 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84526 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84527 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84528 +
84529 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84530 +
84531 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84532 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84533 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84534 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84535 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84536 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84537 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84538 +
84539 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84540 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84541 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84542 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84543 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84544 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84545 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84546 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84547 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84548 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84549 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84550 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84551 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84552 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84553 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84554 + FM_PCD_CcRootDelete(__VA_ARGS__)
84555 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84556 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84557 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84558 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84559 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84560 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84561 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84562 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84563 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84564 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84565 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84566 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84567 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84568 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84569 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84570 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84571 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84572 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84573 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84574 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84575 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84576 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84577 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84578 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84579 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84580 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84581 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84582 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84583 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84584 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84585 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84586 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84587 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84588 +
84589 +
84590 +#endif /* __FM_PCD_EXT */
84591 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84592 new file mode 100644
84593 index 00000000..08a5aa59
84594 --- /dev/null
84595 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84596 @@ -0,0 +1,2608 @@
84597 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84598 + * All rights reserved.
84599 + *
84600 + * Redistribution and use in source and binary forms, with or without
84601 + * modification, are permitted provided that the following conditions are met:
84602 + * * Redistributions of source code must retain the above copyright
84603 + * notice, this list of conditions and the following disclaimer.
84604 + * * Redistributions in binary form must reproduce the above copyright
84605 + * notice, this list of conditions and the following disclaimer in the
84606 + * documentation and/or other materials provided with the distribution.
84607 + * * Neither the name of Freescale Semiconductor nor the
84608 + * names of its contributors may be used to endorse or promote products
84609 + * derived from this software without specific prior written permission.
84610 + *
84611 + *
84612 + * ALTERNATIVELY, this software may be distributed under the terms of the
84613 + * GNU General Public License ("GPL") as published by the Free Software
84614 + * Foundation, either version 2 of that License or (at your option) any
84615 + * later version.
84616 + *
84617 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84618 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84619 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84620 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84621 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84622 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84623 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84624 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84625 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84626 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84627 + */
84628 +
84629 +
84630 +/**************************************************************************//**
84631 + @File fm_port_ext.h
84632 +
84633 + @Description FM-Port Application Programming Interface.
84634 +*//***************************************************************************/
84635 +#ifndef __FM_PORT_EXT
84636 +#define __FM_PORT_EXT
84637 +
84638 +#include "error_ext.h"
84639 +#include "std_ext.h"
84640 +#include "fm_pcd_ext.h"
84641 +#include "fm_ext.h"
84642 +#include "net_ext.h"
84643 +
84644 +
84645 +/**************************************************************************//**
84646 +
84647 + @Group FM_grp Frame Manager API
84648 +
84649 + @Description FM API functions, definitions and enums
84650 +
84651 + @{
84652 +*//***************************************************************************/
84653 +
84654 +/**************************************************************************//**
84655 + @Group FM_PORT_grp FM Port
84656 +
84657 + @Description FM Port API
84658 +
84659 + The FM uses a general module called "port" to represent a Tx port
84660 + (MAC), an Rx port (MAC) or Offline Parsing port.
84661 + The number of ports in an FM varies between SOCs.
84662 + The SW driver manages these ports as sub-modules of the FM, i.e.
84663 + after an FM is initialized, its ports may be initialized and
84664 + operated upon.
84665 +
84666 + The port is initialized aware of its type, but other functions on
84667 + a port may be indifferent to its type. When necessary, the driver
84668 + verifies coherence and returns error if applicable.
84669 +
84670 + On initialization, user specifies the port type and it's index
84671 + (relative to the port's type) - always starting at 0.
84672 +
84673 + @{
84674 +*//***************************************************************************/
84675 +
84676 +/**************************************************************************//**
84677 + @Description An enum for defining port PCD modes.
84678 + This enum defines the superset of PCD engines support - i.e. not
84679 + all engines have to be used, but all have to be enabled. The real
84680 + flow of a specific frame depends on the PCD configuration and the
84681 + frame headers and payload.
84682 + Note: the first engine and the first engine after the parser (if
84683 + exists) should be in order, the order is important as it will
84684 + define the flow of the port. However, as for the rest engines
84685 + (the ones that follows), the order is not important anymore as
84686 + it is defined by the PCD graph itself.
84687 +*//***************************************************************************/
84688 +typedef enum e_FmPortPcdSupport {
84689 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84690 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84691 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84692 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84693 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84694 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84695 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84696 + /**< Use all PCD engines */
84697 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84698 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84699 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84700 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84701 +#ifdef FM_CAPWAP_SUPPORT
84702 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84703 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84704 +#endif /* FM_CAPWAP_SUPPORT */
84705 +} e_FmPortPcdSupport;
84706 +
84707 +/**************************************************************************//**
84708 + @Description Port interrupts
84709 +*//***************************************************************************/
84710 +typedef enum e_FmPortExceptions {
84711 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84712 +} e_FmPortExceptions;
84713 +
84714 +
84715 +/**************************************************************************//**
84716 + @Collection General FM Port defines
84717 +*//***************************************************************************/
84718 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84719 +/* @} */
84720 +
84721 +/**************************************************************************//**
84722 + @Collection FM Frame error
84723 +*//***************************************************************************/
84724 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84725 +
84726 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84727 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84728 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84729 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84730 + was chained to FM */
84731 +
84732 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84733 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84734 +
84735 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84736 +
84737 +#ifdef FM_CAPWAP_SUPPORT
84738 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84739 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84740 +#endif /* FM_CAPWAP_SUPPORT */
84741 +
84742 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84743 + error (SGMII and TBI modes), FIFO parity error. PHY
84744 + Sequence error, PHY error control character detected. */
84745 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84746 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84747 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84748 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84749 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84750 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84751 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84752 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84753 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84754 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84755 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84756 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84757 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84758 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84759 +/* @} */
84760 +
84761 +
84762 +
84763 +/**************************************************************************//**
84764 + @Group FM_PORT_init_grp FM Port Initialization Unit
84765 +
84766 + @Description FM Port Initialization Unit
84767 +
84768 + @{
84769 +*//***************************************************************************/
84770 +
84771 +/**************************************************************************//**
84772 + @Description Exceptions user callback routine, will be called upon an
84773 + exception passing the exception identification.
84774 +
84775 + @Param[in] h_App - User's application descriptor.
84776 + @Param[in] exception - The exception.
84777 + *//***************************************************************************/
84778 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84779 +
84780 +/**************************************************************************//**
84781 + @Description User callback function called by driver with received data.
84782 +
84783 + User provides this function. Driver invokes it.
84784 +
84785 + @Param[in] h_App Application's handle originally specified to
84786 + the API Config function
84787 + @Param[in] p_Data A pointer to data received
84788 + @Param[in] length length of received data
84789 + @Param[in] status receive status and errors
84790 + @Param[in] position position of buffer in frame
84791 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84792 +
84793 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84794 + operation for all ready data.
84795 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84796 +*//***************************************************************************/
84797 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84798 + uint8_t *p_Data,
84799 + uint16_t length,
84800 + uint16_t status,
84801 + uint8_t position,
84802 + t_Handle h_BufContext);
84803 +
84804 +/**************************************************************************//**
84805 + @Description User callback function called by driver when transmit completed.
84806 +
84807 + User provides this function. Driver invokes it.
84808 +
84809 + @Param[in] h_App Application's handle originally specified to
84810 + the API Config function
84811 + @Param[in] p_Data A pointer to data received
84812 + @Param[in] status transmit status and errors
84813 + @Param[in] lastBuffer is last buffer in frame
84814 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84815 + *//***************************************************************************/
84816 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84817 + uint8_t *p_Data,
84818 + uint16_t status,
84819 + t_Handle h_BufContext);
84820 +
84821 +/**************************************************************************//**
84822 + @Description A structure for additional Rx port parameters
84823 +*//***************************************************************************/
84824 +typedef struct t_FmPortRxParams {
84825 + uint32_t errFqid; /**< Error Queue Id. */
84826 + uint32_t dfltFqid; /**< Default Queue Id. */
84827 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84828 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84829 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84830 +} t_FmPortRxParams;
84831 +
84832 +/**************************************************************************//**
84833 + @Description A structure for additional non-Rx port parameters
84834 +*//***************************************************************************/
84835 +typedef struct t_FmPortNonRxParams {
84836 + uint32_t errFqid; /**< Error Queue Id. */
84837 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84838 + 0 means no Tx confirmation for processed
84839 + frames. For OP port - default Rx queue. */
84840 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84841 + by the FM for dequeue. */
84842 +} t_FmPortNonRxParams;
84843 +
84844 +/**************************************************************************//**
84845 + @Description A structure for additional Rx port parameters
84846 +*//***************************************************************************/
84847 +typedef struct t_FmPortImRxTxParams {
84848 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
84849 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
84850 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
84851 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
84852 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
84853 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
84854 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
84855 +} t_FmPortImRxTxParams;
84856 +
84857 +/**************************************************************************//**
84858 + @Description A union for additional parameters depending on port type
84859 +*//***************************************************************************/
84860 +typedef union u_FmPortSpecificParams {
84861 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
84862 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
84863 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
84864 +} u_FmPortSpecificParams;
84865 +
84866 +/**************************************************************************//**
84867 + @Description A structure representing FM initialization parameters
84868 +*//***************************************************************************/
84869 +typedef struct t_FmPortParams {
84870 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
84871 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
84872 + e_FmPortType portType; /**< Port type */
84873 + uint8_t portId; /**< Port Id - relative to type;
84874 + NOTE: When configuring Offline Parsing port for
84875 + FMANv3 devices (DPAA_VERSION 11 and higher),
84876 + it is highly recommended NOT to use portId=0 due to lack
84877 + of HW resources on portId=0. */
84878 + bool independentModeEnable;
84879 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
84880 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
84881 + used together with LIODN offset. */
84882 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
84883 + type. */
84884 +
84885 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
84886 + t_Handle h_App; /**< A handle to an application layer object; This handle will
84887 + be passed by the driver upon calling the above callbacks */
84888 +} t_FmPortParams;
84889 +
84890 +
84891 +/**************************************************************************//**
84892 + @Function FM_PORT_Config
84893 +
84894 + @Description Creates a descriptor for the FM PORT module.
84895 +
84896 + The routine returns a handle (descriptor) to the FM PORT object.
84897 + This descriptor must be passed as first parameter to all other
84898 + FM PORT function calls.
84899 +
84900 + No actual initialization or configuration of FM hardware is
84901 + done by this routine.
84902 +
84903 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
84904 +
84905 + @Retval Handle to FM object, or NULL for Failure.
84906 +*//***************************************************************************/
84907 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
84908 +
84909 +/**************************************************************************//**
84910 + @Function FM_PORT_Init
84911 +
84912 + @Description Initializes the FM PORT module by defining the software structure
84913 + and configuring the hardware registers.
84914 +
84915 + @Param[in] h_FmPort - FM PORT module descriptor
84916 +
84917 + @Return E_OK on success; Error code otherwise.
84918 +*//***************************************************************************/
84919 +t_Error FM_PORT_Init(t_Handle h_FmPort);
84920 +
84921 +/**************************************************************************//**
84922 + @Function FM_PORT_Free
84923 +
84924 + @Description Frees all resources that were assigned to FM PORT module.
84925 +
84926 + Calling this routine invalidates the descriptor.
84927 +
84928 + @Param[in] h_FmPort - FM PORT module descriptor
84929 +
84930 + @Return E_OK on success; Error code otherwise.
84931 +*//***************************************************************************/
84932 +t_Error FM_PORT_Free(t_Handle h_FmPort);
84933 +
84934 +
84935 +/**************************************************************************//**
84936 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
84937 +
84938 + @Description Configuration functions used to change default values.
84939 +
84940 + @{
84941 +*//***************************************************************************/
84942 +
84943 +/**************************************************************************//**
84944 + @Description enum for defining QM frame dequeue
84945 +*//***************************************************************************/
84946 +typedef enum e_FmPortDeqType {
84947 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
84948 + and Intra-Class Scheduling respected. */
84949 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
84950 + and Intra-Class Scheduling respected. */
84951 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
84952 + and override Intra-Class Scheduling */
84953 +} e_FmPortDeqType;
84954 +
84955 +/**************************************************************************//**
84956 + @Description enum for defining QM frame dequeue
84957 +*//***************************************************************************/
84958 +typedef enum e_FmPortDeqPrefetchOption {
84959 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
84960 + only when a dedicated portID Tnum is waiting. */
84961 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
84962 + one dedicated portId tnum is waiting. */
84963 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
84964 + no dedicated portId tnums are waiting. */
84965 +
84966 +} e_FmPortDeqPrefetchOption;
84967 +
84968 +/**************************************************************************//**
84969 + @Description enum for defining port default color
84970 +*//***************************************************************************/
84971 +typedef enum e_FmPortColor {
84972 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
84973 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
84974 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
84975 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
84976 +} e_FmPortColor;
84977 +
84978 +/**************************************************************************//**
84979 + @Description A structure for defining Dual Tx rate limiting scale
84980 +*//***************************************************************************/
84981 +typedef enum e_FmPortDualRateLimiterScaleDown {
84982 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
84983 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
84984 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
84985 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
84986 +} e_FmPortDualRateLimiterScaleDown;
84987 +
84988 +
84989 +/**************************************************************************//**
84990 + @Description A structure for defining FM port resources
84991 +*//***************************************************************************/
84992 +typedef struct t_FmPortRsrc {
84993 + uint32_t num; /**< Committed required resource */
84994 + uint32_t extra; /**< Extra (not committed) required resource */
84995 +} t_FmPortRsrc;
84996 +
84997 +/**************************************************************************//**
84998 + @Description A structure for defining observed pool depletion
84999 +*//***************************************************************************/
85000 +typedef struct t_FmPortObservedBufPoolDepletion {
85001 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
85002 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
85003 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
85004 + and their sizes. */
85005 +} t_FmPortObservedBufPoolDepletion;
85006 +
85007 +/**************************************************************************//**
85008 + @Description A structure for defining Tx rate limiting
85009 +*//***************************************************************************/
85010 +typedef struct t_FmPortRateLimit {
85011 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
85012 + for OP ports. (note that
85013 + for early chips burst size is
85014 + rounded up to a multiply of 1000 frames).*/
85015 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
85016 + OP ports. Rate limit refers to
85017 + data rate (rather than line rate). */
85018 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
85019 + for some earlier chip revisions */
85020 +} t_FmPortRateLimit;
85021 +
85022 +/**************************************************************************//**
85023 + @Description A structure for defining the parameters of
85024 + the Rx port performance counters
85025 +*//***************************************************************************/
85026 +typedef struct t_FmPortPerformanceCnt {
85027 + uint8_t taskCompVal; /**< Task compare value */
85028 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
85029 + value (unused for H/O) */
85030 + uint8_t dmaCompVal; /**< Dma compare value */
85031 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
85032 +} t_FmPortPerformanceCnt;
85033 +
85034 +
85035 +/**************************************************************************//**
85036 + @Description A structure for defining the sizes of the Deep Sleep
85037 + the Auto Response tables
85038 +*//***************************************************************************/
85039 +typedef struct t_FmPortDsarTablesSizes
85040 +{
85041 + uint16_t maxNumOfArpEntries;
85042 + uint16_t maxNumOfEchoIpv4Entries;
85043 + uint16_t maxNumOfNdpEntries;
85044 + uint16_t maxNumOfEchoIpv6Entries;
85045 + uint16_t maxNumOfSnmpIPV4Entries;
85046 + uint16_t maxNumOfSnmpIPV6Entries;
85047 + uint16_t maxNumOfSnmpOidEntries;
85048 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
85049 +
85050 + uint16_t maxNumOfIpProtFiltering;
85051 + uint16_t maxNumOfTcpPortFiltering;
85052 + uint16_t maxNumOfUdpPortFiltering;
85053 +} t_FmPortDsarTablesSizes;
85054 +
85055 +
85056 +/**************************************************************************//**
85057 + @Function FM_PORT_ConfigDsarSupport
85058 +
85059 + @Description This function will allocate the amount of MURAM needed for
85060 + this max number of entries for Deep Sleep Auto Response.
85061 + it will calculate all needed MURAM for autoresponse including
85062 + necesary common stuff.
85063 +
85064 +
85065 + @Param[in] h_FmPort A handle to a FM Port module.
85066 + @Param[in] params A pointer to a structure containing the maximum
85067 + sizes of the auto response tables
85068 +
85069 + @Return E_OK on success; Error code otherwise.
85070 +
85071 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85072 +*//***************************************************************************/
85073 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
85074 +
85075 +/**************************************************************************//**
85076 + @Function FM_PORT_ConfigNumOfOpenDmas
85077 +
85078 + @Description Calling this routine changes the max number of open DMA's
85079 + available for this port. It changes this parameter in the
85080 + internal driver data base from its default configuration
85081 + [OP: 1]
85082 + [1G-RX, 1G-TX: 1 (+1)]
85083 + [10G-RX, 10G-TX: 8 (+8)]
85084 +
85085 + @Param[in] h_FmPort A handle to a FM Port module.
85086 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
85087 + the open DMA allocation.
85088 +
85089 + @Return E_OK on success; Error code otherwise.
85090 +
85091 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85092 +*//***************************************************************************/
85093 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
85094 +
85095 +/**************************************************************************//**
85096 + @Function FM_PORT_ConfigNumOfTasks
85097 +
85098 + @Description Calling this routine changes the max number of tasks
85099 + available for this port. It changes this parameter in the
85100 + internal driver data base from its default configuration
85101 + [OP: 1]
85102 + [1G-RX, 1G-TX: 3 (+2)]
85103 + [10G-RX, 10G-TX: 16 (+8)]
85104 +
85105 + @Param[in] h_FmPort A handle to a FM Port module.
85106 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
85107 + the tasks allocation.
85108 +
85109 + @Return E_OK on success; Error code otherwise.
85110 +
85111 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85112 +*//***************************************************************************/
85113 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
85114 +
85115 +/**************************************************************************//**
85116 + @Function FM_PORT_ConfigSizeOfFifo
85117 +
85118 + @Description Calling this routine changes the max FIFO size configured for this port.
85119 +
85120 + This function changes the internal driver data base from its
85121 + default configuration. Please refer to the driver's User Guide for
85122 + information on default FIFO sizes in the various devices.
85123 + [OP: 2KB]
85124 + [1G-RX, 1G-TX: 11KB]
85125 + [10G-RX, 10G-TX: 12KB]
85126 +
85127 + @Param[in] h_FmPort A handle to a FM Port module.
85128 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
85129 + the FIFO allocation.
85130 +
85131 + @Return E_OK on success; Error code otherwise.
85132 +
85133 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85134 +*//***************************************************************************/
85135 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
85136 +
85137 +/**************************************************************************//**
85138 + @Function FM_PORT_ConfigDeqHighPriority
85139 +
85140 + @Description Calling this routine changes the dequeue priority in the
85141 + internal driver data base from its default configuration
85142 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
85143 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
85144 +
85145 + May be used for Non-Rx ports only
85146 +
85147 + @Param[in] h_FmPort A handle to a FM Port module.
85148 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
85149 +
85150 + @Return E_OK on success; Error code otherwise.
85151 +
85152 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85153 +*//***************************************************************************/
85154 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
85155 +
85156 +/**************************************************************************//**
85157 + @Function FM_PORT_ConfigDeqType
85158 +
85159 + @Description Calling this routine changes the dequeue type parameter in the
85160 + internal driver data base from its default configuration
85161 + [DEFAULT_PORT_deqType].
85162 +
85163 + May be used for Non-Rx ports only
85164 +
85165 + @Param[in] h_FmPort A handle to a FM Port module.
85166 + @Param[in] deqType According to QM definition.
85167 +
85168 + @Return E_OK on success; Error code otherwise.
85169 +
85170 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85171 +*//***************************************************************************/
85172 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
85173 +
85174 +/**************************************************************************//**
85175 + @Function FM_PORT_ConfigDeqPrefetchOption
85176 +
85177 + @Description Calling this routine changes the dequeue prefetch option parameter in the
85178 + internal driver data base from its default configuration
85179 + [DEFAULT_PORT_deqPrefetchOption]
85180 + Note: Available for some chips only
85181 +
85182 + May be used for Non-Rx ports only
85183 +
85184 + @Param[in] h_FmPort A handle to a FM Port module.
85185 + @Param[in] deqPrefetchOption New option
85186 +
85187 + @Return E_OK on success; Error code otherwise.
85188 +
85189 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85190 +*//***************************************************************************/
85191 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
85192 +
85193 +/**************************************************************************//**
85194 + @Function FM_PORT_ConfigDeqByteCnt
85195 +
85196 + @Description Calling this routine changes the dequeue byte count parameter in
85197 + the internal driver data base from its default configuration
85198 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
85199 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
85200 +
85201 + May be used for Non-Rx ports only
85202 +
85203 + @Param[in] h_FmPort A handle to a FM Port module.
85204 + @Param[in] deqByteCnt New byte count
85205 +
85206 + @Return E_OK on success; Error code otherwise.
85207 +
85208 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85209 +*//***************************************************************************/
85210 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
85211 +
85212 +/**************************************************************************//**
85213 + @Function FM_PORT_ConfigBufferPrefixContent
85214 +
85215 + @Description Defines the structure, size and content of the application buffer.
85216 + The prefix will
85217 + In Tx ports, if 'passPrsResult', the application
85218 + should set a value to their offsets in the prefix of
85219 + the FM will save the first 'privDataSize', than,
85220 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
85221 + and timeStamp, and the packet itself (in this order), to the
85222 + application buffer, and to offset.
85223 + Calling this routine changes the buffer margins definitions
85224 + in the internal driver data base from its default
85225 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
85226 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
85227 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
85228 +
85229 + May be used for all ports
85230 +
85231 + @Param[in] h_FmPort A handle to a FM Port module.
85232 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
85233 + structure of the buffer.
85234 + Out parameter: Start margin - offset
85235 + of data from start of external buffer.
85236 +
85237 + @Return E_OK on success; Error code otherwise.
85238 +
85239 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85240 +*//***************************************************************************/
85241 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
85242 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
85243 +
85244 +/**************************************************************************//**
85245 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
85246 +
85247 + @Description Calling this routine changes the number of checksum bytes to ignore
85248 + parameter in the internal driver data base from its default configuration
85249 + [DEFAULT_PORT_cheksumLastBytesIgnore]
85250 +
85251 + May be used by Tx & Rx ports only
85252 +
85253 + @Param[in] h_FmPort A handle to a FM Port module.
85254 + @Param[in] cheksumLastBytesIgnore New value
85255 +
85256 + @Return E_OK on success; Error code otherwise.
85257 +
85258 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85259 +*//***************************************************************************/
85260 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
85261 +
85262 +/**************************************************************************//**
85263 + @Function FM_PORT_ConfigCutBytesFromEnd
85264 +
85265 + @Description Calling this routine changes the number of bytes to cut from a
85266 + frame's end parameter in the internal driver data base
85267 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
85268 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
85269 + less than 14 bytes, the chop operation is not executed.
85270 +
85271 + May be used for Rx ports only
85272 +
85273 + @Param[in] h_FmPort A handle to a FM Port module.
85274 + @Param[in] cutBytesFromEnd New value
85275 +
85276 + @Return E_OK on success; Error code otherwise.
85277 +
85278 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85279 +*//***************************************************************************/
85280 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
85281 +
85282 +/**************************************************************************//**
85283 + @Function FM_PORT_ConfigPoolDepletion
85284 +
85285 + @Description Calling this routine enables pause frame generation depending on the
85286 + depletion status of BM pools. It also defines the conditions to activate
85287 + this functionality. By default, this functionality is disabled.
85288 +
85289 + May be used for Rx ports only
85290 +
85291 + @Param[in] h_FmPort A handle to a FM Port module.
85292 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
85293 +
85294 + @Return E_OK on success; Error code otherwise.
85295 +
85296 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85297 +*//***************************************************************************/
85298 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
85299 +
85300 +/**************************************************************************//**
85301 + @Function FM_PORT_ConfigObservedPoolDepletion
85302 +
85303 + @Description Calling this routine enables a mechanism to stop port enqueue
85304 + depending on the depletion status of selected BM pools.
85305 + It also defines the conditions to activate
85306 + this functionality. By default, this functionality is disabled.
85307 +
85308 + Note: Available for some chips only
85309 +
85310 + May be used for OP ports only
85311 +
85312 + @Param[in] h_FmPort A handle to a FM Port module.
85313 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
85314 +
85315 + @Return E_OK on success; Error code otherwise.
85316 +
85317 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85318 +*//***************************************************************************/
85319 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
85320 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
85321 +
85322 +/**************************************************************************//**
85323 + @Function FM_PORT_ConfigExtBufPools
85324 +
85325 + @Description This routine should be called for OP ports
85326 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
85327 + re-assembly, the FM needs new BM buffers. By calling this routine the user
85328 + specifies the BM buffer pools that should be used.
85329 +
85330 + Note: Available for some chips only
85331 +
85332 + May be used for OP ports only
85333 +
85334 + @Param[in] h_FmPort A handle to a FM Port module.
85335 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
85336 +
85337 + @Return E_OK on success; Error code otherwise.
85338 +
85339 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85340 +*//***************************************************************************/
85341 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
85342 +
85343 +/**************************************************************************//**
85344 + @Function FM_PORT_ConfigBackupPools
85345 +
85346 + @Description Calling this routine allows the configuration of some of the BM pools
85347 + defined for this port as backup pools.
85348 + A pool configured to be a backup pool will be used only if all other
85349 + enabled non-backup pools are depleted.
85350 +
85351 + May be used for Rx ports only
85352 +
85353 + @Param[in] h_FmPort A handle to a FM Port module.
85354 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85355 + be defined as backup pools.
85356 +
85357 + @Return E_OK on success; Error code otherwise.
85358 +
85359 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85360 +*//***************************************************************************/
85361 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85362 +
85363 +/**************************************************************************//**
85364 + @Function FM_PORT_ConfigFrmDiscardOverride
85365 +
85366 + @Description Calling this routine changes the error frames destination parameter
85367 + in the internal driver data base from its default configuration:
85368 + override = [DEFAULT_PORT_frmDiscardOverride]
85369 +
85370 + May be used for Rx and OP ports only
85371 +
85372 + @Param[in] h_FmPort A handle to a FM Port module.
85373 + @Param[in] override TRUE to override discarding of error frames and
85374 + enqueueing them to error queue.
85375 +
85376 + @Return E_OK on success; Error code otherwise.
85377 +
85378 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85379 +*//***************************************************************************/
85380 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85381 +
85382 +/**************************************************************************//**
85383 + @Function FM_PORT_ConfigErrorsToDiscard
85384 +
85385 + @Description Calling this routine changes the behaviour on error parameter
85386 + in the internal driver data base from its default configuration:
85387 + [DEFAULT_PORT_errorsToDiscard].
85388 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85389 + definition will change and the frame will be discarded.
85390 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85391 + "ErrorsToDiscard", will be forwarded to CPU.
85392 +
85393 + May be used for Rx and OP ports only
85394 +
85395 + @Param[in] h_FmPort A handle to a FM Port module.
85396 + @Param[in] errs A list of errors to discard
85397 +
85398 + @Return E_OK on success; Error code otherwise.
85399 +
85400 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85401 +*//***************************************************************************/
85402 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85403 +
85404 +/**************************************************************************//**
85405 + @Function FM_PORT_ConfigDmaSwapData
85406 +
85407 + @Description Calling this routine changes the DMA swap data aparameter
85408 + in the internal driver data base from its default
85409 + configuration [DEFAULT_PORT_dmaSwapData]
85410 +
85411 + May be used for all port types
85412 +
85413 + @Param[in] h_FmPort A handle to a FM Port module.
85414 + @Param[in] swapData New selection
85415 +
85416 + @Return E_OK on success; Error code otherwise.
85417 +
85418 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85419 +*//***************************************************************************/
85420 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85421 +
85422 +/**************************************************************************//**
85423 + @Function FM_PORT_ConfigDmaIcCacheAttr
85424 +
85425 + @Description Calling this routine changes the internal context cache
85426 + attribute parameter in the internal driver data base
85427 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85428 +
85429 + May be used for all port types
85430 +
85431 + @Param[in] h_FmPort A handle to a FM Port module.
85432 + @Param[in] intContextCacheAttr New selection
85433 +
85434 + @Return E_OK on success; Error code otherwise.
85435 +
85436 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85437 +*//***************************************************************************/
85438 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85439 +
85440 +/**************************************************************************//**
85441 + @Function FM_PORT_ConfigDmaHdrAttr
85442 +
85443 + @Description Calling this routine changes the header cache
85444 + attribute parameter in the internal driver data base
85445 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85446 +
85447 + May be used for all port types
85448 +
85449 + @Param[in] h_FmPort A handle to a FM Port module.
85450 + @Param[in] headerCacheAttr New selection
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 +*//***************************************************************************/
85456 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85457 +
85458 +/**************************************************************************//**
85459 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85460 +
85461 + @Description Calling this routine changes the scatter gather cache
85462 + attribute parameter in the internal driver data base
85463 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85464 +
85465 + May be used for all port types
85466 +
85467 + @Param[in] h_FmPort A handle to a FM Port module.
85468 + @Param[in] scatterGatherCacheAttr New selection
85469 +
85470 + @Return E_OK on success; Error code otherwise.
85471 +
85472 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85473 +*//***************************************************************************/
85474 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85475 +
85476 +/**************************************************************************//**
85477 + @Function FM_PORT_ConfigDmaWriteOptimize
85478 +
85479 + @Description Calling this routine changes the write optimization
85480 + parameter in the internal driver data base
85481 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85482 + Note:
85483 +
85484 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85485 +
85486 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85487 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85488 + is extended to be on 16/64 bytes aligned block (chip dependent).
85489 +
85490 + Relevant for non-Tx port types
85491 +
85492 + @Param[in] h_FmPort A handle to a FM Port module.
85493 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85494 +
85495 + @Return E_OK on success; Error code otherwise.
85496 +
85497 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85498 +*//***************************************************************************/
85499 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85500 +
85501 +/**************************************************************************//**
85502 + @Function FM_PORT_ConfigNoScatherGather
85503 +
85504 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85505 + from its default configuration.
85506 +
85507 + @Param[in] h_FmPort A handle to a FM Port module.
85508 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85509 + FALSE - frame can be stored in scatter gather (S/G) format).
85510 +
85511 + @Return E_OK on success; Error code otherwise.
85512 +
85513 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85514 +*//***************************************************************************/
85515 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85516 +
85517 +/**************************************************************************//**
85518 + @Function FM_PORT_ConfigDfltColor
85519 +
85520 + @Description Calling this routine changes the internal default color parameter
85521 + in the internal driver data base
85522 + from its default configuration [DEFAULT_PORT_color]
85523 +
85524 + May be used for all port types
85525 +
85526 + @Param[in] h_FmPort A handle to a FM Port module.
85527 + @Param[in] color New selection
85528 +
85529 + @Return E_OK on success; Error code otherwise.
85530 +
85531 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85532 +*//***************************************************************************/
85533 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85534 +
85535 +/**************************************************************************//**
85536 + @Function FM_PORT_ConfigSyncReq
85537 +
85538 + @Description Calling this routine changes the synchronization attribute parameter
85539 + in the internal driver data base from its default configuration:
85540 + syncReq = [DEFAULT_PORT_syncReq]
85541 +
85542 + May be used for all port types
85543 +
85544 + @Param[in] h_FmPort A handle to a FM Port module.
85545 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85546 +
85547 + @Return E_OK on success; Error code otherwise.
85548 +
85549 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85550 +*//***************************************************************************/
85551 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85552 +
85553 +/**************************************************************************//**
85554 + @Function FM_PORT_ConfigForwardReuseIntContext
85555 +
85556 + @Description This routine is relevant for Rx ports that are routed to OP port.
85557 + It changes the internal context reuse option in the internal
85558 + driver data base from its default configuration:
85559 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85560 +
85561 + May be used for Rx ports only
85562 +
85563 + @Param[in] h_FmPort A handle to a FM Port module.
85564 + @Param[in] reuse TRUE to reuse internal context on frames
85565 + forwarded to OP port.
85566 +
85567 + @Return E_OK on success; Error code otherwise.
85568 +
85569 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85570 +*//***************************************************************************/
85571 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85572 +
85573 +/**************************************************************************//**
85574 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85575 +
85576 + @Description This routine should be called if no Tx confirmation
85577 + is done, and yet buffers should not be released to the BM.
85578 + Normally, buffers are returned using the Tx confirmation
85579 + process. When Tx confirmation is not used (defFqid=0),
85580 + buffers are typically released to the BM. This routine
85581 + may be called to avoid this behavior and not release the
85582 + buffers.
85583 +
85584 + May be used for Tx ports only
85585 +
85586 + @Param[in] h_FmPort A handle to a FM Port module.
85587 +
85588 + @Return E_OK on success; Error code otherwise.
85589 +
85590 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85591 +*//***************************************************************************/
85592 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85593 +
85594 +/**************************************************************************//**
85595 + @Function FM_PORT_ConfigIMMaxRxBufLength
85596 +
85597 + @Description Changes the maximum receive buffer length from its default
85598 + configuration: Closest rounded down power of 2 value of the
85599 + data buffer size.
85600 +
85601 + The maximum receive buffer length directly affects the structure
85602 + of received frames (single- or multi-buffered) and the performance
85603 + of both the FM and the driver.
85604 +
85605 + The selection between single- or multi-buffered frames should be
85606 + done according to the characteristics of the specific application.
85607 + The recommended mode is to use a single data buffer per packet,
85608 + as this mode provides the best performance. However, the user can
85609 + select to use multiple data buffers per packet.
85610 +
85611 + @Param[in] h_FmPort A handle to a FM Port module.
85612 + @Param[in] newVal Maximum receive buffer length (in bytes).
85613 +
85614 + @Return E_OK on success; Error code otherwise.
85615 +
85616 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85617 + This routine is to be used only if Independent-Mode is enabled.
85618 +*//***************************************************************************/
85619 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85620 +
85621 +/**************************************************************************//**
85622 + @Function FM_PORT_ConfigIMRxBdRingLength
85623 +
85624 + @Description Changes the receive BD ring length from its default
85625 + configuration:[DEFAULT_PORT_rxBdRingLength]
85626 +
85627 + @Param[in] h_FmPort A handle to a FM Port module.
85628 + @Param[in] newVal The desired BD ring length.
85629 +
85630 + @Return E_OK on success; Error code otherwise.
85631 +
85632 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85633 + This routine is to be used only if Independent-Mode is enabled.
85634 +*//***************************************************************************/
85635 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85636 +
85637 +/**************************************************************************//**
85638 + @Function FM_PORT_ConfigIMTxBdRingLength
85639 +
85640 + @Description Changes the transmit BD ring length from its default
85641 + configuration:[DEFAULT_PORT_txBdRingLength]
85642 +
85643 + @Param[in] h_FmPort A handle to a FM Port module.
85644 + @Param[in] newVal The desired BD ring length.
85645 +
85646 + @Return E_OK on success; Error code otherwise.
85647 +
85648 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85649 + This routine is to be used only if Independent-Mode is enabled.
85650 +*//***************************************************************************/
85651 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85652 +
85653 +/**************************************************************************//**
85654 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85655 +
85656 + @Description Configures memory partition and attributes for FMan-Controller
85657 + data structures (e.g. BD rings).
85658 + Calling this routine changes the internal driver data base
85659 + from its default configuration
85660 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85661 +
85662 + @Param[in] h_FmPort A handle to a FM Port module.
85663 + @Param[in] memId Memory partition ID.
85664 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85665 +
85666 + @Return E_OK on success; Error code otherwise.
85667 +*//***************************************************************************/
85668 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85669 + uint8_t memId,
85670 + uint32_t memAttributes);
85671 +
85672 +/**************************************************************************//**
85673 + @Function FM_PORT_ConfigIMPolling
85674 +
85675 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85676 +
85677 + @Param[in] h_FmPort A handle to a FM Port module.
85678 +
85679 + @Return E_OK on success; Error code otherwise.
85680 +
85681 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85682 + This routine is to be used only if Independent-Mode is enabled.
85683 +*//***************************************************************************/
85684 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85685 +
85686 +/**************************************************************************//**
85687 + @Function FM_PORT_ConfigMaxFrameLength
85688 +
85689 + @Description Changes the definition of the max size of frame that should be
85690 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85691 + This parameter is used for confirmation of the minimum Fifo
85692 + size calculations and only for Tx ports or ports working in
85693 + independent mode. This should be larger than the maximum possible
85694 + MTU that will be used for this port (i.e. its MAC).
85695 +
85696 + @Param[in] h_FmPort A handle to a FM Port module.
85697 + @Param[in] length Max size of frame
85698 +
85699 + @Return E_OK on success; Error code otherwise.
85700 +
85701 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85702 + This routine is to be used only if Independent-Mode is enabled.
85703 +*//***************************************************************************/
85704 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85705 +
85706 +/**************************************************************************//*
85707 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85708 +
85709 + @Description Calling this routine changes the fifo minimum
85710 + fill level parameter in the internal driver data base
85711 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
85712 +
85713 + May be used for Tx ports only
85714 +
85715 + @Param[in] h_FmPort A handle to a FM Port module.
85716 + @Param[in] minFillLevel New value
85717 +
85718 + @Return E_OK on success; Error code otherwise.
85719 +
85720 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85721 +*//***************************************************************************/
85722 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85723 +
85724 +/**************************************************************************//*
85725 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85726 +
85727 + @Description Calling this routine changes the fifo dequeue
85728 + pipeline depth parameter in the internal driver data base
85729 +
85730 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85731 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85732 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85733 +
85734 + May be used for Tx/OP ports only
85735 +
85736 + @Param[in] h_FmPort A handle to a FM Port module.
85737 + @Param[in] deqPipelineDepth New value
85738 +
85739 + @Return E_OK on success; Error code otherwise.
85740 +
85741 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85742 +*//***************************************************************************/
85743 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85744 +
85745 +/**************************************************************************//*
85746 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85747 +
85748 + @Description Calling this routine changes the fifo low comfort level
85749 + parameter in internal driver data base
85750 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85751 +
85752 + May be used for Tx ports only
85753 +
85754 + @Param[in] h_FmPort A handle to a FM Port module.
85755 + @Param[in] fifoLowComfLevel New value
85756 +
85757 + @Return E_OK on success; Error code otherwise.
85758 +
85759 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85760 +*//***************************************************************************/
85761 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85762 +
85763 +/**************************************************************************//*
85764 + @Function FM_PORT_ConfigRxFifoThreshold
85765 +
85766 + @Description Calling this routine changes the threshold of the FIFO
85767 + fill level parameter in the internal driver data base
85768 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85769 +
85770 + If the total number of buffers which are
85771 + currently in use and associated with the
85772 + specific RX port exceed this threshold, the
85773 + BMI will signal the MAC to send a pause frame
85774 + over the link.
85775 +
85776 + May be used for Rx ports only
85777 +
85778 + @Param[in] h_FmPort A handle to a FM Port module.
85779 + @Param[in] fifoThreshold New value
85780 +
85781 + @Return E_OK on success; Error code otherwise.
85782 +
85783 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85784 +*//***************************************************************************/
85785 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85786 +
85787 +/**************************************************************************//*
85788 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85789 +
85790 + @Description Calling this routine changes the priority elevation level
85791 + parameter in the internal driver data base from its default
85792 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85793 +
85794 + If the total number of buffers which are currently in use and
85795 + associated with the specific RX port exceed the amount specified
85796 + in priElevationLevel, BMI will signal the main FM's DMA to
85797 + elevate the FM priority on the system bus.
85798 +
85799 + May be used for Rx ports only
85800 +
85801 + @Param[in] h_FmPort A handle to a FM Port module.
85802 + @Param[in] priElevationLevel New value
85803 +
85804 + @Return E_OK on success; Error code otherwise.
85805 +
85806 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85807 +*//***************************************************************************/
85808 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85809 +
85810 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85811 +/**************************************************************************//*
85812 + @Function FM_PORT_ConfigBCBWorkaround
85813 +
85814 + @Description Configures BCB errata workaround.
85815 +
85816 + When BCB errata is applicable, the workaround is always
85817 + performed by FM Controller. Thus, this functions doesn't
85818 + actually enable errata workaround but rather allows driver
85819 + to perform adjustments required due to errata workaround
85820 + execution in FM controller.
85821 +
85822 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85823 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85824 + set by FM_PORT_SetErrorsRoute() function.
85825 +
85826 + @Param[in] h_FmPort A handle to a FM Port module.
85827 +
85828 + @Return E_OK on success; Error code otherwise.
85829 +
85830 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85831 +*//***************************************************************************/
85832 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85833 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85834 +
85835 +#if (DPAA_VERSION >= 11)
85836 +/**************************************************************************//*
85837 + @Function FM_PORT_ConfigInternalBuffOffset
85838 +
85839 + @Description Configures internal buffer offset.
85840 +
85841 + May be used for Rx and OP ports only
85842 +
85843 + @Param[in] h_FmPort A handle to a FM Port module.
85844 + @Param[in] val New value
85845 +
85846 + @Return E_OK on success; Error code otherwise.
85847 +
85848 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85849 +*//***************************************************************************/
85850 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
85851 +#endif /* (DPAA_VERSION >= 11) */
85852 +
85853 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
85854 +/** @} */ /* end of FM_PORT_init_grp group */
85855 +
85856 +
85857 +/**************************************************************************//**
85858 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
85859 +
85860 + @Description FM Port Runtime control unit API functions, definitions and enums.
85861 +
85862 + @{
85863 +*//***************************************************************************/
85864 +
85865 +/**************************************************************************//**
85866 + @Description enum for defining FM Port counters
85867 +*//***************************************************************************/
85868 +typedef enum e_FmPortCounters {
85869 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
85870 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
85871 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
85872 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
85873 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
85874 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
85875 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
85876 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
85877 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
85878 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
85879 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
85880 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
85881 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
85882 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
85883 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
85884 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
85885 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
85886 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
85887 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
85888 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
85889 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
85890 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
85891 +} e_FmPortCounters;
85892 +
85893 +typedef struct t_FmPortBmiStats {
85894 + uint32_t cntCycle;
85895 + uint32_t cntTaskUtil;
85896 + uint32_t cntQueueUtil;
85897 + uint32_t cntDmaUtil;
85898 + uint32_t cntFifoUtil;
85899 + uint32_t cntRxPauseActivation;
85900 + uint32_t cntFrame;
85901 + uint32_t cntDiscardFrame;
85902 + uint32_t cntDeallocBuf;
85903 + uint32_t cntRxBadFrame;
85904 + uint32_t cntRxLargeFrame;
85905 + uint32_t cntRxFilterFrame;
85906 + uint32_t cntRxListDmaErr;
85907 + uint32_t cntRxOutOfBuffersDiscard;
85908 + uint32_t cntWredDiscard;
85909 + uint32_t cntLengthErr;
85910 + uint32_t cntUnsupportedFormat;
85911 +} t_FmPortBmiStats;
85912 +
85913 +/**************************************************************************//**
85914 + @Description Structure for Port id parameters.
85915 + Fields commented 'IN' are passed by the port module to be used
85916 + by the FM module.
85917 + Fields commented 'OUT' will be filled by FM before returning to port.
85918 +*//***************************************************************************/
85919 +typedef struct t_FmPortCongestionGrps {
85920 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
85921 + to define the size of the following array */
85922 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
85923 + /**< An array of CG indexes;
85924 + Note that the size of the array should be
85925 + 'numOfCongestionGrpsToConsider'. */
85926 +#if (DPAA_VERSION >= 11)
85927 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
85928 + /**< a matrix that represents the map between the CG ids
85929 + defined in 'congestionGrpsToConsider' to the priorties
85930 + mapping array. */
85931 +#endif /* (DPAA_VERSION >= 11) */
85932 +} t_FmPortCongestionGrps;
85933 +
85934 +/**************************************************************************//**
85935 + @Description Structure for Deep Sleep Auto Response ARP Entry
85936 +*//***************************************************************************/
85937 +typedef struct t_FmPortDsarArpEntry
85938 +{
85939 + uint32_t ipAddress;
85940 + uint8_t mac[6];
85941 + bool isVlan;
85942 + uint16_t vid;
85943 +} t_FmPortDsarArpEntry;
85944 +
85945 +/**************************************************************************//**
85946 + @Description Structure for Deep Sleep Auto Response ARP info
85947 +*//***************************************************************************/
85948 +typedef struct t_FmPortDsarArpInfo
85949 +{
85950 + uint8_t tableSize;
85951 + t_FmPortDsarArpEntry *p_AutoResTable;
85952 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85953 +} t_FmPortDsarArpInfo;
85954 +
85955 +/**************************************************************************//**
85956 + @Description Structure for Deep Sleep Auto Response NDP Entry
85957 +*//***************************************************************************/
85958 +typedef struct t_FmPortDsarNdpEntry
85959 +{
85960 + uint32_t ipAddress[4];
85961 + uint8_t mac[6];
85962 + bool isVlan;
85963 + uint16_t vid;
85964 +} t_FmPortDsarNdpEntry;
85965 +
85966 +/**************************************************************************//**
85967 + @Description Structure for Deep Sleep Auto Response NDP info
85968 +*//***************************************************************************/
85969 +typedef struct t_FmPortDsarNdpInfo
85970 +{
85971 + uint32_t multicastGroup;
85972 +
85973 + uint8_t tableSizeAssigned;
85974 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
85975 + Note that all IP adresses must be from the same multicast group.
85976 + This will be checked and if not operation will fail. */
85977 + uint8_t tableSizeTmp;
85978 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
85979 + Note that all temp IP adresses must be from the same multicast group.
85980 + This will be checked and if not operation will fail. */
85981 +
85982 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85983 +
85984 +} t_FmPortDsarNdpInfo;
85985 +
85986 +/**************************************************************************//**
85987 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
85988 +*//***************************************************************************/
85989 +typedef struct t_FmPortDsarEchoIpv4Info
85990 +{
85991 + uint8_t tableSize;
85992 + t_FmPortDsarArpEntry *p_AutoResTable;
85993 +} t_FmPortDsarEchoIpv4Info;
85994 +
85995 +/**************************************************************************//**
85996 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
85997 +*//***************************************************************************/
85998 +typedef struct t_FmPortDsarEchoIpv6Info
85999 +{
86000 + uint8_t tableSize;
86001 + t_FmPortDsarNdpEntry *p_AutoResTable;
86002 +} t_FmPortDsarEchoIpv6Info;
86003 +
86004 +/**************************************************************************//**
86005 +@Description Deep Sleep Auto Response SNMP OIDs table entry
86006 +
86007 +*//***************************************************************************/
86008 +typedef struct {
86009 + uint16_t oidSize;
86010 + uint8_t *oidVal; /* only the oid string */
86011 + uint16_t resSize;
86012 + uint8_t *resVal; /* resVal will be the entire reply,
86013 + i.e. "Type|Length|Value" */
86014 +} t_FmPortDsarOidsEntry;
86015 +
86016 +/**************************************************************************//**
86017 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
86018 + Refer to the FMan Controller spec for more details.
86019 +*//***************************************************************************/
86020 +typedef struct
86021 +{
86022 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
86023 + bool isVlan;
86024 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86025 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86026 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
86027 +
86028 +/**************************************************************************//**
86029 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
86030 + Refer to the FMan Controller spec for more details.
86031 +*//***************************************************************************/
86032 +typedef struct
86033 +{
86034 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
86035 + bool isVlan;
86036 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86037 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86038 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
86039 +
86040 +/**************************************************************************//**
86041 + @Description Deep Sleep Auto Response SNMP Descriptor
86042 +
86043 +*//***************************************************************************/
86044 +typedef struct
86045 +{
86046 + uint16_t control; /**< Control bits [0-15]. */
86047 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
86048 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
86049 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
86050 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
86051 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
86052 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
86053 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
86054 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
86055 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
86056 +} t_FmPortDsarSnmpInfo;
86057 +
86058 +/**************************************************************************//**
86059 + @Description Structure for Deep Sleep Auto Response filtering Entry
86060 +*//***************************************************************************/
86061 +typedef struct t_FmPortDsarFilteringEntry
86062 +{
86063 + uint16_t srcPort;
86064 + uint16_t dstPort;
86065 + uint16_t srcPortMask;
86066 + uint16_t dstPortMask;
86067 +} t_FmPortDsarFilteringEntry;
86068 +
86069 +/**************************************************************************//**
86070 + @Description Structure for Deep Sleep Auto Response filtering info
86071 +*//***************************************************************************/
86072 +typedef struct t_FmPortDsarFilteringInfo
86073 +{
86074 + /* IP protocol filtering parameters */
86075 + uint8_t ipProtTableSize;
86076 + uint8_t *p_IpProtTablePtr;
86077 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86078 + hit will pass the packet to UDP/TCP filters if needed and if not
86079 + to the classification tree. If the classification tree will pass
86080 + the packet to a queue it will cause a wake interupt.
86081 + When FALSE it the other way around. */
86082 + /* UDP port filtering parameters */
86083 + uint8_t udpPortsTableSize;
86084 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
86085 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86086 + hit will pass the packet to classification tree.
86087 + If the classification tree will pass the packet to a queue it
86088 + will cause a wake interupt.
86089 + When FALSE it the other way around. */
86090 + /* TCP port filtering parameters */
86091 + uint16_t tcpFlagsMask;
86092 + uint8_t tcpPortsTableSize;
86093 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
86094 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86095 + hit will pass the packet to classification tree.
86096 + If the classification tree will pass the packet to a queue it
86097 + will cause a wake interupt.
86098 + When FALSE it the other way around. */
86099 +} t_FmPortDsarFilteringInfo;
86100 +
86101 +/**************************************************************************//**
86102 + @Description Structure for Deep Sleep Auto Response parameters
86103 +*//***************************************************************************/
86104 +typedef struct t_FmPortDsarParams
86105 +{
86106 + t_Handle h_FmPortTx;
86107 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
86108 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
86109 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
86110 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
86111 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
86112 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
86113 +} t_FmPortDsarParams;
86114 +
86115 +/**************************************************************************//**
86116 + @Function FM_PORT_EnterDsar
86117 +
86118 + @Description Enter Deep Sleep Auto Response mode.
86119 + This function write the apropriate values to in the relevant
86120 + tables in the MURAM.
86121 +
86122 + @Param[in] h_FmPortRx - FM PORT module descriptor
86123 + @Param[in] params - Auto Response parameters
86124 +
86125 + @Return E_OK on success; Error code otherwise.
86126 +
86127 + @Cautions Allowed only following FM_PORT_Init().
86128 +*//***************************************************************************/
86129 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
86130 +
86131 +/**************************************************************************//**
86132 + @Function FM_PORT_EnterDsarFinal
86133 +
86134 + @Description Enter Deep Sleep Auto Response mode.
86135 + This function sets the Tx port in independent mode as needed
86136 + and redirect the receive flow to go through the
86137 + Dsar Fman-ctrl code
86138 +
86139 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
86140 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
86141 +
86142 + @Return E_OK on success; Error code otherwise.
86143 +
86144 + @Cautions Allowed only following FM_PORT_Init().
86145 +*//***************************************************************************/
86146 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
86147 +
86148 +/**************************************************************************//**
86149 + @Function FM_PORT_ExitDsar
86150 +
86151 + @Description Exit Deep Sleep Auto Response mode.
86152 + This function reverse the AR mode and put the ports back into
86153 + their original wake mode
86154 +
86155 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
86156 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
86157 +
86158 + @Return E_OK on success; Error code otherwise.
86159 +
86160 + @Cautions Allowed only following FM_PORT_EnterDsar().
86161 +*//***************************************************************************/
86162 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
86163 +
86164 +/**************************************************************************//**
86165 + @Function FM_PORT_IsInDsar
86166 +
86167 + @Description This function returns TRUE if the port was set as Auto Response
86168 + and FALSE if not. Once Exit AR mode it will return FALSE as well
86169 + until re-enabled once more.
86170 +
86171 + @Param[in] h_FmPort - FM PORT module descriptor
86172 +
86173 + @Return E_OK on success; Error code otherwise.
86174 +*//***************************************************************************/
86175 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
86176 +
86177 +typedef struct t_FmPortDsarStats
86178 +{
86179 + uint32_t arpArCnt;
86180 + uint32_t echoIcmpv4ArCnt;
86181 + uint32_t ndpArCnt;
86182 + uint32_t echoIcmpv6ArCnt;
86183 + uint32_t snmpGetCnt;
86184 + uint32_t snmpGetNextCnt;
86185 +} t_FmPortDsarStats;
86186 +
86187 +/**************************************************************************//**
86188 + @Function FM_PORT_GetDsarStats
86189 +
86190 + @Description Return statistics for Deep Sleep Auto Response
86191 +
86192 + @Param[in] h_FmPortRx - FM PORT module descriptor
86193 + @Param[out] stats - structure containing the statistics counters
86194 +
86195 + @Return E_OK on success; Error code otherwise.
86196 +*//***************************************************************************/
86197 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
86198 +
86199 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
86200 +/**************************************************************************//**
86201 + @Function FM_PORT_DumpRegs
86202 +
86203 + @Description Dump all regs.
86204 +
86205 + Calling this routine invalidates the descriptor.
86206 +
86207 + @Param[in] h_FmPort - FM PORT module descriptor
86208 +
86209 + @Return E_OK on success; Error code otherwise.
86210 +
86211 + @Cautions Allowed only following FM_PORT_Init().
86212 +*//***************************************************************************/
86213 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
86214 +#endif /* (defined(DEBUG_ERRORS) && ... */
86215 +
86216 +/**************************************************************************//**
86217 + @Function FM_PORT_GetBufferDataOffset
86218 +
86219 + @Description Relevant for Rx ports.
86220 + Returns the data offset from the beginning of the data buffer
86221 +
86222 + @Param[in] h_FmPort - FM PORT module descriptor
86223 +
86224 + @Return data offset.
86225 +
86226 + @Cautions Allowed only following FM_PORT_Init().
86227 +*//***************************************************************************/
86228 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
86229 +
86230 +/**************************************************************************//**
86231 + @Function FM_PORT_GetBufferICInfo
86232 +
86233 + @Description Returns the Internal Context offset from the beginning of the data buffer
86234 +
86235 + @Param[in] h_FmPort - FM PORT module descriptor
86236 + @Param[in] p_Data - A pointer to the data buffer.
86237 +
86238 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
86239 + configured for this port.
86240 +
86241 + @Cautions Allowed only following FM_PORT_Init().
86242 +*//***************************************************************************/
86243 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
86244 +
86245 +/**************************************************************************//**
86246 + @Function FM_PORT_GetBufferPrsResult
86247 +
86248 + @Description Returns the pointer to the parse result in the data buffer.
86249 + In Rx ports this is relevant after reception, if parse
86250 + result is configured to be part of the data passed to the
86251 + application. For non Rx ports it may be used to get the pointer
86252 + of the area in the buffer where parse result should be
86253 + initialized - if so configured.
86254 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86255 + configuration.
86256 +
86257 + @Param[in] h_FmPort - FM PORT module descriptor
86258 + @Param[in] p_Data - A pointer to the data buffer.
86259 +
86260 + @Return Parse result pointer on success, NULL if parse result was not
86261 + configured for this port.
86262 +
86263 + @Cautions Allowed only following FM_PORT_Init().
86264 +*//***************************************************************************/
86265 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
86266 +
86267 +/**************************************************************************//**
86268 + @Function FM_PORT_GetBufferTimeStamp
86269 +
86270 + @Description Returns the time stamp in the data buffer.
86271 + Relevant for Rx ports for getting the buffer time stamp.
86272 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86273 + configuration.
86274 +
86275 + @Param[in] h_FmPort - FM PORT module descriptor
86276 + @Param[in] p_Data - A pointer to the data buffer.
86277 +
86278 + @Return A pointer to the hash result on success, NULL otherwise.
86279 +
86280 + @Cautions Allowed only following FM_PORT_Init().
86281 +*//***************************************************************************/
86282 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
86283 +
86284 +/**************************************************************************//**
86285 + @Function FM_PORT_GetBufferHashResult
86286 +
86287 + @Description Given a data buffer, on the condition that hash result was defined
86288 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
86289 + this routine will return the pointer to the hash result location in the
86290 + buffer prefix.
86291 +
86292 + @Param[in] h_FmPort - FM PORT module descriptor
86293 + @Param[in] p_Data - A pointer to the data buffer.
86294 +
86295 + @Return A pointer to the hash result on success, NULL otherwise.
86296 +
86297 + @Cautions Allowed only following FM_PORT_Init().
86298 +*//***************************************************************************/
86299 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
86300 +
86301 +/**************************************************************************//**
86302 + @Function FM_PORT_Disable
86303 +
86304 + @Description Gracefully disable an FM port. The port will not start new tasks after all
86305 + tasks associated with the port are terminated.
86306 +
86307 + @Param[in] h_FmPort A handle to a FM Port module.
86308 +
86309 + @Return E_OK on success; Error code otherwise.
86310 +
86311 + @Cautions Allowed only following FM_PORT_Init().
86312 + This is a blocking routine, it returns after port is
86313 + gracefully stopped, i.e. the port will not except new frames,
86314 + but it will finish all frames or tasks which were already began
86315 +*//***************************************************************************/
86316 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
86317 +
86318 +/**************************************************************************//**
86319 + @Function FM_PORT_Enable
86320 +
86321 + @Description A runtime routine provided to allow disable/enable of port.
86322 +
86323 + @Param[in] h_FmPort A handle to a FM Port module.
86324 +
86325 + @Return E_OK on success; Error code otherwise.
86326 +
86327 + @Cautions Allowed only following FM_PORT_Init().
86328 +*//***************************************************************************/
86329 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
86330 +
86331 +/**************************************************************************//**
86332 + @Function FM_PORT_SetRateLimit
86333 +
86334 + @Description Calling this routine enables rate limit algorithm.
86335 + By default, this functionality is disabled.
86336 + Note that rate-limit mechanism uses the FM time stamp.
86337 + The selected rate limit specified here would be
86338 + rounded DOWN to the nearest 16M.
86339 +
86340 + May be used for Tx and OP ports only
86341 +
86342 + @Param[in] h_FmPort A handle to a FM Port module.
86343 + @Param[in] p_RateLimit A structure of rate limit parameters
86344 +
86345 + @Return E_OK on success; Error code otherwise.
86346 +
86347 + @Cautions Allowed only following FM_PORT_Init().
86348 + If rate limit is set on a port that need to send PFC frames,
86349 + it might violate the stop transmit timing.
86350 +*//***************************************************************************/
86351 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
86352 +
86353 +/**************************************************************************//**
86354 + @Function FM_PORT_DeleteRateLimit
86355 +
86356 + @Description Calling this routine disables and clears rate limit
86357 + initialization.
86358 +
86359 + May be used for Tx and OP ports only
86360 +
86361 + @Param[in] h_FmPort A handle to a FM Port module.
86362 +
86363 + @Return E_OK on success; Error code otherwise.
86364 +
86365 + @Cautions Allowed only following FM_PORT_Init().
86366 +*//***************************************************************************/
86367 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86368 +
86369 +/**************************************************************************//**
86370 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86371 +
86372 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86373 + This WQ will be blocked upon receiving a PFC frame with this priority.
86374 +
86375 + May be used for Tx ports only.
86376 +
86377 + @Param[in] h_FmPort A handle to a FM Port module.
86378 + @Param[in] prio PFC priority (0-7).
86379 + @Param[in] wq Work Queue (0-7).
86380 +
86381 + @Return E_OK on success; Error code otherwise.
86382 +
86383 + @Cautions Allowed only following FM_PORT_Init().
86384 +*//***************************************************************************/
86385 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86386 +
86387 +/**************************************************************************//**
86388 + @Function FM_PORT_SetStatisticsCounters
86389 +
86390 + @Description Calling this routine enables/disables port's statistics counters.
86391 + By default, counters are enabled.
86392 +
86393 + May be used for all port types
86394 +
86395 + @Param[in] h_FmPort A handle to a FM Port module.
86396 + @Param[in] enable TRUE to enable, FALSE to disable.
86397 +
86398 + @Return E_OK on success; Error code otherwise.
86399 +
86400 + @Cautions Allowed only following FM_PORT_Init().
86401 +*//***************************************************************************/
86402 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86403 +
86404 +/**************************************************************************//**
86405 + @Function FM_PORT_SetFrameQueueCounters
86406 +
86407 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86408 + By default, counters are enabled.
86409 +
86410 + May be used for all ports
86411 +
86412 + @Param[in] h_FmPort A handle to a FM Port module.
86413 + @Param[in] enable TRUE to enable, FALSE to disable.
86414 +
86415 + @Return E_OK on success; Error code otherwise.
86416 +
86417 + @Cautions Allowed only following FM_PORT_Init().
86418 +*//***************************************************************************/
86419 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86420 +
86421 +/**************************************************************************//**
86422 + @Function FM_PORT_AnalyzePerformanceParams
86423 +
86424 + @Description User may call this routine to so the driver will analyze if the
86425 + basic performance parameters are correct and also the driver may
86426 + suggest of improvements; The basic parameters are FIFO sizes, number
86427 + of DMAs and number of TNUMs for the port.
86428 +
86429 + May be used for all port types
86430 +
86431 + @Param[in] h_FmPort A handle to a FM Port module.
86432 +
86433 + @Return E_OK on success; Error code otherwise.
86434 +
86435 + @Cautions Allowed only following FM_PORT_Init().
86436 +*//***************************************************************************/
86437 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86438 +
86439 +
86440 +/**************************************************************************//**
86441 + @Function FM_PORT_SetAllocBufCounter
86442 +
86443 + @Description Calling this routine enables/disables BM pool allocate
86444 + buffer counters.
86445 + By default, counters are enabled.
86446 +
86447 + May be used for Rx ports only
86448 +
86449 + @Param[in] h_FmPort A handle to a FM Port module.
86450 + @Param[in] poolId BM pool id.
86451 + @Param[in] enable TRUE to enable, FALSE to disable.
86452 +
86453 + @Return E_OK on success; Error code otherwise.
86454 +
86455 + @Cautions Allowed only following FM_PORT_Init().
86456 +*//***************************************************************************/
86457 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86458 +
86459 +/**************************************************************************//**
86460 + @Function FM_PORT_GetBmiCounters
86461 +
86462 + @Description Read port's BMI stat counters and place them into
86463 + a designated structure of counters.
86464 +
86465 + @Param[in] h_FmPort A handle to a FM Port module.
86466 + @Param[out] p_BmiStats counters structure
86467 +
86468 + @Return E_OK on success; Error code otherwise.
86469 +
86470 + @Cautions Allowed only following FM_PORT_Init().
86471 +*//***************************************************************************/
86472 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86473 +
86474 +/**************************************************************************//**
86475 + @Function FM_PORT_GetCounter
86476 +
86477 + @Description Reads one of the FM PORT counters.
86478 +
86479 + @Param[in] h_FmPort A handle to a FM Port module.
86480 + @Param[in] fmPortCounter The requested counter.
86481 +
86482 + @Return Counter's current value.
86483 +
86484 + @Cautions Allowed only following FM_PORT_Init().
86485 + Note that it is user's responsibility to call this routine only
86486 + for enabled counters, and there will be no indication if a
86487 + disabled counter is accessed.
86488 +*//***************************************************************************/
86489 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86490 +
86491 +/**************************************************************************//**
86492 + @Function FM_PORT_ModifyCounter
86493 +
86494 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86495 +
86496 + @Param[in] h_FmPort A handle to a FM Port module.
86497 + @Param[in] fmPortCounter The requested counter.
86498 + @Param[in] value The requested value to be written into the counter.
86499 +
86500 + @Return E_OK on success; Error code otherwise.
86501 +
86502 + @Cautions Allowed only following FM_PORT_Init().
86503 +*//***************************************************************************/
86504 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86505 +
86506 +/**************************************************************************//**
86507 + @Function FM_PORT_GetAllocBufCounter
86508 +
86509 + @Description Reads one of the FM PORT buffer counters.
86510 +
86511 + @Param[in] h_FmPort A handle to a FM Port module.
86512 + @Param[in] poolId The requested pool.
86513 +
86514 + @Return Counter's current value.
86515 +
86516 + @Cautions Allowed only following FM_PORT_Init().
86517 + Note that it is user's responsibility to call this routine only
86518 + for enabled counters, and there will be no indication if a
86519 + disabled counter is accessed.
86520 +*//***************************************************************************/
86521 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86522 +
86523 +/**************************************************************************//**
86524 + @Function FM_PORT_ModifyAllocBufCounter
86525 +
86526 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86527 +
86528 + @Param[in] h_FmPort A handle to a FM Port module.
86529 + @Param[in] poolId The requested pool.
86530 + @Param[in] value The requested value to be written into the counter.
86531 +
86532 + @Return E_OK on success; Error code otherwise.
86533 +
86534 + @Cautions Allowed only following FM_PORT_Init().
86535 +*//***************************************************************************/
86536 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86537 +
86538 +/**************************************************************************//**
86539 + @Function FM_PORT_AddCongestionGrps
86540 +
86541 + @Description This routine effects the corresponding Tx port.
86542 + It should be called in order to enable pause
86543 + frame transmission in case of congestion in one or more
86544 + of the congestion groups relevant to this port.
86545 + Each call to this routine may add one or more congestion
86546 + groups to be considered relevant to this port.
86547 +
86548 + May be used for Rx, or RX+OP ports only (depending on chip)
86549 +
86550 + @Param[in] h_FmPort A handle to a FM Port module.
86551 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86552 + id's to consider.
86553 +
86554 + @Return E_OK on success; Error code otherwise.
86555 +
86556 + @Cautions Allowed only following FM_PORT_Init().
86557 +*//***************************************************************************/
86558 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86559 +
86560 +/**************************************************************************//**
86561 + @Function FM_PORT_RemoveCongestionGrps
86562 +
86563 + @Description This routine effects the corresponding Tx port. It should be
86564 + called when congestion groups were
86565 + defined for this port and are no longer relevant, or pause
86566 + frames transmitting is not required on their behalf.
86567 + Each call to this routine may remove one or more congestion
86568 + groups to be considered relevant to this port.
86569 +
86570 + May be used for Rx, or RX+OP ports only (depending on chip)
86571 +
86572 + @Param[in] h_FmPort A handle to a FM Port module.
86573 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86574 + id's to consider.
86575 +
86576 + @Return E_OK on success; Error code otherwise.
86577 +
86578 + @Cautions Allowed only following FM_PORT_Init().
86579 +*//***************************************************************************/
86580 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86581 +
86582 +/**************************************************************************//**
86583 + @Function FM_PORT_IsStalled
86584 +
86585 + @Description A routine for checking whether the specified port is stalled.
86586 +
86587 + @Param[in] h_FmPort A handle to a FM Port module.
86588 +
86589 + @Return TRUE if port is stalled, FALSE otherwize
86590 +
86591 + @Cautions Allowed only following FM_PORT_Init().
86592 +*//***************************************************************************/
86593 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86594 +
86595 +/**************************************************************************//**
86596 + @Function FM_PORT_ReleaseStalled
86597 +
86598 + @Description This routine may be called in case the port was stalled and may
86599 + now be released.
86600 + Note that this routine is available only on older FMan revisions
86601 + (FMan v2, DPAA v1.0 only).
86602 +
86603 + @Param[in] h_FmPort A handle to a FM Port module.
86604 +
86605 + @Return E_OK on success; Error code otherwise.
86606 +
86607 + @Cautions Allowed only following FM_PORT_Init().
86608 +*//***************************************************************************/
86609 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86610 +
86611 +/**************************************************************************//**
86612 + @Function FM_PORT_SetRxL4ChecksumVerify
86613 +
86614 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86615 + set/clear the L3/L4 checksum verification (on RX side).
86616 + Note that this takes affect only if hw-parser is enabled!
86617 +
86618 + @Param[in] h_FmPort A handle to a FM Port module.
86619 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86620 + on frames or not.
86621 +
86622 + @Return E_OK on success; Error code otherwise.
86623 +
86624 + @Cautions Allowed only following FM_PORT_Init().
86625 +*//***************************************************************************/
86626 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86627 +
86628 +/**************************************************************************//**
86629 + @Function FM_PORT_SetErrorsRoute
86630 +
86631 + @Description Errors selected for this routine will cause a frame with that error
86632 + to be enqueued to error queue.
86633 + Errors not selected for this routine will cause a frame with that error
86634 + to be enqueued to the one of the other port queues.
86635 + By default all errors are defined to be enqueued to error queue.
86636 + Errors that were configured to be discarded (at initialization)
86637 + may not be selected here.
86638 +
86639 + May be used for Rx and OP ports only
86640 +
86641 + @Param[in] h_FmPort A handle to a FM Port module.
86642 + @Param[in] errs A list of errors to enqueue to error queue
86643 +
86644 + @Return E_OK on success; Error code otherwise.
86645 +
86646 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86647 +*//***************************************************************************/
86648 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86649 +
86650 +/**************************************************************************//**
86651 + @Function FM_PORT_SetIMExceptions
86652 +
86653 + @Description Calling this routine enables/disables FM PORT interrupts.
86654 +
86655 + @Param[in] h_FmPort FM PORT module descriptor.
86656 + @Param[in] exception The exception to be selected.
86657 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86658 +
86659 + @Return E_OK on success; Error code otherwise.
86660 +
86661 + @Cautions Allowed only following FM_PORT_Init().
86662 + This routine should NOT be called from guest-partition
86663 + (i.e. guestId != NCSW_MASTER_ID)
86664 +*//***************************************************************************/
86665 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86666 +
86667 +/**************************************************************************//*
86668 + @Function FM_PORT_SetPerformanceCounters
86669 +
86670 + @Description Calling this routine enables/disables port's performance counters.
86671 + By default, counters are enabled.
86672 +
86673 + May be used for all port types
86674 +
86675 + @Param[in] h_FmPort A handle to a FM Port module.
86676 + @Param[in] enable TRUE to enable, FALSE to disable.
86677 +
86678 + @Return E_OK on success; Error code otherwise.
86679 +
86680 + @Cautions Allowed only following FM_PORT_Init().
86681 +*//***************************************************************************/
86682 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86683 +
86684 +/**************************************************************************//*
86685 + @Function FM_PORT_SetPerformanceCountersParams
86686 +
86687 + @Description Calling this routine defines port's performance
86688 + counters parameters.
86689 +
86690 + May be used for all port types
86691 +
86692 + @Param[in] h_FmPort A handle to a FM Port module.
86693 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86694 + counters parameters.
86695 +
86696 + @Return E_OK on success; Error code otherwise.
86697 +
86698 + @Cautions Allowed only following FM_PORT_Init().
86699 +*//***************************************************************************/
86700 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86701 +
86702 +/**************************************************************************//**
86703 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86704 +
86705 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86706 +
86707 + @{
86708 +*//***************************************************************************/
86709 +
86710 +/**************************************************************************//**
86711 + @Description A structure defining the KG scheme after the parser.
86712 + This is relevant only to change scheme selection mode - from
86713 + direct to indirect and vice versa, or when the scheme is selected directly,
86714 + to select the scheme id.
86715 +
86716 +*//***************************************************************************/
86717 +typedef struct t_FmPcdKgSchemeSelect {
86718 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86719 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86720 + Relevant only when 'direct' is TRUE. */
86721 +} t_FmPcdKgSchemeSelect;
86722 +
86723 +/**************************************************************************//**
86724 + @Description A structure of scheme parameters
86725 +*//***************************************************************************/
86726 +typedef struct t_FmPcdPortSchemesParams {
86727 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86728 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86729 + port to be bound to */
86730 +} t_FmPcdPortSchemesParams;
86731 +
86732 +/**************************************************************************//**
86733 + @Description Union for defining port protocol parameters for parser
86734 +*//***************************************************************************/
86735 +typedef union u_FmPcdHdrPrsOpts {
86736 + /* MPLS */
86737 + struct {
86738 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86739 + interpreted as described in HW spec table. When the bit
86740 + is cleared, the parser will advance to MPLS next parse */
86741 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86742 + } mplsPrsOptions;
86743 + /* VLAN */
86744 + struct {
86745 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86746 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86747 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86748 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86749 + } vlanPrsOptions;
86750 + /* PPP */
86751 + struct{
86752 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86753 + } pppoePrsOptions;
86754 +
86755 + /* IPV6 */
86756 + struct{
86757 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86758 + } ipv6PrsOptions;
86759 +
86760 + /* UDP */
86761 + struct{
86762 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86763 + } udpPrsOptions;
86764 +
86765 + /* TCP */
86766 + struct {
86767 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86768 + } tcpPrsOptions;
86769 +} u_FmPcdHdrPrsOpts;
86770 +
86771 +/**************************************************************************//**
86772 + @Description A structure for defining each header for the parser
86773 +*//***************************************************************************/
86774 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86775 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86776 + to indicate that sw parser is to run first
86777 + (before HW parser, and independent of the
86778 + existence of any protocol), in this case,
86779 + swPrsEnable must be set, and all other
86780 + parameters are irrelevant. */
86781 + bool errDisable; /**< TRUE to disable error indication */
86782 + bool swPrsEnable; /**< Enable jump to SW parser when this
86783 + header is recognized by the HW parser. */
86784 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86785 + attachments exists for the same header,
86786 + (in the main sw parser code) use this
86787 + index to distinguish between them. */
86788 + bool usePrsOpts; /**< TRUE to use parser options. */
86789 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86790 + defining the parser options selected.*/
86791 +} t_FmPcdPrsAdditionalHdrParams;
86792 +
86793 +/**************************************************************************//**
86794 + @Description struct for defining port PCD parameters
86795 +*//***************************************************************************/
86796 +typedef struct t_FmPortPcdPrsParams {
86797 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86798 + port information into the parser result. This information
86799 + may be extracted by Keygen and be used for frames
86800 + distribution when a per-port distinction is required,
86801 + it may also be used as a port logical id for analyzing
86802 + incoming frames. */
86803 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86804 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86805 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86806 + NOTE: this field is not valid when the FM is in "guest" mode
86807 + and IPC is not available. */
86808 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86809 + special parameters */
86810 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86811 + /**< 'numOfHdrsWithAdditionalParams' structures
86812 + of additional parameters
86813 + for each header that requires them */
86814 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86815 + indicate a VLAN tag (in addition to the TPID values
86816 + 0x8100 and 0x88A8). */
86817 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86818 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86819 + indicate a VLAN tag (in addition to the TPID values
86820 + 0x8100 and 0x88A8). */
86821 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86822 +} t_FmPortPcdPrsParams;
86823 +
86824 +/**************************************************************************//**
86825 + @Description struct for defining coarse alassification parameters
86826 +*//***************************************************************************/
86827 +typedef struct t_FmPortPcdCcParams {
86828 + t_Handle h_CcTree; /**< A handle to a CC tree */
86829 +} t_FmPortPcdCcParams;
86830 +
86831 +/**************************************************************************//**
86832 + @Description struct for defining keygen parameters
86833 +*//***************************************************************************/
86834 +typedef struct t_FmPortPcdKgParams {
86835 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86836 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86837 + /**< Array of 'numOfSchemes' schemes handles for the
86838 + port to be bound to */
86839 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86840 + regardless of parser result */
86841 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86842 + as returned by FM_PCD_KgSetScheme */
86843 +} t_FmPortPcdKgParams;
86844 +
86845 +/**************************************************************************//**
86846 + @Description struct for defining policer parameters
86847 +*//***************************************************************************/
86848 +typedef struct t_FmPortPcdPlcrParams {
86849 + t_Handle h_Profile; /**< Selected profile handle */
86850 +} t_FmPortPcdPlcrParams;
86851 +
86852 +/**************************************************************************//**
86853 + @Description struct for defining port PCD parameters
86854 +*//***************************************************************************/
86855 +typedef struct t_FmPortPcdParams {
86856 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
86857 + Describes the active PCD engines for this port. */
86858 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
86859 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
86860 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
86861 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
86862 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
86863 + following cases:
86864 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
86865 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
86866 + or if any flow uses a KG scheme were policer
86867 + profile is not generated
86868 + ('bypassPlcrProfileGeneration selected'). */
86869 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
86870 +#if (DPAA_VERSION >= 11)
86871 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
86872 +#endif /* (DPAA_VERSION >= 11) */
86873 +} t_FmPortPcdParams;
86874 +
86875 +/**************************************************************************//**
86876 + @Description A structure for defining the Parser starting point
86877 +*//***************************************************************************/
86878 +typedef struct t_FmPcdPrsStart {
86879 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
86880 + start parsing */
86881 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
86882 + 'parsingOffset' */
86883 +} t_FmPcdPrsStart;
86884 +
86885 +#if (DPAA_VERSION >= 11)
86886 +/**************************************************************************//**
86887 + @Description struct for defining external buffer margins
86888 +*//***************************************************************************/
86889 +typedef struct t_FmPortVSPAllocParams {
86890 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
86891 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
86892 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
86893 + if relevant function called for Rx port */
86894 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
86895 +} t_FmPortVSPAllocParams;
86896 +#endif /* (DPAA_VERSION >= 11) */
86897 +
86898 +
86899 +/**************************************************************************//**
86900 + @Function FM_PORT_SetPCD
86901 +
86902 + @Description Calling this routine defines the port's PCD configuration.
86903 + It changes it from its default configuration which is PCD
86904 + disabled (BMI to BMI) and configures it according to the passed
86905 + parameters.
86906 +
86907 + May be used for Rx and OP ports only
86908 +
86909 + @Param[in] h_FmPort A handle to a FM Port module.
86910 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
86911 + configuration.
86912 +
86913 + @Return E_OK on success; Error code otherwise.
86914 +
86915 + @Cautions Allowed only following FM_PORT_Init().
86916 +*//***************************************************************************/
86917 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
86918 +
86919 +/**************************************************************************//**
86920 + @Function FM_PORT_DeletePCD
86921 +
86922 + @Description Calling this routine releases the port's PCD configuration.
86923 + The port returns to its default configuration which is PCD
86924 + disabled (BMI to BMI) and all PCD configuration is removed.
86925 +
86926 + May be used for Rx and OP ports which are
86927 + in PCD mode only
86928 +
86929 + @Param[in] h_FmPort A handle to a FM Port module.
86930 +
86931 + @Return E_OK on success; Error code otherwise.
86932 +
86933 + @Cautions Allowed only following FM_PORT_Init().
86934 +*//***************************************************************************/
86935 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
86936 +
86937 +/**************************************************************************//**
86938 + @Function FM_PORT_AttachPCD
86939 +
86940 + @Description This routine may be called after FM_PORT_DetachPCD was called,
86941 + to return to the originally configured PCD support flow.
86942 + The couple of routines are used to allow PCD configuration changes
86943 + that demand that PCD will not be used while changes take place.
86944 +
86945 + May be used for Rx and OP ports which are
86946 + in PCD mode only
86947 +
86948 + @Param[in] h_FmPort A handle to a FM Port module.
86949 +
86950 + @Return E_OK on success; Error code otherwise.
86951 +
86952 + @Cautions Allowed only following FM_PORT_Init().
86953 +*//***************************************************************************/
86954 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
86955 +
86956 +/**************************************************************************//**
86957 + @Function FM_PORT_DetachPCD
86958 +
86959 + @Description Calling this routine detaches the port from its PCD functionality.
86960 + The port returns to its default flow which is BMI to BMI.
86961 +
86962 + May be used for Rx and OP ports which are
86963 + in PCD mode only
86964 +
86965 + @Param[in] h_FmPort A handle to a FM Port module.
86966 +
86967 + @Return E_OK on success; Error code otherwise.
86968 +
86969 + @Cautions Allowed only following FM_PORT_AttachPCD().
86970 +*//***************************************************************************/
86971 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
86972 +
86973 +/**************************************************************************//**
86974 + @Function FM_PORT_PcdPlcrAllocProfiles
86975 +
86976 + @Description This routine may be called only for ports that use the Policer in
86977 + order to allocate private policer profiles.
86978 +
86979 + @Param[in] h_FmPort A handle to a FM Port module.
86980 + @Param[in] numOfProfiles The number of required policer profiles
86981 +
86982 + @Return E_OK on success; Error code otherwise.
86983 +
86984 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86985 + and before FM_PORT_SetPCD().
86986 +*//***************************************************************************/
86987 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
86988 +
86989 +/**************************************************************************//**
86990 + @Function FM_PORT_PcdPlcrFreeProfiles
86991 +
86992 + @Description This routine should be called for freeing private policer profiles.
86993 +
86994 + @Param[in] h_FmPort A handle to a FM Port module.
86995 +
86996 + @Return E_OK on success; Error code otherwise.
86997 +
86998 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86999 + and before FM_PORT_SetPCD().
87000 +*//***************************************************************************/
87001 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
87002 +
87003 +#if (DPAA_VERSION >= 11)
87004 +/**************************************************************************//**
87005 + @Function FM_PORT_VSPAlloc
87006 +
87007 + @Description This routine allocated VSPs per port and forces the port to work
87008 + in VSP mode. Note that the port is initialized by default with the
87009 + physical-storage-profile only.
87010 +
87011 + @Param[in] h_FmPort A handle to a FM Port module.
87012 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
87013 +
87014 + @Return E_OK on success; Error code otherwise.
87015 +
87016 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
87017 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
87018 +*//***************************************************************************/
87019 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
87020 +#endif /* (DPAA_VERSION >= 11) */
87021 +
87022 +/**************************************************************************//**
87023 + @Function FM_PORT_PcdKgModifyInitialScheme
87024 +
87025 + @Description This routine may be called only for ports that use the keygen in
87026 + order to change the initial scheme frame should be routed to.
87027 + The change may be of a scheme id (in case of direct mode),
87028 + from direct to indirect, or from indirect to direct - specifying the scheme id.
87029 +
87030 + @Param[in] h_FmPort A handle to a FM Port module.
87031 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
87032 + a scheme is direct/indirect, and if direct - scheme id.
87033 +
87034 + @Return E_OK on success; Error code otherwise.
87035 +
87036 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87037 +*//***************************************************************************/
87038 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
87039 +
87040 +/**************************************************************************//**
87041 + @Function FM_PORT_PcdPlcrModifyInitialProfile
87042 +
87043 + @Description This routine may be called for ports with flows
87044 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
87045 + only, to change the initial Policer profile frame should be
87046 + routed to. The change may be of a profile and/or absolute/direct
87047 + mode selection.
87048 +
87049 + @Param[in] h_FmPort A handle to a FM Port module.
87050 + @Param[in] h_Profile Policer profile handle
87051 +
87052 + @Return E_OK on success; Error code otherwise.
87053 +
87054 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87055 +*//***************************************************************************/
87056 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
87057 +
87058 +/**************************************************************************//**
87059 + @Function FM_PORT_PcdCcModifyTree
87060 +
87061 + @Description This routine may be called for ports that use coarse classification tree
87062 + if the user wishes to replace the tree. The routine may not be called while port
87063 + receives packets using the PCD functionalities, therefor port must be first detached
87064 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
87065 +
87066 + @Param[in] h_FmPort A handle to a FM Port module.
87067 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
87068 + the BuildTree routine.
87069 +
87070 + @Return E_OK on success; Error code otherwise.
87071 +
87072 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
87073 +*//***************************************************************************/
87074 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
87075 +
87076 +/**************************************************************************//**
87077 + @Function FM_PORT_PcdKgBindSchemes
87078 +
87079 + @Description These routines may be called for adding more schemes for the
87080 + port to be bound to. The selected schemes are not added,
87081 + just this specific port starts using them.
87082 +
87083 + @Param[in] h_FmPort A handle to a FM Port module.
87084 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87085 +
87086 + @Return E_OK on success; Error code otherwise.
87087 +
87088 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87089 +*//***************************************************************************/
87090 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87091 +
87092 +/**************************************************************************//**
87093 + @Function FM_PORT_PcdKgUnbindSchemes
87094 +
87095 + @Description These routines may be called for adding more schemes for the
87096 + port to be bound to. The selected schemes are not removed or invalidated,
87097 + just this specific port stops using them.
87098 +
87099 + @Param[in] h_FmPort A handle to a FM Port module.
87100 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87101 +
87102 + @Return E_OK on success; Error code otherwise.
87103 +
87104 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87105 +*//***************************************************************************/
87106 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87107 +
87108 +/**************************************************************************//**
87109 + @Function FM_PORT_GetIPv4OptionsCount
87110 +
87111 + @Description TODO
87112 +
87113 + @Param[in] h_FmPort A handle to a FM Port module.
87114 + @Param[out] p_Ipv4OptionsCount will hold the counter value
87115 +
87116 + @Return E_OK on success; Error code otherwise.
87117 +
87118 + @Cautions Allowed only following FM_PORT_Init()
87119 +*//***************************************************************************/
87120 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
87121 +
87122 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
87123 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
87124 +
87125 +
87126 +/**************************************************************************//**
87127 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
87128 +
87129 + @Description FM Port Runtime data unit API functions, definitions and enums.
87130 + This API is valid only if working in Independent-Mode.
87131 +
87132 + @{
87133 +*//***************************************************************************/
87134 +
87135 +/**************************************************************************//**
87136 + @Function FM_PORT_ImTx
87137 +
87138 + @Description Tx function, called to transmit a data buffer on the port.
87139 +
87140 + @Param[in] h_FmPort A handle to a FM Port module.
87141 + @Param[in] p_Data A pointer to an LCP data buffer.
87142 + @Param[in] length Size of data for transmission.
87143 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
87144 + of a frame, including a single buffer frame
87145 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
87146 +
87147 + @Return E_OK on success; Error code otherwise.
87148 +
87149 + @Cautions Allowed only following FM_PORT_Init().
87150 + NOTE - This routine can be used only when working in
87151 + Independent-Mode mode.
87152 +*//***************************************************************************/
87153 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
87154 + uint8_t *p_Data,
87155 + uint16_t length,
87156 + bool lastBuffer,
87157 + t_Handle h_BufContext);
87158 +
87159 +/**************************************************************************//**
87160 + @Function FM_PORT_ImTxConf
87161 +
87162 + @Description Tx port confirmation routine, optional, may be called to verify
87163 + transmission of all frames. The procedure performed by this
87164 + routine will be performed automatically on next buffer transmission,
87165 + but if desired, calling this routine will invoke this action on
87166 + demand.
87167 +
87168 + @Param[in] h_FmPort A handle to a FM Port module.
87169 +
87170 + @Cautions Allowed only following FM_PORT_Init().
87171 + NOTE - This routine can be used only when working in
87172 + Independent-Mode mode.
87173 +*//***************************************************************************/
87174 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
87175 +
87176 +/**************************************************************************//**
87177 + @Function FM_PORT_ImRx
87178 +
87179 + @Description Rx function, may be called to poll for received buffers.
87180 + Normally, Rx process is invoked by the driver on Rx interrupt.
87181 + Alternatively, this routine may be called on demand.
87182 +
87183 + @Param[in] h_FmPort A handle to a FM Port module.
87184 +
87185 + @Return E_OK on success; Error code otherwise.
87186 +
87187 + @Cautions Allowed only following FM_PORT_Init().
87188 + NOTE - This routine can be used only when working in
87189 + Independent-Mode mode.
87190 +*//***************************************************************************/
87191 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
87192 +
87193 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
87194 +/** @} */ /* end of FM_PORT_grp group */
87195 +/** @} */ /* end of FM_grp group */
87196 +
87197 +
87198 +
87199 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
87200 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
87201 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
87202 +
87203 +
87204 +#endif /* __FM_PORT_EXT */
87205 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87206 new file mode 100644
87207 index 00000000..72078ac4
87208 --- /dev/null
87209 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87210 @@ -0,0 +1,619 @@
87211 +/*
87212 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87213 + *
87214 + * Redistribution and use in source and binary forms, with or without
87215 + * modification, are permitted provided that the following conditions are met:
87216 + * * Redistributions of source code must retain the above copyright
87217 + * notice, this list of conditions and the following disclaimer.
87218 + * * Redistributions in binary form must reproduce the above copyright
87219 + * notice, this list of conditions and the following disclaimer in the
87220 + * documentation and/or other materials provided with the distribution.
87221 + * * Neither the name of Freescale Semiconductor nor the
87222 + * names of its contributors may be used to endorse or promote products
87223 + * derived from this software without specific prior written permission.
87224 + *
87225 + *
87226 + * ALTERNATIVELY, this software may be distributed under the terms of the
87227 + * GNU General Public License ("GPL") as published by the Free Software
87228 + * Foundation, either version 2 of that License or (at your option) any
87229 + * later version.
87230 + *
87231 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87232 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87233 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87234 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87235 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87236 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87237 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87238 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87239 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87240 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87241 + */
87242 +
87243 +
87244 +/**************************************************************************//**
87245 + @File fm_rtc_ext.h
87246 +
87247 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
87248 +
87249 + @Cautions None.
87250 +*//***************************************************************************/
87251 +
87252 +#ifndef __FM_RTC_EXT_H__
87253 +#define __FM_RTC_EXT_H__
87254 +
87255 +
87256 +#include "error_ext.h"
87257 +#include "std_ext.h"
87258 +#include "fsl_fman_rtc.h"
87259 +
87260 +/**************************************************************************//**
87261 +
87262 + @Group FM_grp Frame Manager API
87263 +
87264 + @Description FM API functions, definitions and enums
87265 +
87266 + @{
87267 +*//***************************************************************************/
87268 +
87269 +/**************************************************************************//**
87270 + @Group fm_rtc_grp FM RTC
87271 +
87272 + @Description FM RTC functions, definitions and enums.
87273 +
87274 + @{
87275 +*//***************************************************************************/
87276 +
87277 +/**************************************************************************//**
87278 + @Group fm_rtc_init_grp FM RTC Initialization Unit
87279 +
87280 + @Description FM RTC initialization API.
87281 +
87282 + @{
87283 +*//***************************************************************************/
87284 +
87285 +/**************************************************************************//**
87286 + @Description FM RTC Alarm Polarity Options.
87287 +*//***************************************************************************/
87288 +typedef enum e_FmRtcAlarmPolarity
87289 +{
87290 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
87291 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
87292 +} e_FmRtcAlarmPolarity;
87293 +
87294 +/**************************************************************************//**
87295 + @Description FM RTC Trigger Polarity Options.
87296 +*//***************************************************************************/
87297 +typedef enum e_FmRtcTriggerPolarity
87298 +{
87299 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
87300 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
87301 +} e_FmRtcTriggerPolarity;
87302 +
87303 +/**************************************************************************//**
87304 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
87305 +*//***************************************************************************/
87306 +typedef enum e_FmSrcClock
87307 +{
87308 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
87309 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
87310 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
87311 +}e_FmSrcClk;
87312 +
87313 +/**************************************************************************//**
87314 + @Description FM RTC configuration parameters structure.
87315 +
87316 + This structure should be passed to FM_RTC_Config().
87317 +*//***************************************************************************/
87318 +typedef struct t_FmRtcParams
87319 +{
87320 + t_Handle h_Fm; /**< FM Handle*/
87321 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
87322 + t_Handle h_App; /**< A handle to an application layer object; This handle will
87323 + be passed by the driver upon calling the above callbacks */
87324 +} t_FmRtcParams;
87325 +
87326 +
87327 +/**************************************************************************//**
87328 + @Function FM_RTC_Config
87329 +
87330 + @Description Configures the FM RTC module according to user's parameters.
87331 +
87332 + The driver assigns default values to some FM RTC parameters.
87333 + These parameters can be overwritten using the advanced
87334 + configuration routines.
87335 +
87336 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
87337 +
87338 + @Return Handle to the new FM RTC object; NULL pointer on failure.
87339 +
87340 + @Cautions None
87341 +*//***************************************************************************/
87342 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
87343 +
87344 +/**************************************************************************//**
87345 + @Function FM_RTC_Init
87346 +
87347 + @Description Initializes the FM RTC driver and hardware.
87348 +
87349 + @Param[in] h_FmRtc - Handle to FM RTC object.
87350 +
87351 + @Return E_OK on success; Error code otherwise.
87352 +
87353 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87354 +*//***************************************************************************/
87355 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
87356 +
87357 +/**************************************************************************//**
87358 + @Function FM_RTC_Free
87359 +
87360 + @Description Frees the FM RTC object and all allocated resources.
87361 +
87362 + @Param[in] h_FmRtc - Handle to FM RTC object.
87363 +
87364 + @Return E_OK on success; Error code otherwise.
87365 +
87366 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87367 +*//***************************************************************************/
87368 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
87369 +
87370 +
87371 +/**************************************************************************//**
87372 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87373 +
87374 + @Description FM RTC advanced configuration functions.
87375 +
87376 + @{
87377 +*//***************************************************************************/
87378 +
87379 +/**************************************************************************//**
87380 + @Function FM_RTC_ConfigPeriod
87381 +
87382 + @Description Configures the period of the timestamp if different than
87383 + default [DEFAULT_clockPeriod].
87384 +
87385 + @Param[in] h_FmRtc - Handle to FM RTC object.
87386 + @Param[in] period - Period in nano-seconds.
87387 +
87388 + @Return E_OK on success; Error code otherwise.
87389 +
87390 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87391 +*//***************************************************************************/
87392 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87393 +
87394 +/**************************************************************************//**
87395 + @Function FM_RTC_ConfigSourceClock
87396 +
87397 + @Description Configures the source clock of the RTC.
87398 +
87399 + @Param[in] h_FmRtc - Handle to FM RTC object.
87400 + @Param[in] srcClk - Source clock selection.
87401 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87402 +
87403 + @Return E_OK on success; Error code otherwise.
87404 +
87405 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87406 +*//***************************************************************************/
87407 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87408 + e_FmSrcClk srcClk,
87409 + uint32_t freqInMhz);
87410 +
87411 +/**************************************************************************//**
87412 + @Function FM_RTC_ConfigPulseRealignment
87413 +
87414 + @Description Configures the RTC to automatic FIPER pulse realignment in
87415 + response to timer adjustments [DEFAULT_pulseRealign]
87416 +
87417 + In this mode, the RTC clock is identical to the source clock.
87418 + This feature can be useful when the system contains an external
87419 + RTC with inherent frequency compensation.
87420 +
87421 + @Param[in] h_FmRtc - Handle to FM RTC object.
87422 + @Param[in] enable - TRUE to enable automatic realignment.
87423 +
87424 + @Return E_OK on success; Error code otherwise.
87425 +
87426 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87427 +*//***************************************************************************/
87428 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87429 +
87430 +/**************************************************************************//**
87431 + @Function FM_RTC_ConfigFrequencyBypass
87432 +
87433 + @Description Configures the RTC to bypass the frequency compensation
87434 + mechanism. [DEFAULT_bypass]
87435 +
87436 + In this mode, the RTC clock is identical to the source clock.
87437 + This feature can be useful when the system contains an external
87438 + RTC with inherent frequency compensation.
87439 +
87440 + @Param[in] h_FmRtc - Handle to FM RTC object.
87441 + @Param[in] enabled - TRUE to bypass frequency compensation;
87442 + FALSE otherwise.
87443 +
87444 + @Return E_OK on success; Error code otherwise.
87445 +
87446 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87447 +*//***************************************************************************/
87448 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87449 +
87450 +/**************************************************************************//**
87451 + @Function FM_RTC_ConfigInvertedInputClockPhase
87452 +
87453 + @Description Configures the RTC to invert the source clock phase on input.
87454 + [DEFAULT_invertInputClkPhase]
87455 +
87456 + @Param[in] h_FmRtc - Handle to FM RTC object.
87457 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87458 + FALSE otherwise.
87459 +
87460 + @Return E_OK on success; Error code otherwise.
87461 +
87462 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87463 +*//***************************************************************************/
87464 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87465 +
87466 +/**************************************************************************//**
87467 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87468 +
87469 + @Description Configures the RTC to invert the output clock phase.
87470 + [DEFAULT_invertOutputClkPhase]
87471 +
87472 + @Param[in] h_FmRtc - Handle to FM RTC object.
87473 + @Param[in] inverted - TRUE to invert the output clock phase.
87474 + FALSE otherwise.
87475 +
87476 + @Return E_OK on success; Error code otherwise.
87477 +
87478 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87479 +*//***************************************************************************/
87480 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87481 +
87482 +/**************************************************************************//**
87483 + @Function FM_RTC_ConfigOutputClockDivisor
87484 +
87485 + @Description Configures the divisor for generating the output clock from
87486 + the RTC clock. [DEFAULT_outputClockDivisor]
87487 +
87488 + @Param[in] h_FmRtc - Handle to FM RTC object.
87489 + @Param[in] divisor - Divisor for generation of the output clock.
87490 +
87491 + @Return E_OK on success; Error code otherwise.
87492 +
87493 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87494 +*//***************************************************************************/
87495 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87496 +
87497 +/**************************************************************************//**
87498 + @Function FM_RTC_ConfigAlarmPolarity
87499 +
87500 + @Description Configures the polarity (active-high/active-low) of a specific
87501 + alarm signal. [DEFAULT_alarmPolarity]
87502 +
87503 + @Param[in] h_FmRtc - Handle to FM RTC object.
87504 + @Param[in] alarmId - Alarm ID.
87505 + @Param[in] alarmPolarity - Alarm polarity.
87506 +
87507 + @Return E_OK on success; Error code otherwise.
87508 +
87509 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87510 +*//***************************************************************************/
87511 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87512 + uint8_t alarmId,
87513 + e_FmRtcAlarmPolarity alarmPolarity);
87514 +
87515 +/**************************************************************************//**
87516 + @Function FM_RTC_ConfigExternalTriggerPolarity
87517 +
87518 + @Description Configures the polarity (rising/falling edge) of a specific
87519 + external trigger signal. [DEFAULT_triggerPolarity]
87520 +
87521 + @Param[in] h_FmRtc - Handle to FM RTC object.
87522 + @Param[in] triggerId - Trigger ID.
87523 + @Param[in] triggerPolarity - Trigger polarity.
87524 +
87525 + @Return E_OK on success; Error code otherwise.
87526 +
87527 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87528 +*//***************************************************************************/
87529 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87530 + uint8_t triggerId,
87531 + e_FmRtcTriggerPolarity triggerPolarity);
87532 +
87533 +/** @} */ /* end of fm_rtc_adv_config_grp */
87534 +/** @} */ /* end of fm_rtc_init_grp */
87535 +
87536 +
87537 +/**************************************************************************//**
87538 + @Group fm_rtc_control_grp FM RTC Control Unit
87539 +
87540 + @Description FM RTC runtime control API.
87541 +
87542 + @{
87543 +*//***************************************************************************/
87544 +
87545 +/**************************************************************************//**
87546 + @Function t_FmRtcExceptionsCallback
87547 +
87548 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87549 +
87550 + @Param[in] h_App - User's application descriptor.
87551 + @Param[in] id - source id.
87552 +*//***************************************************************************/
87553 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87554 +
87555 +/**************************************************************************//**
87556 + @Description FM RTC alarm parameters.
87557 +*//***************************************************************************/
87558 +typedef struct t_FmRtcAlarmParams {
87559 + uint8_t alarmId; /**< 0 or 1 */
87560 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87561 + should go off - must be a multiple of
87562 + the RTC period */
87563 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87564 + reaches alarmTime */
87565 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87566 +} t_FmRtcAlarmParams;
87567 +
87568 +/**************************************************************************//**
87569 + @Description FM RTC Periodic Pulse parameters.
87570 +*//***************************************************************************/
87571 +typedef struct t_FmRtcPeriodicPulseParams {
87572 + uint8_t periodicPulseId; /**< 0 or 1 */
87573 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87574 + a multiple of the RTC period */
87575 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87576 + periodicPulsePeriod. */
87577 +} t_FmRtcPeriodicPulseParams;
87578 +
87579 +/**************************************************************************//**
87580 + @Description FM RTC Periodic Pulse parameters.
87581 +*//***************************************************************************/
87582 +typedef struct t_FmRtcExternalTriggerParams {
87583 + uint8_t externalTriggerId; /**< 0 or 1 */
87584 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87585 + an external signal */
87586 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87587 + periodicPulsePeriod. */
87588 +} t_FmRtcExternalTriggerParams;
87589 +
87590 +
87591 +/**************************************************************************//**
87592 + @Function FM_RTC_Enable
87593 +
87594 + @Description Enable the RTC (time count is started).
87595 +
87596 + The user can select to resume the time count from previous
87597 + point, or to restart the time count.
87598 +
87599 + @Param[in] h_FmRtc - Handle to FM RTC object.
87600 + @Param[in] resetClock - Restart the time count from zero.
87601 +
87602 + @Return E_OK on success; Error code otherwise.
87603 +
87604 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87605 +*//***************************************************************************/
87606 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87607 +
87608 +/**************************************************************************//**
87609 + @Function FM_RTC_Disable
87610 +
87611 + @Description Disables the RTC (time count is stopped).
87612 +
87613 + @Param[in] h_FmRtc - Handle to FM RTC object.
87614 +
87615 + @Return E_OK on success; Error code otherwise.
87616 +
87617 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87618 +*//***************************************************************************/
87619 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87620 +
87621 +/**************************************************************************//**
87622 + @Function FM_RTC_SetClockOffset
87623 +
87624 + @Description Sets the clock offset (usually relative to another clock).
87625 +
87626 + The user can pass a negative offset value.
87627 +
87628 + @Param[in] h_FmRtc - Handle to FM RTC object.
87629 + @Param[in] offset - New clock offset (in nanoseconds).
87630 +
87631 + @Return E_OK on success; Error code otherwise.
87632 +
87633 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87634 +*//***************************************************************************/
87635 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87636 +
87637 +/**************************************************************************//**
87638 + @Function FM_RTC_SetAlarm
87639 +
87640 + @Description Schedules an alarm event to a given RTC time.
87641 +
87642 + @Param[in] h_FmRtc - Handle to FM RTC object.
87643 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87644 +
87645 + @Return E_OK on success; Error code otherwise.
87646 +
87647 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87648 + Must be called only prior to FM_RTC_Enable().
87649 +*//***************************************************************************/
87650 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87651 +
87652 +/**************************************************************************//**
87653 + @Function FM_RTC_SetPeriodicPulse
87654 +
87655 + @Description Sets a periodic pulse.
87656 +
87657 + @Param[in] h_FmRtc - Handle to FM RTC object.
87658 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87659 +
87660 + @Return E_OK on success; Error code otherwise.
87661 +
87662 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87663 + Must be called only prior to FM_RTC_Enable().
87664 +*//***************************************************************************/
87665 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87666 +
87667 +/**************************************************************************//**
87668 + @Function FM_RTC_ClearPeriodicPulse
87669 +
87670 + @Description Clears a periodic pulse.
87671 +
87672 + @Param[in] h_FmRtc - Handle to FM RTC object.
87673 + @Param[in] periodicPulseId - Periodic pulse id.
87674 +
87675 + @Return E_OK on success; Error code otherwise.
87676 +
87677 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87678 +*//***************************************************************************/
87679 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87680 +
87681 +/**************************************************************************//**
87682 + @Function FM_RTC_SetExternalTrigger
87683 +
87684 + @Description Sets an external trigger indication and define a callback
87685 + routine to be called on such event.
87686 +
87687 + @Param[in] h_FmRtc - Handle to FM RTC object.
87688 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87689 +
87690 + @Return E_OK on success; Error code otherwise.
87691 +
87692 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87693 +*//***************************************************************************/
87694 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87695 +
87696 +/**************************************************************************//**
87697 + @Function FM_RTC_ClearExternalTrigger
87698 +
87699 + @Description Clears external trigger indication.
87700 +
87701 + @Param[in] h_FmRtc - Handle to FM RTC object.
87702 + @Param[in] id - External Trigger id.
87703 +
87704 + @Return E_OK on success; Error code otherwise.
87705 +
87706 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87707 +*//***************************************************************************/
87708 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87709 +
87710 +/**************************************************************************//**
87711 + @Function FM_RTC_GetExternalTriggerTimeStamp
87712 +
87713 + @Description Reads the External Trigger TimeStamp.
87714 +
87715 + @Param[in] h_FmRtc - Handle to FM RTC object.
87716 + @Param[in] triggerId - External Trigger id.
87717 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87718 +
87719 + @Return E_OK on success; Error code otherwise.
87720 +
87721 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87722 +*//***************************************************************************/
87723 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87724 + uint8_t triggerId,
87725 + uint64_t *p_TimeStamp);
87726 +
87727 +/**************************************************************************//**
87728 + @Function FM_RTC_GetCurrentTime
87729 +
87730 + @Description Returns the current RTC time.
87731 +
87732 + @Param[in] h_FmRtc - Handle to FM RTC object.
87733 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87734 +
87735 + @Return E_OK on success; Error code otherwise.
87736 +
87737 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87738 +*//***************************************************************************/
87739 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87740 +
87741 +/**************************************************************************//**
87742 + @Function FM_RTC_SetCurrentTime
87743 +
87744 + @Description Sets the current RTC time.
87745 +
87746 + @Param[in] h_FmRtc - Handle to FM RTC object.
87747 + @Param[in] ts - The new time stamp (in nanoseconds).
87748 +
87749 + @Return E_OK on success; Error code otherwise.
87750 +
87751 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87752 +*//***************************************************************************/
87753 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87754 +
87755 +/**************************************************************************//**
87756 + @Function FM_RTC_GetFreqCompensation
87757 +
87758 + @Description Retrieves the frequency compensation value
87759 +
87760 + @Param[in] h_FmRtc - Handle to FM RTC object.
87761 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87762 +
87763 + @Return E_OK on success; Error code otherwise.
87764 +
87765 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87766 +*//***************************************************************************/
87767 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87768 +
87769 +/**************************************************************************//**
87770 + @Function FM_RTC_SetFreqCompensation
87771 +
87772 + @Description Sets a new frequency compensation value.
87773 +
87774 + @Param[in] h_FmRtc - Handle to FM RTC object.
87775 + @Param[in] freqCompensation - The new frequency compensation value to set.
87776 +
87777 + @Return E_OK on success; Error code otherwise.
87778 +
87779 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87780 +*//***************************************************************************/
87781 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87782 +
87783 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87784 +/**************************************************************************//**
87785 +*@Function FM_RTC_EnableInterrupt
87786 +*
87787 +*@Description Enable interrupt of FM RTC.
87788 +*
87789 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87790 +*@Param[in] events - Interrupt events.
87791 +*
87792 +*@Return E_OK on success; Error code otherwise.
87793 +*//***************************************************************************/
87794 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87795 +
87796 +/**************************************************************************//**
87797 +*@Function FM_RTC_DisableInterrupt
87798 +*
87799 +*@Description Disable interrupt of FM RTC.
87800 +*
87801 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87802 +*@Param[in] events - Interrupt events.
87803 +*
87804 +*@Return E_OK on success; Error code otherwise.
87805 +*//***************************************************************************/
87806 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87807 +#endif
87808 +
87809 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87810 +/**************************************************************************//**
87811 + @Function FM_RTC_DumpRegs
87812 +
87813 + @Description Dumps all FM registers
87814 +
87815 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87816 +
87817 + @Return E_OK on success;
87818 +
87819 + @Cautions Allowed only FM_Init().
87820 +*//***************************************************************************/
87821 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87822 +#endif /* (defined(DEBUG_ERRORS) && ... */
87823 +
87824 +/** @} */ /* end of fm_rtc_control_grp */
87825 +/** @} */ /* end of fm_rtc_grp */
87826 +/** @} */ /* end of FM_grp group */
87827 +
87828 +
87829 +#endif /* __FM_RTC_EXT_H__ */
87830 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87831 new file mode 100644
87832 index 00000000..f9aed036
87833 --- /dev/null
87834 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87835 @@ -0,0 +1,411 @@
87836 +/*
87837 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87838 + *
87839 + * Redistribution and use in source and binary forms, with or without
87840 + * modification, are permitted provided that the following conditions are met:
87841 + * * Redistributions of source code must retain the above copyright
87842 + * notice, this list of conditions and the following disclaimer.
87843 + * * Redistributions in binary form must reproduce the above copyright
87844 + * notice, this list of conditions and the following disclaimer in the
87845 + * documentation and/or other materials provided with the distribution.
87846 + * * Neither the name of Freescale Semiconductor nor the
87847 + * names of its contributors may be used to endorse or promote products
87848 + * derived from this software without specific prior written permission.
87849 + *
87850 + *
87851 + * ALTERNATIVELY, this software may be distributed under the terms of the
87852 + * GNU General Public License ("GPL") as published by the Free Software
87853 + * Foundation, either version 2 of that License or (at your option) any
87854 + * later version.
87855 + *
87856 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87857 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87858 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87859 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87860 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87861 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87862 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87863 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87864 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87865 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87866 + */
87867 +
87868 +
87869 +/**************************************************************************//**
87870 + @File fm_vsp_ext.h
87871 +
87872 + @Description FM Virtual Storage-Profile ...
87873 +*//***************************************************************************/
87874 +#ifndef __FM_VSP_EXT_H
87875 +#define __FM_VSP_EXT_H
87876 +
87877 +#include "std_ext.h"
87878 +#include "error_ext.h"
87879 +#include "string_ext.h"
87880 +#include "debug_ext.h"
87881 +
87882 +#include "fm_ext.h"
87883 +
87884 +
87885 +/**************************************************************************//**
87886 +
87887 + @Group FM_grp Frame Manager API
87888 +
87889 + @Description FM API functions, definitions and enums
87890 +
87891 + @{
87892 +*//***************************************************************************/
87893 +
87894 +/**************************************************************************//**
87895 + @Group FM_VSP_grp FM Virtual-Storage-Profile
87896 +
87897 + @Description FM Virtual-Storage-Profile API
87898 +
87899 + @{
87900 +*//***************************************************************************/
87901 +
87902 +/**************************************************************************//**
87903 + @Group FM_VSP_init_grp FM VSP Initialization Unit
87904 +
87905 + @Description FM VSP initialization API.
87906 +
87907 + @{
87908 +*//***************************************************************************/
87909 +
87910 +/**************************************************************************//**
87911 + @Description Virtual Storage Profile
87912 +*//***************************************************************************/
87913 +typedef struct t_FmVspParams {
87914 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
87915 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
87916 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
87917 + parameter associated with Rx / OP port */
87918 + uint16_t liodnOffset; /**< VSP's LIODN offset */
87919 + struct {
87920 + e_FmPortType portType; /**< Port type */
87921 + uint8_t portId; /**< Port Id - relative to type */
87922 + } portParams;
87923 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
87924 + defined in relevant FM object */
87925 +} t_FmVspParams;
87926 +
87927 +
87928 +/**************************************************************************//**
87929 + @Function FM_VSP_Config
87930 +
87931 + @Description Creates descriptor for the FM VSP module.
87932 +
87933 + The routine returns a handle (descriptor) to the FM VSP object.
87934 + This descriptor must be passed as first parameter to all other
87935 + FM VSP function calls.
87936 +
87937 + No actual initialization or configuration of FM hardware is
87938 + done by this routine.
87939 +
87940 +@Param[in] p_FmVspParams Pointer to data structure of parameters
87941 +
87942 + @Retval Handle to FM VSP object, or NULL for Failure.
87943 +*//***************************************************************************/
87944 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
87945 +
87946 +/**************************************************************************//**
87947 + @Function FM_VSP_Init
87948 +
87949 + @Description Initializes the FM VSP module
87950 +
87951 + @Param[in] h_FmVsp - FM VSP module descriptor
87952 +
87953 + @Return E_OK on success; Error code otherwise.
87954 +*//***************************************************************************/
87955 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
87956 +
87957 +/**************************************************************************//**
87958 + @Function FM_VSP_Free
87959 +
87960 + @Description Frees all resources that were assigned to FM VSP module.
87961 +
87962 + Calling this routine invalidates the descriptor.
87963 +
87964 + @Param[in] h_FmVsp - FM VSP module descriptor
87965 +
87966 + @Return E_OK on success; Error code otherwise.
87967 +*//***************************************************************************/
87968 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
87969 +
87970 +
87971 +/**************************************************************************//**
87972 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
87973 +
87974 + @Description FM VSP advanced configuration functions.
87975 +
87976 + @{
87977 +*//***************************************************************************/
87978 +
87979 +/**************************************************************************//**
87980 + @Function FM_VSP_ConfigBufferPrefixContent
87981 +
87982 + @Description Defines the structure, size and content of the application buffer.
87983 +
87984 + The prefix will
87985 + In VSPs defined for Tx ports, if 'passPrsResult', the application
87986 + should set a value to their offsets in the prefix of
87987 + the FM will save the first 'privDataSize', than,
87988 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
87989 + and timeStamp, and the packet itself (in this order), to the
87990 + application buffer, and to offset.
87991 +
87992 + Calling this routine changes the buffer margins definitions
87993 + in the internal driver data base from its default
87994 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
87995 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
87996 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
87997 +
87998 + @Param[in] h_FmVsp A handle to a FM VSP module.
87999 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
88000 + structure of the buffer.
88001 + Out parameter: Start margin - offset
88002 + of data from start of external buffer.
88003 +
88004 + @Return E_OK on success; Error code otherwise.
88005 +
88006 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88007 +*//***************************************************************************/
88008 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
88009 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
88010 +
88011 +/**************************************************************************//**
88012 + @Function FM_VSP_ConfigDmaSwapData
88013 +
88014 + @Description Calling this routine changes the DMA swap data parameter
88015 + in the internal driver data base from its default
88016 + configuration [DEFAULT_FM_SP_dmaSwapData]
88017 +
88018 + @Param[in] h_FmVsp A handle to a FM VSP module.
88019 + @Param[in] swapData New selection
88020 +
88021 + @Return E_OK on success; Error code otherwise.
88022 +
88023 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88024 +*//***************************************************************************/
88025 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
88026 +
88027 +/**************************************************************************//**
88028 + @Function FM_VSP_ConfigDmaIcCacheAttr
88029 +
88030 + @Description Calling this routine changes the internal context cache
88031 + attribute parameter in the internal driver data base
88032 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
88033 +
88034 + @Param[in] h_FmVsp A handle to a FM VSP module.
88035 + @Param[in] intContextCacheAttr New selection
88036 +
88037 + @Return E_OK on success; Error code otherwise.
88038 +
88039 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88040 +*//***************************************************************************/
88041 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
88042 + e_FmDmaCacheOption intContextCacheAttr);
88043 +
88044 +/**************************************************************************//**
88045 + @Function FM_VSP_ConfigDmaHdrAttr
88046 +
88047 + @Description Calling this routine changes the header cache
88048 + attribute parameter in the internal driver data base
88049 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
88050 +
88051 + @Param[in] h_FmVsp A handle to a FM VSP module.
88052 + @Param[in] headerCacheAttr New selection
88053 +
88054 + @Return E_OK on success; Error code otherwise.
88055 +
88056 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88057 +*//***************************************************************************/
88058 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
88059 +
88060 +/**************************************************************************//**
88061 + @Function FM_VSP_ConfigDmaScatterGatherAttr
88062 +
88063 + @Description Calling this routine changes the scatter gather cache
88064 + attribute parameter in the internal driver data base
88065 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
88066 +
88067 + @Param[in] h_FmVsp A handle to a FM VSP module.
88068 + @Param[in] scatterGatherCacheAttr New selection
88069 +
88070 + @Return E_OK on success; Error code otherwise.
88071 +
88072 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88073 +*//***************************************************************************/
88074 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
88075 + e_FmDmaCacheOption scatterGatherCacheAttr);
88076 +
88077 +/**************************************************************************//**
88078 + @Function FM_VSP_ConfigDmaWriteOptimize
88079 +
88080 + @Description Calling this routine changes the write optimization
88081 + parameter in the internal driver data base
88082 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
88083 +
88084 + @Param[in] h_FmVsp A handle to a FM VSP module.
88085 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
88086 +
88087 + @Return E_OK on success; Error code otherwise.
88088 +
88089 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88090 +*//***************************************************************************/
88091 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
88092 +
88093 +/**************************************************************************//**
88094 + @Function FM_VSP_ConfigNoScatherGather
88095 +
88096 + @Description Calling this routine changes the possibility to receive S/G frame
88097 + in the internal driver data base
88098 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
88099 +
88100 + @Param[in] h_FmVsp A handle to a FM VSP module.
88101 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
88102 +
88103 + @Return E_OK on success; Error code otherwise.
88104 +
88105 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88106 +*//***************************************************************************/
88107 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
88108 +
88109 +/**************************************************************************//**
88110 + @Function FM_VSP_ConfigPoolDepletion
88111 +
88112 + @Description Calling this routine enables pause frame generation depending on the
88113 + depletion status of BM pools. It also defines the conditions to activate
88114 + this functionality. By default, this functionality is disabled.
88115 +
88116 + @Param[in] h_FmVsp A handle to a FM VSP module.
88117 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
88118 +
88119 + @Return E_OK on success; Error code otherwise.
88120 +
88121 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88122 +*//***************************************************************************/
88123 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
88124 +
88125 +/**************************************************************************//**
88126 + @Function FM_VSP_ConfigBackupPools
88127 +
88128 + @Description Calling this routine allows the configuration of some of the BM pools
88129 + defined for this port as backup pools.
88130 + A pool configured to be a backup pool will be used only if all other
88131 + enabled non-backup pools are depleted.
88132 +
88133 + @Param[in] h_FmVsp A handle to a FM VSP module.
88134 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
88135 + be defined as backup pools.
88136 +
88137 + @Return E_OK on success; Error code otherwise.
88138 +
88139 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88140 +*//***************************************************************************/
88141 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
88142 +
88143 +/** @} */ /* end of FM_VSP_adv_config_grp group */
88144 +/** @} */ /* end of FM_VSP_init_grp group */
88145 +
88146 +
88147 +/**************************************************************************//**
88148 + @Group FM_VSP_control_grp FM VSP Control Unit
88149 +
88150 + @Description FM VSP runtime control API.
88151 +
88152 + @{
88153 +*//***************************************************************************/
88154 +
88155 +/**************************************************************************//**
88156 + @Function FM_VSP_GetBufferDataOffset
88157 +
88158 + @Description Relevant for Rx ports.
88159 + Returns the data offset from the beginning of the data buffer
88160 +
88161 + @Param[in] h_FmVsp - FM PORT module descriptor
88162 +
88163 + @Return data offset.
88164 +
88165 + @Cautions Allowed only following FM_VSP_Init().
88166 +*//***************************************************************************/
88167 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
88168 +
88169 +/**************************************************************************//**
88170 + @Function FM_VSP_GetBufferICInfo
88171 +
88172 + @Description Returns the Internal Context offset from the beginning of the data buffer
88173 +
88174 + @Param[in] h_FmVsp - FM PORT module descriptor
88175 + @Param[in] p_Data - A pointer to the data buffer.
88176 +
88177 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
88178 + configured for this port.
88179 +
88180 + @Cautions Allowed only following FM_VSP_Init().
88181 +*//***************************************************************************/
88182 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
88183 +
88184 +/**************************************************************************//**
88185 + @Function FM_VSP_GetBufferPrsResult
88186 +
88187 + @Description Returns the pointer to the parse result in the data buffer.
88188 + In Rx ports this is relevant after reception, if parse
88189 + result is configured to be part of the data passed to the
88190 + application. For non Rx ports it may be used to get the pointer
88191 + of the area in the buffer where parse result should be
88192 + initialized - if so configured.
88193 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88194 + configuration.
88195 +
88196 + @Param[in] h_FmVsp - FM PORT module descriptor
88197 + @Param[in] p_Data - A pointer to the data buffer.
88198 +
88199 + @Return Parse result pointer on success, NULL if parse result was not
88200 + configured for this port.
88201 +
88202 + @Cautions Allowed only following FM_VSP_Init().
88203 +*//***************************************************************************/
88204 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
88205 +
88206 +/**************************************************************************//**
88207 + @Function FM_VSP_GetBufferTimeStamp
88208 +
88209 + @Description Returns the time stamp in the data buffer.
88210 + Relevant for Rx ports for getting the buffer time stamp.
88211 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88212 + configuration.
88213 +
88214 + @Param[in] h_FmVsp - FM PORT module descriptor
88215 + @Param[in] p_Data - A pointer to the data buffer.
88216 +
88217 + @Return A pointer to the hash result on success, NULL otherwise.
88218 +
88219 + @Cautions Allowed only following FM_VSP_Init().
88220 +*//***************************************************************************/
88221 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
88222 +
88223 +/**************************************************************************//**
88224 + @Function FM_VSP_GetBufferHashResult
88225 +
88226 + @Description Given a data buffer, on the condition that hash result was defined
88227 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
88228 + this routine will return the pointer to the hash result location in the
88229 + buffer prefix.
88230 +
88231 + @Param[in] h_FmVsp - FM PORT module descriptor
88232 + @Param[in] p_Data - A pointer to the data buffer.
88233 +
88234 + @Return A pointer to the hash result on success, NULL otherwise.
88235 +
88236 + @Cautions Allowed only following FM_VSP_Init().
88237 +*//***************************************************************************/
88238 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
88239 +
88240 +
88241 +/** @} */ /* end of FM_VSP_control_grp group */
88242 +/** @} */ /* end of FM_VSP_grp group */
88243 +/** @} */ /* end of FM_grp group */
88244 +
88245 +
88246 +#endif /* __FM_VSP_EXT_H */
88247 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88248 new file mode 100644
88249 index 00000000..f635d3c2
88250 --- /dev/null
88251 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88252 @@ -0,0 +1,76 @@
88253 +/*
88254 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88255 + *
88256 + * Redistribution and use in source and binary forms, with or without
88257 + * modification, are permitted provided that the following conditions are met:
88258 + * * Redistributions of source code must retain the above copyright
88259 + * notice, this list of conditions and the following disclaimer.
88260 + * * Redistributions in binary form must reproduce the above copyright
88261 + * notice, this list of conditions and the following disclaimer in the
88262 + * documentation and/or other materials provided with the distribution.
88263 + * * Neither the name of Freescale Semiconductor nor the
88264 + * names of its contributors may be used to endorse or promote products
88265 + * derived from this software without specific prior written permission.
88266 + *
88267 + *
88268 + * ALTERNATIVELY, this software may be distributed under the terms of the
88269 + * GNU General Public License ("GPL") as published by the Free Software
88270 + * Foundation, either version 2 of that License or (at your option) any
88271 + * later version.
88272 + *
88273 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88274 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88275 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88276 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88277 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88278 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88279 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88280 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88281 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88282 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88283 + */
88284 +
88285 +
88286 +
88287 +#ifndef __MII_ACC_EXT_H
88288 +#define __MII_ACC_EXT_H
88289 +
88290 +
88291 +/**************************************************************************//**
88292 + @Function MII_ReadPhyReg
88293 +
88294 + @Description This routine is called to read a specified PHY
88295 + register value.
88296 +
88297 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88298 + @Param[in] phyAddr - PHY address (0-31).
88299 + @Param[in] reg - PHY register to read
88300 + @Param[out] p_Data - Gets the register value.
88301 +
88302 + @Return Always zero (success).
88303 +*//***************************************************************************/
88304 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
88305 + uint8_t phyAddr,
88306 + uint8_t reg,
88307 + uint16_t *p_Data);
88308 +
88309 +/**************************************************************************//**
88310 + @Function MII_WritePhyReg
88311 +
88312 + @Description This routine is called to write data to a specified PHY
88313 + register.
88314 +
88315 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88316 + @Param[in] phyAddr - PHY address (0-31).
88317 + @Param[in] reg - PHY register to write
88318 + @Param[in] data - Data to write in register.
88319 +
88320 + @Return Always zero (success).
88321 +*//***************************************************************************/
88322 +int MII_WritePhyReg(t_Handle h_MiiAccess,
88323 + uint8_t phyAddr,
88324 + uint8_t reg,
88325 + uint16_t data);
88326 +
88327 +
88328 +#endif /* __MII_ACC_EXT_H */
88329 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88330 new file mode 100644
88331 index 00000000..ec89a6dd
88332 --- /dev/null
88333 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88334 @@ -0,0 +1,90 @@
88335 +/*
88336 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88337 + *
88338 + * Redistribution and use in source and binary forms, with or without
88339 + * modification, are permitted provided that the following conditions are met:
88340 + * * Redistributions of source code must retain the above copyright
88341 + * notice, this list of conditions and the following disclaimer.
88342 + * * Redistributions in binary form must reproduce the above copyright
88343 + * notice, this list of conditions and the following disclaimer in the
88344 + * documentation and/or other materials provided with the distribution.
88345 + * * Neither the name of Freescale Semiconductor nor the
88346 + * names of its contributors may be used to endorse or promote products
88347 + * derived from this software without specific prior written permission.
88348 + *
88349 + *
88350 + * ALTERNATIVELY, this software may be distributed under the terms of the
88351 + * GNU General Public License ("GPL") as published by the Free Software
88352 + * Foundation, either version 2 of that License or (at your option) any
88353 + * later version.
88354 + *
88355 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88356 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88357 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88358 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88359 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88360 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88361 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88362 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88363 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88364 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88365 + */
88366 +
88367 +
88368 +/**************************************************************************//**
88369 + @File core_ext.h
88370 +
88371 + @Description Generic interface to basic core operations.
88372 +
88373 + The system integrator must ensure that this interface is
88374 + mapped to a specific core implementation, by including the
88375 + appropriate header file.
88376 +*//***************************************************************************/
88377 +#ifndef __CORE_EXT_H
88378 +#define __CORE_EXT_H
88379 +
88380 +#ifdef CONFIG_FMAN_ARM
88381 +#include "arm_ext.h"
88382 +#include <linux/smp.h>
88383 +#else
88384 +#ifdef NCSW_PPC_CORE
88385 +#include "ppc_ext.h"
88386 +#elif defined(NCSW_VXWORKS)
88387 +#include "core_vxw_ext.h"
88388 +#else
88389 +#error "Core is not defined!"
88390 +#endif /* NCSW_CORE */
88391 +
88392 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88393 +#error "Must define core as little-endian or big-endian!"
88394 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88395 +
88396 +#ifndef CORE_CACHELINE_SIZE
88397 +#error "Must define the core cache-line size!"
88398 +#endif /* !CORE_CACHELINE_SIZE */
88399 +
88400 +#endif /* CONFIG_FMAN_ARM */
88401 +
88402 +
88403 +/**************************************************************************//**
88404 + @Function CORE_GetId
88405 +
88406 + @Description Returns the core ID in the system.
88407 +
88408 + @Return Core ID.
88409 +*//***************************************************************************/
88410 +uint32_t CORE_GetId(void);
88411 +
88412 +/**************************************************************************//**
88413 + @Function CORE_MemoryBarrier
88414 +
88415 + @Description This routine will cause the core to stop executing any commands
88416 + until all previous memory read/write commands are completely out
88417 + of the core's pipeline.
88418 +
88419 + @Return None.
88420 +*//***************************************************************************/
88421 +void CORE_MemoryBarrier(void);
88422 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88423 +
88424 +#endif /* __CORE_EXT_H */
88425 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88426 new file mode 100644
88427 index 00000000..e63444a7
88428 --- /dev/null
88429 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88430 @@ -0,0 +1,55 @@
88431 +/*
88432 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88433 + *
88434 + * Redistribution and use in source and binary forms, with or without
88435 + * modification, are permitted provided that the following conditions are met:
88436 + * * Redistributions of source code must retain the above copyright
88437 + * notice, this list of conditions and the following disclaimer.
88438 + * * Redistributions in binary form must reproduce the above copyright
88439 + * notice, this list of conditions and the following disclaimer in the
88440 + * documentation and/or other materials provided with the distribution.
88441 + * * Neither the name of Freescale Semiconductor nor the
88442 + * names of its contributors may be used to endorse or promote products
88443 + * derived from this software without specific prior written permission.
88444 + *
88445 + *
88446 + * ALTERNATIVELY, this software may be distributed under the terms of the
88447 + * GNU General Public License ("GPL") as published by the Free Software
88448 + * Foundation, either version 2 of that License or (at your option) any
88449 + * later version.
88450 + *
88451 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88452 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88453 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88454 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88455 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88456 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88457 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88458 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88459 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88460 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88461 + */
88462 +
88463 +
88464 +/**************************************************************************//**
88465 + @File arm_ext.h
88466 +
88467 + @Description Core API for ARM cores
88468 +
88469 + These routines must be implemented by each specific PowerPC
88470 + core driver.
88471 +*//***************************************************************************/
88472 +#ifndef __ARM_EXT_H
88473 +#define __ARM_EXT_H
88474 +
88475 +#include "part_ext.h"
88476 +
88477 +
88478 +#define CORE_IS_LITTLE_ENDIAN
88479 +
88480 +static __inline__ void CORE_MemoryBarrier(void)
88481 +{
88482 + mb();
88483 +}
88484 +
88485 +#endif /* __PPC_EXT_H */
88486 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88487 new file mode 100644
88488 index 00000000..e79b1ddf
88489 --- /dev/null
88490 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88491 @@ -0,0 +1,476 @@
88492 +/*
88493 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88494 + *
88495 + * Redistribution and use in source and binary forms, with or without
88496 + * modification, are permitted provided that the following conditions are met:
88497 + * * Redistributions of source code must retain the above copyright
88498 + * notice, this list of conditions and the following disclaimer.
88499 + * * Redistributions in binary form must reproduce the above copyright
88500 + * notice, this list of conditions and the following disclaimer in the
88501 + * documentation and/or other materials provided with the distribution.
88502 + * * Neither the name of Freescale Semiconductor nor the
88503 + * names of its contributors may be used to endorse or promote products
88504 + * derived from this software without specific prior written permission.
88505 + *
88506 + *
88507 + * ALTERNATIVELY, this software may be distributed under the terms of the
88508 + * GNU General Public License ("GPL") as published by the Free Software
88509 + * Foundation, either version 2 of that License or (at your option) any
88510 + * later version.
88511 + *
88512 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88513 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88514 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88515 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88516 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88517 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88518 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88519 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88520 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88521 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88522 + */
88523 +
88524 +
88525 +/**************************************************************************//**
88526 + @File e500v2_ext.h
88527 +
88528 + @Description E500 external definitions prototypes
88529 + This file is not included by the E500
88530 + source file as it is an assembly file. It is used
88531 + only for prototypes exposure, for inclusion
88532 + by user and other modules.
88533 +*//***************************************************************************/
88534 +
88535 +#ifndef __E500V2_EXT_H
88536 +#define __E500V2_EXT_H
88537 +
88538 +#include "std_ext.h"
88539 +
88540 +
88541 +/* Layer 1 Cache Manipulations
88542 + *==============================
88543 + * Should not be called directly by the user.
88544 + */
88545 +void L1DCache_Invalidate (void);
88546 +void L1ICache_Invalidate(void);
88547 +void L1DCache_Enable(void);
88548 +void L1ICache_Enable(void);
88549 +void L1DCache_Disable(void);
88550 +void L1ICache_Disable(void);
88551 +void L1DCache_Flush(void);
88552 +void L1ICache_Flush(void);
88553 +uint32_t L1ICache_IsEnabled(void);
88554 +uint32_t L1DCache_IsEnabled(void);
88555 +/*
88556 + *
88557 + */
88558 +uint32_t L1DCache_LineLock(uint32_t addr);
88559 +uint32_t L1ICache_LineLock(uint32_t addr);
88560 +void L1Cache_BroadCastEnable(void);
88561 +void L1Cache_BroadCastDisable(void);
88562 +
88563 +
88564 +#define CORE_DCacheEnable E500_DCacheEnable
88565 +#define CORE_ICacheEnable E500_ICacheEnable
88566 +#define CORE_DCacheDisable E500_DCacheDisable
88567 +#define CORE_ICacheDisable E500_ICacheDisable
88568 +#define CORE_GetId E500_GetId
88569 +#define CORE_TestAndSet E500_TestAndSet
88570 +#define CORE_MemoryBarrier E500_MemoryBarrier
88571 +#define CORE_InstructionSync E500_InstructionSync
88572 +
88573 +#define CORE_SetDozeMode E500_SetDozeMode
88574 +#define CORE_SetNapMode E500_SetNapMode
88575 +#define CORE_SetSleepMode E500_SetSleepMode
88576 +#define CORE_SetJogMode E500_SetJogMode
88577 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88578 +
88579 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88580 +#define CORE_RecoverNapMode E500_RecoverNapMode
88581 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88582 +#define CORE_RecoverJogMode E500_RecoverJogMode
88583 +
88584 +void E500_SetDozeMode(void);
88585 +void E500_SetNapMode(void);
88586 +void E500_SetSleepMode(void);
88587 +void E500_SetJogMode(void);
88588 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88589 +
88590 +void E500_RecoverDozeMode(void);
88591 +void E500_RecoverNapMode(void);
88592 +void E500_RecoverSleepMode(void);
88593 +void E500_RecoverJogMode(void);
88594 +
88595 +
88596 +/**************************************************************************//**
88597 + @Group E500_id E500 Application Programming Interface
88598 +
88599 + @Description E500 API functions, definitions and enums
88600 +
88601 + @{
88602 +*//***************************************************************************/
88603 +
88604 +/**************************************************************************//**
88605 + @Group E500_init_grp E500 Initialization Unit
88606 +
88607 + @Description E500 initialization unit API functions, definitions and enums
88608 +
88609 + @{
88610 +*//***************************************************************************/
88611 +
88612 +
88613 +/**************************************************************************//**
88614 + @Function E500_DCacheEnable
88615 +
88616 + @Description Enables the data cache for memory pages that are
88617 + not cache inhibited.
88618 +
88619 + @Return None.
88620 +*//***************************************************************************/
88621 +void E500_DCacheEnable(void);
88622 +
88623 +/**************************************************************************//**
88624 + @Function E500_ICacheEnable
88625 +
88626 + @Description Enables the instruction cache for memory pages that are
88627 + not cache inhibited.
88628 +
88629 + @Return None.
88630 +*//***************************************************************************/
88631 +void E500_ICacheEnable(void);
88632 +
88633 +/**************************************************************************//**
88634 + @Function E500_DCacheDisable
88635 +
88636 + @Description Disables the data cache.
88637 +
88638 + @Return None.
88639 +*//***************************************************************************/
88640 +void E500_DCacheDisable(void);
88641 +
88642 +/**************************************************************************//**
88643 + @Function E500_ICacheDisable
88644 +
88645 + @Description Disables the instruction cache.
88646 +
88647 + @Return None.
88648 +*//***************************************************************************/
88649 +void E500_ICacheDisable(void);
88650 +
88651 +/**************************************************************************//**
88652 + @Function E500_DCacheFlush
88653 +
88654 + @Description Flushes the data cache
88655 +
88656 + @Return None.
88657 +*//***************************************************************************/
88658 +void E500_DCacheFlush(void);
88659 +
88660 +/**************************************************************************//**
88661 + @Function E500_ICacheFlush
88662 +
88663 + @Description Flushes the instruction cache.
88664 +
88665 + @Return None.
88666 +*//***************************************************************************/
88667 +void E500_ICacheFlush(void);
88668 +
88669 +/**************************************************************************//**
88670 + @Function E500_DCacheSetStashId
88671 +
88672 + @Description Set Stash Id for data cache
88673 +
88674 + @Param[in] stashId the stash id to be set.
88675 +
88676 + @Return None.
88677 +*//***************************************************************************/
88678 +void E500_DCacheSetStashId(uint8_t stashId);
88679 +
88680 +/**************************************************************************//**
88681 + @Description E500mc L2 Cache Operation Mode
88682 +*//***************************************************************************/
88683 +typedef enum e_E500mcL2CacheMode
88684 +{
88685 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88686 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88687 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88688 +} e_E500mcL2CacheMode;
88689 +
88690 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88691 +/**************************************************************************//**
88692 + @Function E500_L2CacheEnable
88693 +
88694 + @Description Enables the cache for memory pages that are not cache inhibited.
88695 +
88696 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88697 +
88698 + @Return None.
88699 +
88700 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88701 + not possible to call this routine for i-cache and than to call
88702 + again for d-cache; The second call will override the first one.
88703 +*//***************************************************************************/
88704 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88705 +
88706 +/**************************************************************************//**
88707 + @Function E500_L2CacheDisable
88708 +
88709 + @Description Disables the cache (data instruction or both).
88710 +
88711 + @Return None.
88712 +
88713 +*//***************************************************************************/
88714 +void E500_L2CacheDisable(void);
88715 +
88716 +/**************************************************************************//**
88717 + @Function E500_L2CacheFlush
88718 +
88719 + @Description Flushes the cache.
88720 +
88721 + @Return None.
88722 +*//***************************************************************************/
88723 +void E500_L2CacheFlush(void);
88724 +
88725 +/**************************************************************************//**
88726 + @Function E500_L2SetStashId
88727 +
88728 + @Description Set Stash Id
88729 +
88730 + @Param[in] stashId the stash id to be set.
88731 +
88732 + @Return None.
88733 +*//***************************************************************************/
88734 +void E500_L2SetStashId(uint8_t stashId);
88735 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88736 +
88737 +#ifdef CORE_E6500
88738 +/**************************************************************************//**
88739 + @Function E6500_L2CacheEnable
88740 +
88741 + @Description Enables the cache for memory pages that are not cache inhibited.
88742 +
88743 + @param[in] mode - L2 cache mode: support data & instruction only.
88744 +
88745 + @Return None.
88746 +
88747 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88748 + not possible to call this routine for i-cache and than to call
88749 + again for d-cache; The second call will override the first one.
88750 +*//***************************************************************************/
88751 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88752 +
88753 +/**************************************************************************//**
88754 + @Function E6500_L2CacheDisable
88755 +
88756 + @Description Disables the cache (data instruction or both).
88757 +
88758 + @Return None.
88759 +
88760 +*//***************************************************************************/
88761 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88762 +
88763 +/**************************************************************************//**
88764 + @Function E6500_L2CacheFlush
88765 +
88766 + @Description Flushes the cache.
88767 +
88768 + @Return None.
88769 +*//***************************************************************************/
88770 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88771 +
88772 +/**************************************************************************//**
88773 + @Function E6500_L2SetStashId
88774 +
88775 + @Description Set Stash Id
88776 +
88777 + @Param[in] stashId the stash id to be set.
88778 +
88779 + @Return None.
88780 +*//***************************************************************************/
88781 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88782 +
88783 +/**************************************************************************//**
88784 + @Function E6500_GetCcsrBase
88785 +
88786 + @Description Obtain SoC CCSR base address
88787 +
88788 + @Param[in] None.
88789 +
88790 + @Return Physical CCSR base address.
88791 +*//***************************************************************************/
88792 +physAddress_t E6500_GetCcsrBase(void);
88793 +#endif /* CORE_E6500 */
88794 +
88795 +/**************************************************************************//**
88796 + @Function E500_AddressBusStreamingEnable
88797 +
88798 + @Description Enables address bus streaming on the CCB.
88799 +
88800 + This setting, along with the ECM streaming configuration
88801 + parameters, enables address bus streaming on the CCB.
88802 +
88803 + @Return None.
88804 +*//***************************************************************************/
88805 +void E500_AddressBusStreamingEnable(void);
88806 +
88807 +/**************************************************************************//**
88808 + @Function E500_AddressBusStreamingDisable
88809 +
88810 + @Description Disables address bus streaming on the CCB.
88811 +
88812 + @Return None.
88813 +*//***************************************************************************/
88814 +void E500_AddressBusStreamingDisable(void);
88815 +
88816 +/**************************************************************************//**
88817 + @Function E500_AddressBroadcastEnable
88818 +
88819 + @Description Enables address broadcast.
88820 +
88821 + The e500 broadcasts cache management instructions (dcbst, dcblc
88822 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88823 + based on ABE. ABE must be set to allow management of external
88824 + L2 caches.
88825 +
88826 + @Return None.
88827 +*//***************************************************************************/
88828 +void E500_AddressBroadcastEnable(void);
88829 +
88830 +/**************************************************************************//**
88831 + @Function E500_AddressBroadcastDisable
88832 +
88833 + @Description Disables address broadcast.
88834 +
88835 + The e500 broadcasts cache management instructions (dcbst, dcblc
88836 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88837 + based on ABE. ABE must be set to allow management of external
88838 + L2 caches.
88839 +
88840 + @Return None.
88841 +*//***************************************************************************/
88842 +void E500_AddressBroadcastDisable(void);
88843 +
88844 +/**************************************************************************//**
88845 + @Function E500_IsTaskletSupported
88846 +
88847 + @Description Checks if tasklets are supported by the e500 interrupt handler.
88848 +
88849 + @Retval TRUE - Tasklets are supported.
88850 + @Retval FALSE - Tasklets are not supported.
88851 +*//***************************************************************************/
88852 +bool E500_IsTaskletSupported(void);
88853 +
88854 +void E500_EnableTimeBase(void);
88855 +void E500_DisableTimeBase(void);
88856 +
88857 +uint64_t E500_GetTimeBaseTime(void);
88858 +
88859 +void E500_GenericIntrInit(void);
88860 +
88861 +t_Error E500_SetIntr(int ppcIntrSrc,
88862 + void (* Isr)(t_Handle handle),
88863 + t_Handle handle);
88864 +
88865 +t_Error E500_ClearIntr(int ppcIntrSrc);
88866 +
88867 +/**************************************************************************//**
88868 + @Function E500_GenericIntrHandler
88869 +
88870 + @Description This is the general e500 interrupt handler.
88871 +
88872 + It is called by the main assembly interrupt handler
88873 + when an exception occurs and no other function has been
88874 + assigned to this exception.
88875 +
88876 + @Param intrEntry - (In) The exception interrupt vector entry.
88877 +*//***************************************************************************/
88878 +void E500_GenericIntrHandler(uint32_t intrEntry);
88879 +
88880 +/**************************************************************************//**
88881 + @Function CriticalIntr
88882 +
88883 + @Description This is the specific critical e500 interrupt handler.
88884 +
88885 + It is called by the main assembly interrupt handler
88886 + when an critical interrupt.
88887 +
88888 + @Param intrEntry - (In) The exception interrupt vector entry.
88889 +*//***************************************************************************/
88890 +void CriticalIntr(uint32_t intrEntry);
88891 +
88892 +
88893 +/**************************************************************************//**
88894 + @Function E500_GetId
88895 +
88896 + @Description Returns the core ID in the system.
88897 +
88898 + @Return Core ID.
88899 +*//***************************************************************************/
88900 +uint32_t E500_GetId(void);
88901 +
88902 +/**************************************************************************//**
88903 + @Function E500_TestAndSet
88904 +
88905 + @Description This routine tries to atomically test-and-set an integer
88906 + in memory to a non-zero value.
88907 +
88908 + The memory will be set only if it is tested as zero, in which
88909 + case the routine returns the new non-zero value; otherwise the
88910 + routine returns zero.
88911 +
88912 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88913 + operation should be made.
88914 +
88915 + @Retval Zero - Operation failed - memory was already set.
88916 + @Retval Non-zero - Operation succeeded - memory has been set.
88917 +*//***************************************************************************/
88918 +int E500_TestAndSet(volatile int *p);
88919 +
88920 +/**************************************************************************//**
88921 + @Function E500_MemoryBarrier
88922 +
88923 + @Description This routine will cause the core to stop executing any commands
88924 + until all previous memory read/write commands are completely out
88925 + of the core's pipeline.
88926 +
88927 + @Return None.
88928 +*//***************************************************************************/
88929 +static __inline__ void E500_MemoryBarrier(void)
88930 +{
88931 +#ifndef CORE_E500V2
88932 + __asm__ ("mbar 1");
88933 +#else /* CORE_E500V2 */
88934 + /**** ERRATA WORK AROUND START ****/
88935 + /* ERRATA num: CPU1 */
88936 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
88937 + guarded loads and stores. */
88938 +
88939 + /* "msync" instruction is used instead */
88940 +
88941 + __asm__ ("msync");
88942 +
88943 + /**** ERRATA WORK AROUND END ****/
88944 +#endif /* CORE_E500V2 */
88945 +}
88946 +
88947 +/**************************************************************************//**
88948 + @Function E500_InstructionSync
88949 +
88950 + @Description This routine will cause the core to wait for previous instructions
88951 + (including any interrupts they generate) to complete before the
88952 + synchronization command executes, which purges all instructions
88953 + from the processor's pipeline and refetches the next instruction.
88954 +
88955 + @Return None.
88956 +*//***************************************************************************/
88957 +static __inline__ void E500_InstructionSync(void)
88958 +{
88959 + __asm__ ("isync");
88960 +}
88961 +
88962 +
88963 +/** @} */ /* end of E500_init_grp group */
88964 +/** @} */ /* end of E500_grp group */
88965 +
88966 +
88967 +#endif /* __E500V2_EXT_H */
88968 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88969 new file mode 100644
88970 index 00000000..9344b3a1
88971 --- /dev/null
88972 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88973 @@ -0,0 +1,141 @@
88974 +/*
88975 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88976 + *
88977 + * Redistribution and use in source and binary forms, with or without
88978 + * modification, are permitted provided that the following conditions are met:
88979 + * * Redistributions of source code must retain the above copyright
88980 + * notice, this list of conditions and the following disclaimer.
88981 + * * Redistributions in binary form must reproduce the above copyright
88982 + * notice, this list of conditions and the following disclaimer in the
88983 + * documentation and/or other materials provided with the distribution.
88984 + * * Neither the name of Freescale Semiconductor nor the
88985 + * names of its contributors may be used to endorse or promote products
88986 + * derived from this software without specific prior written permission.
88987 + *
88988 + *
88989 + * ALTERNATIVELY, this software may be distributed under the terms of the
88990 + * GNU General Public License ("GPL") as published by the Free Software
88991 + * Foundation, either version 2 of that License or (at your option) any
88992 + * later version.
88993 + *
88994 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88995 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88996 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88997 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88998 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88999 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89000 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89001 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89002 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89003 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89004 + */
89005 +
89006 +
89007 +/**************************************************************************//**
89008 + @File ppc_ext.h
89009 +
89010 + @Description Core API for PowerPC cores
89011 +
89012 + These routines must be implemented by each specific PowerPC
89013 + core driver.
89014 +*//***************************************************************************/
89015 +#ifndef __PPC_EXT_H
89016 +#define __PPC_EXT_H
89017 +
89018 +#include "part_ext.h"
89019 +
89020 +
89021 +#define CORE_IS_BIG_ENDIAN
89022 +
89023 +#if defined(CORE_E300) || defined(CORE_E500V2)
89024 +#define CORE_CACHELINE_SIZE 32
89025 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89026 +#define CORE_CACHELINE_SIZE 64
89027 +#else
89028 +#error "Core not defined!"
89029 +#endif /* defined(CORE_E300) || ... */
89030 +
89031 +
89032 +/**************************************************************************//**
89033 + @Function CORE_TestAndSet
89034 +
89035 + @Description This routine tries to atomically test-and-set an integer
89036 + in memory to a non-zero value.
89037 +
89038 + The memory will be set only if it is tested as zero, in which
89039 + case the routine returns the new non-zero value; otherwise the
89040 + routine returns zero.
89041 +
89042 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
89043 + operation should be made.
89044 +
89045 + @Retval Zero - Operation failed - memory was already set.
89046 + @Retval Non-zero - Operation succeeded - memory has been set.
89047 +*//***************************************************************************/
89048 +int CORE_TestAndSet(volatile int *p);
89049 +
89050 +/**************************************************************************//**
89051 + @Function CORE_InstructionSync
89052 +
89053 + @Description This routine will cause the core to wait for previous instructions
89054 + (including any interrupts they generate) to complete before the
89055 + synchronization command executes, which purges all instructions
89056 + from the processor's pipeline and refetches the next instruction.
89057 +
89058 + @Return None.
89059 +*//***************************************************************************/
89060 +void CORE_InstructionSync(void);
89061 +
89062 +/**************************************************************************//**
89063 + @Function CORE_DCacheEnable
89064 +
89065 + @Description Enables the data cache for memory pages that are
89066 + not cache inhibited.
89067 +
89068 + @Return None.
89069 +*//***************************************************************************/
89070 +void CORE_DCacheEnable(void);
89071 +
89072 +/**************************************************************************//**
89073 + @Function CORE_ICacheEnable
89074 +
89075 + @Description Enables the instruction cache for memory pages that are
89076 + not cache inhibited.
89077 +
89078 + @Return None.
89079 +*//***************************************************************************/
89080 +void CORE_ICacheEnable(void);
89081 +
89082 +/**************************************************************************//**
89083 + @Function CORE_DCacheDisable
89084 +
89085 + @Description Disables the data cache.
89086 +
89087 + @Return None.
89088 +*//***************************************************************************/
89089 +void CORE_DCacheDisable(void);
89090 +
89091 +/**************************************************************************//**
89092 + @Function CORE_ICacheDisable
89093 +
89094 + @Description Disables the instruction cache.
89095 +
89096 + @Return None.
89097 +*//***************************************************************************/
89098 +void CORE_ICacheDisable(void);
89099 +
89100 +
89101 +
89102 +#if defined(CORE_E300)
89103 +#include "e300_ext.h"
89104 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89105 +#include "e500v2_ext.h"
89106 +#if !defined(NCSW_LINUX)
89107 +#include "e500v2_asm_ext.h"
89108 +#endif
89109 +#else
89110 +#error "Core not defined!"
89111 +#endif
89112 +
89113 +
89114 +#endif /* __PPC_EXT_H */
89115 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
89116 new file mode 100644
89117 index 00000000..8bb343fc
89118 --- /dev/null
89119 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
89120 @@ -0,0 +1,77 @@
89121 +/*
89122 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89123 + *
89124 + * Redistribution and use in source and binary forms, with or without
89125 + * modification, are permitted provided that the following conditions are met:
89126 + * * Redistributions of source code must retain the above copyright
89127 + * notice, this list of conditions and the following disclaimer.
89128 + * * Redistributions in binary form must reproduce the above copyright
89129 + * notice, this list of conditions and the following disclaimer in the
89130 + * documentation and/or other materials provided with the distribution.
89131 + * * Neither the name of Freescale Semiconductor nor the
89132 + * names of its contributors may be used to endorse or promote products
89133 + * derived from this software without specific prior written permission.
89134 + *
89135 + *
89136 + * ALTERNATIVELY, this software may be distributed under the terms of the
89137 + * GNU General Public License ("GPL") as published by the Free Software
89138 + * Foundation, either version 2 of that License or (at your option) any
89139 + * later version.
89140 + *
89141 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89142 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89143 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89144 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89145 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89146 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89147 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89148 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89149 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89150 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89151 + */
89152 +
89153 +#ifndef __DDR_SDT_EXT_H
89154 +#define __DDR_SDT_EXT_H
89155 +
89156 +
89157 +/**************************************************************************//**
89158 + @Group ddr_Generic_Resources
89159 +
89160 + @Description ddr generic functions, definitions and enums.
89161 +
89162 + @{
89163 +*//***************************************************************************/
89164 +
89165 +
89166 +/**************************************************************************//**
89167 + @Description SPD maximum size
89168 +*//***************************************************************************/
89169 +#define SPD_MAX_SIZE 256
89170 +
89171 +/**************************************************************************//**
89172 + @Description DDR types select
89173 +*//***************************************************************************/
89174 +typedef enum e_DdrType
89175 +{
89176 + e_DDR_DDR1,
89177 + e_DDR_DDR2,
89178 + e_DDR_DDR3,
89179 + e_DDR_DDR3L,
89180 + e_DDR_DDR4
89181 +} e_DdrType;
89182 +
89183 +/**************************************************************************//**
89184 + @Description DDR Mode.
89185 +*//***************************************************************************/
89186 +typedef enum e_DdrMode
89187 +{
89188 + e_DDR_BUS_WIDTH_32BIT,
89189 + e_DDR_BUS_WIDTH_64BIT
89190 +} e_DdrMode;
89191 +
89192 +/** @} */ /* end of ddr_Generic_Resources group */
89193 +
89194 +
89195 +
89196 +#endif /* __DDR_SDT_EXT_H */
89197 +
89198 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89199 new file mode 100644
89200 index 00000000..57db0a14
89201 --- /dev/null
89202 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89203 @@ -0,0 +1,233 @@
89204 +/*
89205 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89206 + *
89207 + * Redistribution and use in source and binary forms, with or without
89208 + * modification, are permitted provided that the following conditions are met:
89209 + * * Redistributions of source code must retain the above copyright
89210 + * notice, this list of conditions and the following disclaimer.
89211 + * * Redistributions in binary form must reproduce the above copyright
89212 + * notice, this list of conditions and the following disclaimer in the
89213 + * documentation and/or other materials provided with the distribution.
89214 + * * Neither the name of Freescale Semiconductor nor the
89215 + * names of its contributors may be used to endorse or promote products
89216 + * derived from this software without specific prior written permission.
89217 + *
89218 + *
89219 + * ALTERNATIVELY, this software may be distributed under the terms of the
89220 + * GNU General Public License ("GPL") as published by the Free Software
89221 + * Foundation, either version 2 of that License or (at your option) any
89222 + * later version.
89223 + *
89224 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89225 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89226 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89227 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89228 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89229 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89230 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89231 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89232 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89233 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89234 + */
89235 +
89236 +
89237 +/**************************************************************************//**
89238 + @File debug_ext.h
89239 +
89240 + @Description Debug mode definitions.
89241 +*//***************************************************************************/
89242 +
89243 +#ifndef __DEBUG_EXT_H
89244 +#define __DEBUG_EXT_H
89245 +
89246 +#include "std_ext.h"
89247 +#include "xx_ext.h"
89248 +#include "memcpy_ext.h"
89249 +#if (DEBUG_ERRORS > 0)
89250 +#include "sprint_ext.h"
89251 +#include "string_ext.h"
89252 +#endif /* DEBUG_ERRORS > 0 */
89253 +
89254 +
89255 +#if (DEBUG_ERRORS > 0)
89256 +
89257 +/* Internally used macros */
89258 +
89259 +#define DUMP_Print XX_Print
89260 +#define DUMP_MAX_LEVELS 6
89261 +#define DUMP_IDX_LEN 6
89262 +#define DUMP_MAX_STR 64
89263 +
89264 +
89265 +#define _CREATE_DUMP_SUBSTR(phrase) \
89266 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
89267 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
89268 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
89269 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
89270 + { \
89271 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
89272 + if (dumpIsArr[dumpTmpLevel]) \
89273 + { \
89274 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
89275 + p_DumpToken = strtok(NULL, "."); \
89276 + } \
89277 + if ((p_DumpToken != NULL) && \
89278 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
89279 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
89280 + }
89281 +
89282 +
89283 +/**************************************************************************//**
89284 + @Group gen_id General Drivers Utilities
89285 +
89286 + @Description External routines.
89287 +
89288 + @{
89289 +*//***************************************************************************/
89290 +
89291 +/**************************************************************************//**
89292 + @Group dump_id Memory and Registers Dump Mechanism
89293 +
89294 + @Description Macros for dumping memory mapped structures.
89295 +
89296 + @{
89297 +*//***************************************************************************/
89298 +
89299 +/**************************************************************************//**
89300 + @Description Declaration of dump mechanism variables.
89301 +
89302 + This macro must be declared at the beginning of each routine
89303 + which uses the dump mechanism macros, before the routine's code
89304 + starts.
89305 +*//***************************************************************************/
89306 +#define DECLARE_DUMP \
89307 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
89308 + char dumpSubStr[DUMP_MAX_STR] = ""; \
89309 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
89310 + char *p_DumpToken = NULL; \
89311 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
89312 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
89313 + /* Prevent warnings if not all used */ \
89314 + UNUSED(dumpIdxStr[0][0]); \
89315 + UNUSED(dumpSubStr[0]); \
89316 + UNUSED(dumpTmpStr[0]); \
89317 + UNUSED(p_DumpToken); \
89318 + UNUSED(dumpArrIdx); \
89319 + UNUSED(dumpArrSize); \
89320 + UNUSED(dumpLevel); \
89321 + UNUSED(dumpTmpLevel); \
89322 + UNUSED(dumpIsArr[0]);
89323 +
89324 +
89325 +/**************************************************************************//**
89326 + @Description Prints a title for a subsequent dumped structure or memory.
89327 +
89328 + The inputs for this macro are the structure/memory title and
89329 + its base addresses.
89330 +*//***************************************************************************/
89331 +#define DUMP_TITLE(addr, msg) \
89332 + DUMP_Print("\r\n"); DUMP_Print msg; \
89333 + if (addr) \
89334 + DUMP_Print(" (%p)", (addr)); \
89335 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
89336 +
89337 +/**************************************************************************//**
89338 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
89339 +
89340 + The inputs for this macro are the sub-structure subtitle.
89341 + A separating line with this subtitle will be printed.
89342 +*//***************************************************************************/
89343 +#define DUMP_SUBTITLE(subtitle) \
89344 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
89345 +
89346 +
89347 +/**************************************************************************//**
89348 + @Description Dumps a memory region in 4-bytes aligned format.
89349 +
89350 + The inputs for this macro are the base addresses and size
89351 + (in bytes) of the memory region.
89352 +*//***************************************************************************/
89353 +#define DUMP_MEMORY(addr, size) \
89354 + MemDisp((uint8_t *)(addr), (int)(size))
89355 +
89356 +
89357 +/**************************************************************************//**
89358 + @Description Declares a dump loop, for dumping a sub-structure array.
89359 +
89360 + The inputs for this macro are:
89361 + - idx: an index variable, for indexing the sub-structure items
89362 + inside the loop. This variable must be declared separately
89363 + in the beginning of the routine.
89364 + - cnt: the number of times to repeat the loop. This number should
89365 + equal the number of items in the sub-structures array.
89366 +
89367 + Note, that the body of the loop must be written inside brackets.
89368 +*//***************************************************************************/
89369 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
89370 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
89371 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
89372 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
89373 +
89374 +
89375 +/**************************************************************************//**
89376 + @Description Dumps a structure's member variable.
89377 +
89378 + The input for this macro is the full reference for the member
89379 + variable, where the structure is referenced using a pointer.
89380 +
89381 + Note, that a members array must be dumped using DUMP_ARR macro,
89382 + rather than using this macro.
89383 +
89384 + If the member variable is part of a sub-structure hierarchy,
89385 + the full hierarchy (including array indexing) must be specified.
89386 +
89387 + Examples: p_Struct->member
89388 + p_Struct->sub.member
89389 + p_Struct->sub[i].member
89390 +*//***************************************************************************/
89391 +#define DUMP_VAR(st, phrase) \
89392 + do { \
89393 + void *addr = (void *)&((st)->phrase); \
89394 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89395 + _CREATE_DUMP_SUBSTR(phrase); \
89396 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89397 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89398 + } while (0)
89399 +
89400 +
89401 +/**************************************************************************//**
89402 + @Description Dumps a structure's members array.
89403 +
89404 + The input for this macro is the full reference for the members
89405 + array, where the structure is referenced using a pointer.
89406 +
89407 + If the members array is part of a sub-structure hierarchy,
89408 + the full hierarchy (including array indexing) must be specified.
89409 +
89410 + Examples: p_Struct->array
89411 + p_Struct->sub.array
89412 + p_Struct->sub[i].array
89413 +*//***************************************************************************/
89414 +#define DUMP_ARR(st, phrase) \
89415 + do { \
89416 + physAddress_t physAddr; \
89417 + _CREATE_DUMP_SUBSTR(phrase); \
89418 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89419 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89420 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89421 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89422 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89423 + } \
89424 + } while (0)
89425 +
89426 +
89427 +
89428 +#endif /* DEBUG_ERRORS > 0 */
89429 +
89430 +
89431 +/** @} */ /* end of dump_id group */
89432 +/** @} */ /* end of gen_id group */
89433 +
89434 +
89435 +#endif /* __DEBUG_EXT_H */
89436 +
89437 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89438 new file mode 100644
89439 index 00000000..5cdec668
89440 --- /dev/null
89441 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89442 @@ -0,0 +1,447 @@
89443 +/*
89444 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89445 + *
89446 + * Redistribution and use in source and binary forms, with or without
89447 + * modification, are permitted provided that the following conditions are met:
89448 + * * Redistributions of source code must retain the above copyright
89449 + * notice, this list of conditions and the following disclaimer.
89450 + * * Redistributions in binary form must reproduce the above copyright
89451 + * notice, this list of conditions and the following disclaimer in the
89452 + * documentation and/or other materials provided with the distribution.
89453 + * * Neither the name of Freescale Semiconductor nor the
89454 + * names of its contributors may be used to endorse or promote products
89455 + * derived from this software without specific prior written permission.
89456 + *
89457 + *
89458 + * ALTERNATIVELY, this software may be distributed under the terms of the
89459 + * GNU General Public License ("GPL") as published by the Free Software
89460 + * Foundation, either version 2 of that License or (at your option) any
89461 + * later version.
89462 + *
89463 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89464 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89466 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89467 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89468 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89469 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89470 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89471 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89472 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89473 + */
89474 +
89475 +
89476 +/**************************************************************************//**
89477 +
89478 + @File endian_ext.h
89479 +
89480 + @Description Big/little endian swapping routines.
89481 +*//***************************************************************************/
89482 +
89483 +#ifndef __ENDIAN_EXT_H
89484 +#define __ENDIAN_EXT_H
89485 +
89486 +#include "std_ext.h"
89487 +
89488 +
89489 +/**************************************************************************//**
89490 + @Group gen_id General Drivers Utilities
89491 +
89492 + @Description General usage API. This API is intended for usage by both the
89493 + internal modules and the user's application.
89494 +
89495 + @{
89496 +*//***************************************************************************/
89497 +
89498 +/**************************************************************************//**
89499 + @Group endian_id Big/Little-Endian Conversion
89500 +
89501 + @Description Routines and macros for Big/Little-Endian conversion and
89502 + general byte swapping.
89503 +
89504 + All routines and macros are expecting unsigned values as
89505 + parameters, but will generate the correct result also for
89506 + signed values. Therefore, signed/unsigned casting is allowed.
89507 + @{
89508 +*//***************************************************************************/
89509 +
89510 +/**************************************************************************//**
89511 + @Collection Byte-Swap Macros
89512 +
89513 + Macros for swapping byte order.
89514 +
89515 + @Cautions The parameters of these macros are evaluated multiple times.
89516 + For calculated expressions or expressions that contain function
89517 + calls it is recommended to use the byte-swap routines.
89518 +
89519 + @{
89520 +*//***************************************************************************/
89521 +
89522 +/**************************************************************************//**
89523 + @Description Swaps the byte order of a given 16-bit value.
89524 +
89525 + @Param[in] val - The 16-bit value to swap.
89526 +
89527 + @Return The byte-swapped value..
89528 +
89529 + @Cautions The given value is evaluated multiple times by this macro.
89530 + For calculated expressions or expressions that contain function
89531 + calls it is recommended to use the SwapUint16() routine.
89532 +
89533 + @hideinitializer
89534 +*//***************************************************************************/
89535 +#define SWAP_UINT16(val) \
89536 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89537 +
89538 +/**************************************************************************//**
89539 + @Description Swaps the byte order of a given 32-bit value.
89540 +
89541 + @Param[in] val - The 32-bit value to swap.
89542 +
89543 + @Return The byte-swapped value..
89544 +
89545 + @Cautions The given value is evaluated multiple times by this macro.
89546 + For calculated expressions or expressions that contain function
89547 + calls it is recommended to use the SwapUint32() routine.
89548 +
89549 + @hideinitializer
89550 +*//***************************************************************************/
89551 +#define SWAP_UINT32(val) \
89552 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89553 + (((val) & 0x0000FF00) << 8) | \
89554 + (((val) & 0x00FF0000) >> 8) | \
89555 + (((val) & 0xFF000000) >> 24)))
89556 +
89557 +/**************************************************************************//**
89558 + @Description Swaps the byte order of a given 64-bit value.
89559 +
89560 + @Param[in] val - The 64-bit value to swap.
89561 +
89562 + @Return The byte-swapped value..
89563 +
89564 + @Cautions The given value is evaluated multiple times by this macro.
89565 + For calculated expressions or expressions that contain function
89566 + calls it is recommended to use the SwapUint64() routine.
89567 +
89568 + @hideinitializer
89569 +*//***************************************************************************/
89570 +#define SWAP_UINT64(val) \
89571 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89572 + (((val) & 0x000000000000FF00ULL) << 40) | \
89573 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89574 + (((val) & 0x00000000FF000000ULL) << 8) | \
89575 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89576 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89577 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89578 + (((val) & 0xFF00000000000000ULL) >> 56)))
89579 +
89580 +/* @} */
89581 +
89582 +/**************************************************************************//**
89583 + @Collection Byte-Swap Routines
89584 +
89585 + Routines for swapping the byte order of a given parameter and
89586 + returning the swapped value.
89587 +
89588 + These inline routines are safer than the byte-swap macros,
89589 + because they evaluate the parameter expression only once.
89590 + @{
89591 +*//***************************************************************************/
89592 +
89593 +/**************************************************************************//**
89594 + @Function SwapUint16
89595 +
89596 + @Description Returns the byte-swapped value of a given 16-bit value.
89597 +
89598 + @Param[in] val - The 16-bit value.
89599 +
89600 + @Return The byte-swapped value of the parameter.
89601 +*//***************************************************************************/
89602 +static __inline__ uint16_t SwapUint16(uint16_t val)
89603 +{
89604 + return (uint16_t)(((val & 0x00FF) << 8) |
89605 + ((val & 0xFF00) >> 8));
89606 +}
89607 +
89608 +/**************************************************************************//**
89609 + @Function SwapUint32
89610 +
89611 + @Description Returns the byte-swapped value of a given 32-bit value.
89612 +
89613 + @Param[in] val - The 32-bit value.
89614 +
89615 + @Return The byte-swapped value of the parameter.
89616 +*//***************************************************************************/
89617 +static __inline__ uint32_t SwapUint32(uint32_t val)
89618 +{
89619 + return (uint32_t)(((val & 0x000000FF) << 24) |
89620 + ((val & 0x0000FF00) << 8) |
89621 + ((val & 0x00FF0000) >> 8) |
89622 + ((val & 0xFF000000) >> 24));
89623 +}
89624 +
89625 +/**************************************************************************//**
89626 + @Function SwapUint64
89627 +
89628 + @Description Returns the byte-swapped value of a given 64-bit value.
89629 +
89630 + @Param[in] val - The 64-bit value.
89631 +
89632 + @Return The byte-swapped value of the parameter.
89633 +*//***************************************************************************/
89634 +static __inline__ uint64_t SwapUint64(uint64_t val)
89635 +{
89636 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89637 + ((val & 0x000000000000FF00ULL) << 40) |
89638 + ((val & 0x0000000000FF0000ULL) << 24) |
89639 + ((val & 0x00000000FF000000ULL) << 8) |
89640 + ((val & 0x000000FF00000000ULL) >> 8) |
89641 + ((val & 0x0000FF0000000000ULL) >> 24) |
89642 + ((val & 0x00FF000000000000ULL) >> 40) |
89643 + ((val & 0xFF00000000000000ULL) >> 56));
89644 +}
89645 +
89646 +/* @} */
89647 +
89648 +/**************************************************************************//**
89649 + @Collection In-place Byte-Swap-And-Set Routines
89650 +
89651 + Routines for swapping the byte order of a given variable and
89652 + setting the swapped value back to the same variable.
89653 + @{
89654 +*//***************************************************************************/
89655 +
89656 +/**************************************************************************//**
89657 + @Function SwapUint16P
89658 +
89659 + @Description Swaps the byte order of a given 16-bit variable.
89660 +
89661 + @Param[in] p_Val - Pointer to the 16-bit variable.
89662 +
89663 + @Return None.
89664 +*//***************************************************************************/
89665 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89666 +{
89667 + *p_Val = SwapUint16(*p_Val);
89668 +}
89669 +
89670 +/**************************************************************************//**
89671 + @Function SwapUint32P
89672 +
89673 + @Description Swaps the byte order of a given 32-bit variable.
89674 +
89675 + @Param[in] p_Val - Pointer to the 32-bit variable.
89676 +
89677 + @Return None.
89678 +*//***************************************************************************/
89679 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89680 +{
89681 + *p_Val = SwapUint32(*p_Val);
89682 +}
89683 +
89684 +/**************************************************************************//**
89685 + @Function SwapUint64P
89686 +
89687 + @Description Swaps the byte order of a given 64-bit variable.
89688 +
89689 + @Param[in] p_Val - Pointer to the 64-bit variable.
89690 +
89691 + @Return None.
89692 +*//***************************************************************************/
89693 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89694 +{
89695 + *p_Val = SwapUint64(*p_Val);
89696 +}
89697 +
89698 +/* @} */
89699 +
89700 +
89701 +/**************************************************************************//**
89702 + @Collection Little-Endian Conversion Macros
89703 +
89704 + These macros convert given parameters to or from Little-Endian
89705 + format. Use these macros when you want to read or write a specific
89706 + Little-Endian value in memory, without a-priori knowing the CPU
89707 + byte order.
89708 +
89709 + These macros use the byte-swap routines. For conversion of
89710 + constants in initialization structures, you may use the CONST
89711 + versions of these macros (see below), which are using the
89712 + byte-swap macros instead.
89713 + @{
89714 +*//***************************************************************************/
89715 +
89716 +/**************************************************************************//**
89717 + @Description Converts a given 16-bit value from CPU byte order to
89718 + Little-Endian byte order.
89719 +
89720 + @Param[in] val - The 16-bit value to convert.
89721 +
89722 + @Return The converted value.
89723 +
89724 + @hideinitializer
89725 +*//***************************************************************************/
89726 +#define CPU_TO_LE16(val) SwapUint16(val)
89727 +
89728 +/**************************************************************************//**
89729 + @Description Converts a given 32-bit value from CPU byte order to
89730 + Little-Endian byte order.
89731 +
89732 + @Param[in] val - The 32-bit value to convert.
89733 +
89734 + @Return The converted value.
89735 +
89736 + @hideinitializer
89737 +*//***************************************************************************/
89738 +#define CPU_TO_LE32(val) SwapUint32(val)
89739 +
89740 +/**************************************************************************//**
89741 + @Description Converts a given 64-bit value from CPU byte order to
89742 + Little-Endian byte order.
89743 +
89744 + @Param[in] val - The 64-bit value to convert.
89745 +
89746 + @Return The converted value.
89747 +
89748 + @hideinitializer
89749 +*//***************************************************************************/
89750 +#define CPU_TO_LE64(val) SwapUint64(val)
89751 +
89752 +
89753 +/**************************************************************************//**
89754 + @Description Converts a given 16-bit value from Little-Endian byte order to
89755 + CPU byte order.
89756 +
89757 + @Param[in] val - The 16-bit value to convert.
89758 +
89759 + @Return The converted value.
89760 +
89761 + @hideinitializer
89762 +*//***************************************************************************/
89763 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89764 +
89765 +/**************************************************************************//**
89766 + @Description Converts a given 32-bit value from Little-Endian byte order to
89767 + CPU byte order.
89768 +
89769 + @Param[in] val - The 32-bit value to convert.
89770 +
89771 + @Return The converted value.
89772 +
89773 + @hideinitializer
89774 +*//***************************************************************************/
89775 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89776 +
89777 +/**************************************************************************//**
89778 + @Description Converts a given 64-bit value from Little-Endian byte order to
89779 + CPU byte order.
89780 +
89781 + @Param[in] val - The 64-bit value to convert.
89782 +
89783 + @Return The converted value.
89784 +
89785 + @hideinitializer
89786 +*//***************************************************************************/
89787 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89788 +
89789 +/* @} */
89790 +
89791 +/**************************************************************************//**
89792 + @Collection Little-Endian Constant Conversion Macros
89793 +
89794 + These macros convert given constants to or from Little-Endian
89795 + format. Use these macros when you want to read or write a specific
89796 + Little-Endian constant in memory, without a-priori knowing the
89797 + CPU byte order.
89798 +
89799 + These macros use the byte-swap macros, therefore can be used for
89800 + conversion of constants in initialization structures.
89801 +
89802 + @Cautions The parameters of these macros are evaluated multiple times.
89803 + For non-constant expressions, use the non-CONST macro versions.
89804 +
89805 + @{
89806 +*//***************************************************************************/
89807 +
89808 +/**************************************************************************//**
89809 + @Description Converts a given 16-bit constant from CPU byte order to
89810 + Little-Endian byte order.
89811 +
89812 + @Param[in] val - The 16-bit value to convert.
89813 +
89814 + @Return The converted value.
89815 +
89816 + @hideinitializer
89817 +*//***************************************************************************/
89818 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89819 +
89820 +/**************************************************************************//**
89821 + @Description Converts a given 32-bit constant from CPU byte order to
89822 + Little-Endian byte order.
89823 +
89824 + @Param[in] val - The 32-bit value to convert.
89825 +
89826 + @Return The converted value.
89827 +
89828 + @hideinitializer
89829 +*//***************************************************************************/
89830 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89831 +
89832 +/**************************************************************************//**
89833 + @Description Converts a given 64-bit constant from CPU byte order to
89834 + Little-Endian byte order.
89835 +
89836 + @Param[in] val - The 64-bit value to convert.
89837 +
89838 + @Return The converted value.
89839 +
89840 + @hideinitializer
89841 +*//***************************************************************************/
89842 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89843 +
89844 +
89845 +/**************************************************************************//**
89846 + @Description Converts a given 16-bit constant from Little-Endian byte order
89847 + to CPU byte order.
89848 +
89849 + @Param[in] val - The 16-bit value to convert.
89850 +
89851 + @Return The converted value.
89852 +
89853 + @hideinitializer
89854 +*//***************************************************************************/
89855 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
89856 +
89857 +/**************************************************************************//**
89858 + @Description Converts a given 32-bit constant from Little-Endian byte order
89859 + to CPU byte order.
89860 +
89861 + @Param[in] val - The 32-bit value to convert.
89862 +
89863 + @Return The converted value.
89864 +
89865 + @hideinitializer
89866 +*//***************************************************************************/
89867 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
89868 +
89869 +/**************************************************************************//**
89870 + @Description Converts a given 64-bit constant from Little-Endian byte order
89871 + to CPU byte order.
89872 +
89873 + @Param[in] val - The 64-bit value to convert.
89874 +
89875 + @Return The converted value.
89876 +
89877 + @hideinitializer
89878 +*//***************************************************************************/
89879 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
89880 +
89881 +/* @} */
89882 +
89883 +
89884 +/** @} */ /* end of endian_id group */
89885 +/** @} */ /* end of gen_id group */
89886 +
89887 +
89888 +#endif /* __ENDIAN_EXT_H */
89889 +
89890 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89891 new file mode 100644
89892 index 00000000..ef3bee55
89893 --- /dev/null
89894 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89895 @@ -0,0 +1,205 @@
89896 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89897 + * All rights reserved.
89898 + *
89899 + * Redistribution and use in source and binary forms, with or without
89900 + * modification, are permitted provided that the following conditions are met:
89901 + * * Redistributions of source code must retain the above copyright
89902 + * notice, this list of conditions and the following disclaimer.
89903 + * * Redistributions in binary form must reproduce the above copyright
89904 + * notice, this list of conditions and the following disclaimer in the
89905 + * documentation and/or other materials provided with the distribution.
89906 + * * Neither the name of Freescale Semiconductor nor the
89907 + * names of its contributors may be used to endorse or promote products
89908 + * derived from this software without specific prior written permission.
89909 + *
89910 + *
89911 + * ALTERNATIVELY, this software may be distributed under the terms of the
89912 + * GNU General Public License ("GPL") as published by the Free Software
89913 + * Foundation, either version 2 of that License or (at your option) any
89914 + * later version.
89915 + *
89916 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89917 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89918 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89919 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89920 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89921 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89922 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89923 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89924 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89925 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89926 + */
89927 +
89928 +
89929 +/**************************************************************************//**
89930 + @File enet_ext.h
89931 +
89932 + @Description Ethernet generic definitions and enums.
89933 +*//***************************************************************************/
89934 +
89935 +#ifndef __ENET_EXT_H
89936 +#define __ENET_EXT_H
89937 +
89938 +#include "fsl_enet.h"
89939 +
89940 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
89941 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
89942 +
89943 +
89944 +/**************************************************************************//**
89945 + @Description Ethernet Address
89946 +*//***************************************************************************/
89947 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
89948 +
89949 +/**************************************************************************//**
89950 + @Description Ethernet Address Type.
89951 +*//***************************************************************************/
89952 +typedef enum e_EnetAddrType
89953 +{
89954 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
89955 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
89956 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
89957 +} e_EnetAddrType;
89958 +
89959 +/**************************************************************************//**
89960 + @Description Ethernet MAC-PHY Interface
89961 +*//***************************************************************************/
89962 +typedef enum e_EnetInterface
89963 +{
89964 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
89965 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
89966 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
89967 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
89968 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
89969 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
89970 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
89971 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
89972 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
89973 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
89974 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
89975 +} e_EnetInterface;
89976 +
89977 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
89978 + auto-negotiation between MAC and phy
89979 + or backplane;
89980 + Note: 1000BaseX auto-negotiation relates
89981 + only to interface between MAC and phy/backplane,
89982 + SGMII phy can still synchronize with far-end phy
89983 + at 10Mbps, 100Mbps or 1000Mbps */
89984 +
89985 +/**************************************************************************//**
89986 + @Description Ethernet Duplex Mode
89987 +*//***************************************************************************/
89988 +typedef enum e_EnetDuplexMode
89989 +{
89990 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
89991 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
89992 +} e_EnetDuplexMode;
89993 +
89994 +/**************************************************************************//**
89995 + @Description Ethernet Speed (nominal data rate)
89996 +*//***************************************************************************/
89997 +typedef enum e_EnetSpeed
89998 +{
89999 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
90000 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
90001 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
90002 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
90003 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
90004 +} e_EnetSpeed;
90005 +
90006 +/**************************************************************************//**
90007 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
90008 +*//***************************************************************************/
90009 +typedef enum e_EnetMode
90010 +{
90011 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
90012 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
90013 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
90014 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
90015 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
90016 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
90017 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
90018 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
90019 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
90020 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
90021 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
90022 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
90023 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
90024 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
90025 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
90026 + SGMII phy according to Cisco SGMII specification */
90027 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
90028 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
90029 + SGMII phy according to Cisco SGMII specification */
90030 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90031 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
90032 + SGMII phy according to Cisco SGMII specification */
90033 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
90034 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
90035 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
90036 + MAC and SGMII phy or backplane */
90037 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
90038 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
90039 + MAC and SGMII phy or backplane */
90040 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90041 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
90042 + MAC and SGMII phy or backplane */
90043 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90044 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
90045 + QSGMII phy according to Cisco QSGMII specification */
90046 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90047 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
90048 + MAC and QSGMII phy or backplane */
90049 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
90050 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
90051 +} e_EnetMode;
90052 +
90053 +
90054 +#define IS_ENET_MODE_VALID(mode) \
90055 + (((mode) == e_ENET_MODE_MII_10 ) || \
90056 + ((mode) == e_ENET_MODE_MII_100 ) || \
90057 + ((mode) == e_ENET_MODE_RMII_10 ) || \
90058 + ((mode) == e_ENET_MODE_RMII_100 ) || \
90059 + ((mode) == e_ENET_MODE_SMII_10 ) || \
90060 + ((mode) == e_ENET_MODE_SMII_100 ) || \
90061 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
90062 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
90063 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
90064 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
90065 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
90066 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
90067 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
90068 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
90069 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
90070 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
90071 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
90072 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
90073 + ((mode) == e_ENET_MODE_XGMII_10000) || \
90074 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
90075 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
90076 + ((mode) == e_ENET_MODE_XFI_10000))
90077 +
90078 +
90079 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
90080 +
90081 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
90082 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
90083 +
90084 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
90085 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
90086 + ((uint64_t)(_enetAddr)[1] << 32) | \
90087 + ((uint64_t)(_enetAddr)[2] << 24) | \
90088 + ((uint64_t)(_enetAddr)[3] << 16) | \
90089 + ((uint64_t)(_enetAddr)[4] << 8) | \
90090 + ((uint64_t)(_enetAddr)[5]))
90091 +
90092 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
90093 + do { \
90094 + int i; \
90095 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
90096 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
90097 + } while (0)
90098 +
90099 +
90100 +#endif /* __ENET_EXT_H */
90101 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
90102 new file mode 100644
90103 index 00000000..2a5ad67b
90104 --- /dev/null
90105 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
90106 @@ -0,0 +1,529 @@
90107 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90108 + * All rights reserved.
90109 + *
90110 + * Redistribution and use in source and binary forms, with or without
90111 + * modification, are permitted provided that the following conditions are met:
90112 + * * Redistributions of source code must retain the above copyright
90113 + * notice, this list of conditions and the following disclaimer.
90114 + * * Redistributions in binary form must reproduce the above copyright
90115 + * notice, this list of conditions and the following disclaimer in the
90116 + * documentation and/or other materials provided with the distribution.
90117 + * * Neither the name of Freescale Semiconductor nor the
90118 + * names of its contributors may be used to endorse or promote products
90119 + * derived from this software without specific prior written permission.
90120 + *
90121 + *
90122 + * ALTERNATIVELY, this software may be distributed under the terms of the
90123 + * GNU General Public License ("GPL") as published by the Free Software
90124 + * Foundation, either version 2 of that License or (at your option) any
90125 + * later version.
90126 + *
90127 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90128 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90129 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90130 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90131 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90132 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90133 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90134 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90135 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90136 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90137 + */
90138 +
90139 +
90140 +/**************************************************************************//**
90141 + @File error_ext.h
90142 +
90143 + @Description Error definitions.
90144 +*//***************************************************************************/
90145 +
90146 +#ifndef __ERROR_EXT_H
90147 +#define __ERROR_EXT_H
90148 +
90149 +#if !defined(NCSW_LINUX)
90150 +#include <errno.h>
90151 +#endif
90152 +
90153 +#include "std_ext.h"
90154 +#include "xx_ext.h"
90155 +#include "core_ext.h"
90156 +
90157 +
90158 +
90159 +
90160 +/**************************************************************************//**
90161 + @Group gen_id General Drivers Utilities
90162 +
90163 + @Description External routines.
90164 +
90165 + @{
90166 +*//***************************************************************************/
90167 +
90168 +/**************************************************************************//**
90169 + @Group gen_error_id Errors, Events and Debug
90170 +
90171 + @Description External routines.
90172 +
90173 + @{
90174 +*//***************************************************************************/
90175 +
90176 +/******************************************************************************
90177 +The scheme below provides the bits description for error codes:
90178 +
90179 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
90180 +| Reserved (should be zero) | Module ID |
90181 +
90182 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
90183 +| Error Type |
90184 +******************************************************************************/
90185 +
90186 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
90187 +
90188 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
90189 + /**< Extract module code from error code (#t_Error) */
90190 +
90191 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
90192 + /**< Extract error type (#e_ErrorType) from
90193 + error code (#t_Error) */
90194 +
90195 +
90196 +/**************************************************************************//**
90197 + @Description Error Type Enumeration
90198 +*//***************************************************************************/
90199 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
90200 +{ /* ------------------------------------------------------------ */
90201 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
90202 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
90203 + /* String: none, or device name. */
90204 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
90205 + /* String: none. */
90206 + ,E_NOT_AVAILABLE = EAGAIN
90207 + /**< Resource is unavailable. */
90208 + /* String: none, unless the operation is not the main goal
90209 + of the function (in this case add resource description). */
90210 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
90211 + /* String: description of item for which allocation failed. */
90212 + ,E_INVALID_ADDRESS = EFAULT
90213 + /**< Invalid address. */
90214 + /* String: description of the specific violation. */
90215 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
90216 + /* String: none, unless the operation is not the main goal
90217 + of the function (in this case add resource description). */
90218 + ,E_ALREADY_EXISTS = EEXIST
90219 + /**< Requested resource or item already exists. */
90220 + /* Use when resource duplication or sharing are not allowed.
90221 + String: none, unless the operation is not the main goal
90222 + of the function (in this case add item description). */
90223 + ,E_INVALID_OPERATION = ENODEV
90224 + /**< The operation/command is invalid (unrecognized). */
90225 + /* String: none. */
90226 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
90227 + /* Use for non-enumeration parameters, and
90228 + only when other error types are not suitable.
90229 + String: parameter description + "(should be <attribute>)",
90230 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
90231 + "Channel number (should be even)". */
90232 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
90233 + /* Don't use this error for enumeration parameters.
90234 + String: parameter description + "(should be %d-%d)",
90235 + e.g: "Number of pad characters (should be 0-15)". */
90236 + ,E_NOT_SUPPORTED = ENOSYS
90237 + /**< The function is not supported or not implemented. */
90238 + /* String: none. */
90239 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
90240 + /* String: none. */
90241 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
90242 + /* String: none, unless the function takes in more than one
90243 + handle (in this case add the handle description) */
90244 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
90245 + /* String: none, unless the function takes in more than one
90246 + ID (in this case add the ID description) */
90247 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
90248 + /* String: pointer description. */
90249 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
90250 + /* Use for enumeration values, only when other error types
90251 + are not suitable.
90252 + String: parameter description. */
90253 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
90254 + /* String: none, unless the function takes in more than one
90255 + communication mode indications (in this case add
90256 + parameter description). */
90257 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
90258 + /* String: none, unless the function takes in more than one
90259 + memory types (in this case add memory description,
90260 + e.g: "Data memory", "Buffer descriptors memory"). */
90261 + ,E_INVALID_CLOCK /**< Invalid clock. */
90262 + /* String: none, unless the function takes in more than one
90263 + clocks (in this case add clock description,
90264 + e.g: "Rx clock", "Tx clock"). */
90265 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
90266 + /* String: description of the conflicting settings. */
90267 + ,E_NOT_ALIGNED /**< Non-aligned address. */
90268 + /* String: parameter description + "(should be %d-bytes aligned)",
90269 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
90270 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
90271 + /* Use only when the resource/item is uniquely identified.
90272 + String: none, unless the operation is not the main goal
90273 + of the function (in this case add item description). */
90274 + ,E_FULL /**< Resource is full. */
90275 + /* String: none, unless the operation is not the main goal
90276 + of the function (in this case add resource description). */
90277 + ,E_EMPTY /**< Resource is empty. */
90278 + /* String: none, unless the operation is not the main goal
90279 + of the function (in this case add resource description). */
90280 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
90281 + /* String: none, unless the operation is not the main goal
90282 + of the function (in this case add item description). */
90283 + ,E_READ_FAILED /**< Read access failed on memory/device. */
90284 + /* String: none, or device name. */
90285 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
90286 + /* String: none. */
90287 + ,E_SEND_FAILED /**< Send operation failed on device. */
90288 + /* String: none, or device name. */
90289 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
90290 + /* String: none, or device name. */
90291 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
90292 + /* String: none. */
90293 +
90294 + ,E_DUMMY_LAST /* NEVER USED */
90295 +
90296 +} e_ErrorType;
90297 +
90298 +/**************************************************************************//**
90299 + @Description Event Type Enumeration
90300 +*//***************************************************************************/
90301 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
90302 +{ /* ------------------------------------------------------------ */
90303 + EV_NO_EVENT = 0 /**< No event; Never used. */
90304 +
90305 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
90306 + complete packets);
90307 + Flags: error flags in case of error, zero otherwise. */
90308 + /* String: reason for discard, e.g: "Error in frame",
90309 + "Disordered frame", "Incomplete frame", "No frame object". */
90310 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
90311 + Flags: usually status flags from the buffer descriptor. */
90312 + /* String: none. */
90313 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
90314 + Flags: usually status flags from the buffer descriptor. */
90315 + /* String: none. */
90316 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
90317 + Flags: zero. */
90318 + /* String: none. */
90319 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
90320 + Flags: zero. */
90321 + /* String: none. */
90322 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
90323 + Flags: zero. */
90324 + /* String: none. */
90325 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
90326 + Flags: zero. */
90327 + /* String: none. */
90328 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
90329 + Flags: zero. */
90330 + /* String: none. */
90331 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
90332 + Flags: zero. */
90333 + /* String: none. */
90334 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
90335 + Flags: zero. */
90336 + /* String: none. */
90337 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
90338 + Flags: zero. */
90339 + /* String: object description (name). */
90340 + ,EV_BUS_ERROR /**< Illegal access on bus;
90341 + Flags: the address (if available) or bus identifier */
90342 + /* String: bus/address/module description. */
90343 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
90344 + Flags: zero. */
90345 + /* String: none. */
90346 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
90347 + Flags: zero. */
90348 + /* String: none. */
90349 + ,EV_DUMMY_LAST
90350 +
90351 +} e_Event;
90352 +
90353 +
90354 +/**************************************************************************//**
90355 + @Collection Debug Levels for Errors and Events
90356 +
90357 + The level description refers to errors only.
90358 + For events, classification is done by the user.
90359 +
90360 + The TRACE, INFO and WARNING levels are allowed only when using
90361 + the DBG macro, and are not allowed when using the error macros
90362 + (RETURN_ERROR or REPORT_ERROR).
90363 + @{
90364 +*//***************************************************************************/
90365 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
90366 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
90367 + configuration. */
90368 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
90369 + parameters may be successful. */
90370 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
90371 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
90372 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
90373 +
90374 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
90375 +
90376 +/* @} */
90377 +
90378 +
90379 +
90380 +#define NO_MSG ("")
90381 +
90382 +#ifndef DEBUG_GLOBAL_LEVEL
90383 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
90384 +#endif /* DEBUG_GLOBAL_LEVEL */
90385 +
90386 +#ifndef ERROR_GLOBAL_LEVEL
90387 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
90388 +#endif /* ERROR_GLOBAL_LEVEL */
90389 +
90390 +#ifndef EVENT_GLOBAL_LEVEL
90391 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90392 +#endif /* EVENT_GLOBAL_LEVEL */
90393 +
90394 +#ifdef EVENT_LOCAL_LEVEL
90395 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90396 +#else
90397 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90398 +#endif /* EVENT_LOCAL_LEVEL */
90399 +
90400 +
90401 +#ifndef DEBUG_DYNAMIC_LEVEL
90402 +#define DEBUG_USING_STATIC_LEVEL
90403 +
90404 +#ifdef DEBUG_STATIC_LEVEL
90405 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90406 +#else
90407 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90408 +#endif /* DEBUG_STATIC_LEVEL */
90409 +
90410 +#else /* DEBUG_DYNAMIC_LEVEL */
90411 +#ifdef DEBUG_STATIC_LEVEL
90412 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90413 +#else
90414 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90415 +#endif /* DEBUG_STATIC_LEVEL */
90416 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90417 +
90418 +
90419 +#ifndef ERROR_DYNAMIC_LEVEL
90420 +
90421 +#ifdef ERROR_STATIC_LEVEL
90422 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90423 +#else
90424 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90425 +#endif /* ERROR_STATIC_LEVEL */
90426 +
90427 +#else /* ERROR_DYNAMIC_LEVEL */
90428 +#ifdef ERROR_STATIC_LEVEL
90429 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90430 +#else
90431 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90432 +#endif /* ERROR_STATIC_LEVEL */
90433 +#endif /* !ERROR_DYNAMIC_LEVEL */
90434 +
90435 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90436 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90437 +
90438 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90439 +/* No debug/error/event messages at all */
90440 +#define DBG(_level, _vmsg)
90441 +
90442 +#define REPORT_ERROR(_level, _err, _vmsg)
90443 +
90444 +#define RETURN_ERROR(_level, _err, _vmsg) \
90445 + return ERROR_CODE(_err)
90446 +
90447 +#if (REPORT_EVENTS > 0)
90448 +
90449 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90450 + do { \
90451 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90452 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90453 + } \
90454 + } while (0)
90455 +
90456 +#else
90457 +
90458 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90459 +
90460 +#endif /* (REPORT_EVENTS > 0) */
90461 +
90462 +
90463 +#else /* DEBUG_ERRORS > 0 */
90464 +
90465 +extern const char *dbgLevelStrings[];
90466 +extern const char *moduleStrings[];
90467 +#if (REPORT_EVENTS > 0)
90468 +extern const char *eventStrings[];
90469 +#endif /* (REPORT_EVENTS > 0) */
90470 +
90471 +char * ErrTypeStrings (e_ErrorType err);
90472 +
90473 +
90474 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90475 +/* No need for DBG macro - debug level is higher anyway */
90476 +#define DBG(_level, _vmsg)
90477 +#else
90478 +#define DBG(_level, _vmsg) \
90479 + do { \
90480 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90481 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90482 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90483 + moduleStrings[__ERR_MODULE__ >> 16], \
90484 + PRINT_FMT_PARAMS); \
90485 + XX_Print _vmsg; \
90486 + XX_Print("\r\n"); \
90487 + } \
90488 + } while (0)
90489 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90490 +
90491 +
90492 +#define REPORT_ERROR(_level, _err, _vmsg) \
90493 + do { \
90494 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90495 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90496 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90497 + moduleStrings[__ERR_MODULE__ >> 16], \
90498 + PRINT_FMT_PARAMS, \
90499 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90500 + XX_Print _vmsg; \
90501 + XX_Print("\r\n"); \
90502 + } \
90503 + } while (0)
90504 +
90505 +
90506 +#define RETURN_ERROR(_level, _err, _vmsg) \
90507 + do { \
90508 + REPORT_ERROR(_level, (_err), _vmsg); \
90509 + return ERROR_CODE(_err); \
90510 + } while (0)
90511 +
90512 +
90513 +#if (REPORT_EVENTS > 0)
90514 +
90515 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90516 + do { \
90517 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90518 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90519 + dbgLevelStrings[_ev##_LEVEL - 1], \
90520 + moduleStrings[__ERR_MODULE__ >> 16], \
90521 + PRINT_FMT_PARAMS, \
90522 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90523 + (uint16_t)(_flg)); \
90524 + XX_Print _vmsg; \
90525 + XX_Print("\r\n"); \
90526 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90527 + } \
90528 + } while (0)
90529 +
90530 +#else /* not REPORT_EVENTS */
90531 +
90532 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90533 +
90534 +#endif /* (REPORT_EVENTS > 0) */
90535 +
90536 +#endif /* (DEBUG_ERRORS > 0) */
90537 +
90538 +
90539 +/**************************************************************************//**
90540 + @Function ASSERT_COND
90541 +
90542 + @Description Assertion macro.
90543 +
90544 + @Param[in] _cond - The condition being checked, in positive form;
90545 + Failure of the condition triggers the assert.
90546 +*//***************************************************************************/
90547 +#ifdef DISABLE_ASSERTIONS
90548 +#define ASSERT_COND(_cond)
90549 +#else
90550 +#define ASSERT_COND(_cond) \
90551 + do { \
90552 + if (!(_cond)) { \
90553 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90554 + PRINT_FMT_PARAMS); \
90555 + XX_Exit(1); \
90556 + } \
90557 + } while (0)
90558 +#endif /* DISABLE_ASSERTIONS */
90559 +
90560 +
90561 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90562 +
90563 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90564 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90565 +
90566 +#else
90567 +
90568 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90569 + do { \
90570 + t_Error err = f_check(handle); \
90571 + if (err != E_OK) { \
90572 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90573 + } \
90574 + } while (0)
90575 +
90576 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90577 + do { \
90578 + t_Error err = f_check(handle); \
90579 + if (err != E_OK) { \
90580 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90581 + return (retval); \
90582 + } \
90583 + } while (0)
90584 +
90585 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90586 +
90587 +#ifdef DISABLE_SANITY_CHECKS
90588 +
90589 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90590 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90591 +#define SANITY_CHECK_RETURN(_cond, _err)
90592 +#define SANITY_CHECK_EXIT(_cond, _err)
90593 +
90594 +#else /* DISABLE_SANITY_CHECKS */
90595 +
90596 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90597 + do { \
90598 + if (!(_cond)) { \
90599 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90600 + } \
90601 + } while (0)
90602 +
90603 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90604 + do { \
90605 + if (!(_cond)) { \
90606 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90607 + return (retval); \
90608 + } \
90609 + } while (0)
90610 +
90611 +#define SANITY_CHECK_RETURN(_cond, _err) \
90612 + do { \
90613 + if (!(_cond)) { \
90614 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90615 + return; \
90616 + } \
90617 + } while (0)
90618 +
90619 +#define SANITY_CHECK_EXIT(_cond, _err) \
90620 + do { \
90621 + if (!(_cond)) { \
90622 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90623 + XX_Exit(1); \
90624 + } \
90625 + } while (0)
90626 +
90627 +#endif /* DISABLE_SANITY_CHECKS */
90628 +
90629 +/** @} */ /* end of Debug/error Utils group */
90630 +
90631 +/** @} */ /* end of General Utils group */
90632 +
90633 +#endif /* __ERROR_EXT_H */
90634 +
90635 +
90636 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90637 new file mode 100644
90638 index 00000000..ee6b9f29
90639 --- /dev/null
90640 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90641 @@ -0,0 +1,358 @@
90642 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90643 + * All rights reserved.
90644 + *
90645 + * Redistribution and use in source and binary forms, with or without
90646 + * modification, are permitted provided that the following conditions are met:
90647 + * * Redistributions of source code must retain the above copyright
90648 + * notice, this list of conditions and the following disclaimer.
90649 + * * Redistributions in binary form must reproduce the above copyright
90650 + * notice, this list of conditions and the following disclaimer in the
90651 + * documentation and/or other materials provided with the distribution.
90652 + * * Neither the name of Freescale Semiconductor nor the
90653 + * names of its contributors may be used to endorse or promote products
90654 + * derived from this software without specific prior written permission.
90655 + *
90656 + *
90657 + * ALTERNATIVELY, this software may be distributed under the terms of the
90658 + * GNU General Public License ("GPL") as published by the Free Software
90659 + * Foundation, either version 2 of that License or (at your option) any
90660 + * later version.
90661 + *
90662 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90663 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90664 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90665 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90666 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90667 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90668 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90669 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90670 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90671 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90672 + */
90673 +
90674 +
90675 +/**************************************************************************//**
90676 +
90677 + @File list_ext.h
90678 +
90679 + @Description External prototypes for list.c
90680 +*//***************************************************************************/
90681 +
90682 +#ifndef __LIST_EXT_H
90683 +#define __LIST_EXT_H
90684 +
90685 +
90686 +#include "std_ext.h"
90687 +
90688 +
90689 +/**************************************************************************//**
90690 + @Group etc_id Utility Library Application Programming Interface
90691 +
90692 + @Description External routines.
90693 +
90694 + @{
90695 +*//***************************************************************************/
90696 +
90697 +/**************************************************************************//**
90698 + @Group list_id List
90699 +
90700 + @Description List module functions,definitions and enums.
90701 +
90702 + @{
90703 +*//***************************************************************************/
90704 +
90705 +/**************************************************************************//**
90706 + @Description List structure.
90707 +*//***************************************************************************/
90708 +typedef struct List
90709 +{
90710 + struct List *p_Next; /**< A pointer to the next list object */
90711 + struct List *p_Prev; /**< A pointer to the previous list object */
90712 +} t_List;
90713 +
90714 +
90715 +/**************************************************************************//**
90716 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90717 +
90718 + @Description Macro to get first/last/next/previous entry in a list.
90719 +
90720 + @Param[in] p_List - A pointer to a list.
90721 +*//***************************************************************************/
90722 +#define LIST_FIRST(p_List) (p_List)->p_Next
90723 +#define LIST_LAST(p_List) (p_List)->p_Prev
90724 +#define LIST_NEXT LIST_FIRST
90725 +#define LIST_PREV LIST_LAST
90726 +
90727 +
90728 +/**************************************************************************//**
90729 + @Function LIST_INIT
90730 +
90731 + @Description Macro for initialization of a list struct.
90732 +
90733 + @Param[in] lst - The t_List object to initialize.
90734 +*//***************************************************************************/
90735 +#define LIST_INIT(lst) {&(lst), &(lst)}
90736 +
90737 +
90738 +/**************************************************************************//**
90739 + @Function LIST
90740 +
90741 + @Description Macro to declare of a list.
90742 +
90743 + @Param[in] listName - The list object name.
90744 +*//***************************************************************************/
90745 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90746 +
90747 +
90748 +/**************************************************************************//**
90749 + @Function INIT_LIST
90750 +
90751 + @Description Macro to initialize a list pointer.
90752 +
90753 + @Param[in] p_List - The list pointer.
90754 +*//***************************************************************************/
90755 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90756 +
90757 +
90758 +/**************************************************************************//**
90759 + @Function LIST_OBJECT
90760 +
90761 + @Description Macro to get the struct (object) for this entry.
90762 +
90763 + @Param[in] type - The type of the struct (object) this list is embedded in.
90764 + @Param[in] member - The name of the t_List object within the struct.
90765 +
90766 + @Return The structure pointer for this entry.
90767 +*//***************************************************************************/
90768 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90769 +#define LIST_OBJECT(p_List, type, member) \
90770 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90771 +
90772 +
90773 +/**************************************************************************//**
90774 + @Function LIST_FOR_EACH
90775 +
90776 + @Description Macro to iterate over a list.
90777 +
90778 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90779 + @Param[in] p_Head - A pointer to the head for your list pointer.
90780 +
90781 + @Cautions You can't delete items with this routine.
90782 + For deletion use LIST_FOR_EACH_SAFE().
90783 +*//***************************************************************************/
90784 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90785 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90786 +
90787 +
90788 +/**************************************************************************//**
90789 + @Function LIST_FOR_EACH_SAFE
90790 +
90791 + @Description Macro to iterate over a list safe against removal of list entry.
90792 +
90793 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90794 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90795 + @Param[in] p_Head - A pointer to the head for your list pointer.
90796 +*//***************************************************************************/
90797 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90798 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90799 + p_Pos != (p_Head); \
90800 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90801 +
90802 +
90803 +/**************************************************************************//**
90804 + @Function LIST_FOR_EACH_OBJECT_SAFE
90805 +
90806 + @Description Macro to iterate over list of given type safely.
90807 +
90808 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90809 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90810 + @Param[in] type - The type of the struct this is embedded in.
90811 + @Param[in] p_Head - A pointer to the head for your list pointer.
90812 + @Param[in] member - The name of the list_struct within the struct.
90813 +
90814 + @Cautions You can't delete items with this routine.
90815 + For deletion use LIST_FOR_EACH_SAFE().
90816 +*//***************************************************************************/
90817 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90818 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90819 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90820 + &p_Pos->member != (p_Head); \
90821 + p_Pos = p_Tmp, \
90822 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90823 +
90824 +/**************************************************************************//**
90825 + @Function LIST_FOR_EACH_OBJECT
90826 +
90827 + @Description Macro to iterate over list of given type.
90828 +
90829 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90830 + @Param[in] type - The type of the struct this is embedded in.
90831 + @Param[in] p_Head - A pointer to the head for your list pointer.
90832 + @Param[in] member - The name of the list_struct within the struct.
90833 +
90834 + @Cautions You can't delete items with this routine.
90835 + For deletion use LIST_FOR_EACH_SAFE().
90836 +*//***************************************************************************/
90837 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90838 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90839 + &p_Pos->member != (p_Head); \
90840 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90841 +
90842 +
90843 +/**************************************************************************//**
90844 + @Function LIST_Add
90845 +
90846 + @Description Add a new entry to a list.
90847 +
90848 + Insert a new entry after the specified head.
90849 + This is good for implementing stacks.
90850 +
90851 + @Param[in] p_New - A pointer to a new list entry to be added.
90852 + @Param[in] p_Head - A pointer to a list head to add it after.
90853 +
90854 + @Return none.
90855 +*//***************************************************************************/
90856 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
90857 +{
90858 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
90859 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
90860 + LIST_PREV(p_New) = p_Head;
90861 + LIST_NEXT(p_Head) = p_New;
90862 +}
90863 +
90864 +
90865 +/**************************************************************************//**
90866 + @Function LIST_AddToTail
90867 +
90868 + @Description Add a new entry to a list.
90869 +
90870 + Insert a new entry before the specified head.
90871 + This is useful for implementing queues.
90872 +
90873 + @Param[in] p_New - A pointer to a new list entry to be added.
90874 + @Param[in] p_Head - A pointer to a list head to add it before.
90875 +
90876 + @Return none.
90877 +*//***************************************************************************/
90878 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
90879 +{
90880 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
90881 + LIST_PREV(p_New) = LIST_PREV(p_Head);
90882 + LIST_NEXT(p_New) = p_Head;
90883 + LIST_PREV(p_Head) = p_New;
90884 +}
90885 +
90886 +
90887 +/**************************************************************************//**
90888 + @Function LIST_Del
90889 +
90890 + @Description Deletes entry from a list.
90891 +
90892 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90893 +
90894 + @Return none.
90895 +
90896 + @Cautions LIST_IsEmpty() on entry does not return true after this,
90897 + the entry is in an undefined state.
90898 +*//***************************************************************************/
90899 +static __inline__ void LIST_Del(t_List *p_Entry)
90900 +{
90901 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
90902 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
90903 +}
90904 +
90905 +
90906 +/**************************************************************************//**
90907 + @Function LIST_DelAndInit
90908 +
90909 + @Description Deletes entry from list and reinitialize it.
90910 +
90911 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90912 +
90913 + @Return none.
90914 +*//***************************************************************************/
90915 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
90916 +{
90917 + LIST_Del(p_Entry);
90918 + INIT_LIST(p_Entry);
90919 +}
90920 +
90921 +
90922 +/**************************************************************************//**
90923 + @Function LIST_Move
90924 +
90925 + @Description Delete from one list and add as another's head.
90926 +
90927 + @Param[in] p_Entry - A pointer to the list entry to move.
90928 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
90929 +
90930 + @Return none.
90931 +*//***************************************************************************/
90932 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
90933 +{
90934 + LIST_Del(p_Entry);
90935 + LIST_Add(p_Entry, p_Head);
90936 +}
90937 +
90938 +
90939 +/**************************************************************************//**
90940 + @Function LIST_MoveToTail
90941 +
90942 + @Description Delete from one list and add as another's tail.
90943 +
90944 + @Param[in] p_Entry - A pointer to the entry to move.
90945 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
90946 +
90947 + @Return none.
90948 +*//***************************************************************************/
90949 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
90950 +{
90951 + LIST_Del(p_Entry);
90952 + LIST_AddToTail(p_Entry, p_Head);
90953 +}
90954 +
90955 +
90956 +/**************************************************************************//**
90957 + @Function LIST_IsEmpty
90958 +
90959 + @Description Tests whether a list is empty.
90960 +
90961 + @Param[in] p_List - A pointer to the list to test.
90962 +
90963 + @Return 1 if the list is empty, 0 otherwise.
90964 +*//***************************************************************************/
90965 +static __inline__ int LIST_IsEmpty(t_List *p_List)
90966 +{
90967 + return (LIST_FIRST(p_List) == p_List);
90968 +}
90969 +
90970 +
90971 +/**************************************************************************//**
90972 + @Function LIST_Append
90973 +
90974 + @Description Join two lists.
90975 +
90976 + @Param[in] p_NewList - A pointer to the new list to add.
90977 + @Param[in] p_Head - A pointer to the place to add it in the first list.
90978 +
90979 + @Return none.
90980 +*//***************************************************************************/
90981 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
90982 +
90983 +
90984 +/**************************************************************************//**
90985 + @Function LIST_NumOfObjs
90986 +
90987 + @Description Counts number of objects in the list
90988 +
90989 + @Param[in] p_List - A pointer to the list which objects are to be counted.
90990 +
90991 + @Return Number of objects in the list.
90992 +*//***************************************************************************/
90993 +int LIST_NumOfObjs(t_List *p_List);
90994 +
90995 +/** @} */ /* end of list_id group */
90996 +/** @} */ /* end of etc_id group */
90997 +
90998 +
90999 +#endif /* __LIST_EXT_H */
91000 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
91001 new file mode 100644
91002 index 00000000..d0565d41
91003 --- /dev/null
91004 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
91005 @@ -0,0 +1,318 @@
91006 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91007 + * All rights reserved.
91008 + *
91009 + * Redistribution and use in source and binary forms, with or without
91010 + * modification, are permitted provided that the following conditions are met:
91011 + * * Redistributions of source code must retain the above copyright
91012 + * notice, this list of conditions and the following disclaimer.
91013 + * * Redistributions in binary form must reproduce the above copyright
91014 + * notice, this list of conditions and the following disclaimer in the
91015 + * documentation and/or other materials provided with the distribution.
91016 + * * Neither the name of Freescale Semiconductor nor the
91017 + * names of its contributors may be used to endorse or promote products
91018 + * derived from this software without specific prior written permission.
91019 + *
91020 + *
91021 + * ALTERNATIVELY, this software may be distributed under the terms of the
91022 + * GNU General Public License ("GPL") as published by the Free Software
91023 + * Foundation, either version 2 of that License or (at your option) any
91024 + * later version.
91025 + *
91026 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91027 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91028 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91029 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91030 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91031 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91032 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91033 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91034 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91035 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91036 + */
91037 +
91038 +
91039 +/**************************************************************************//**
91040 +
91041 + @File mem_ext.h
91042 +
91043 + @Description External prototypes for the memory manager object
91044 +*//***************************************************************************/
91045 +
91046 +#ifndef __MEM_EXT_H
91047 +#define __MEM_EXT_H
91048 +
91049 +#include "std_ext.h"
91050 +#include "part_ext.h"
91051 +
91052 +
91053 +/**************************************************************************//**
91054 + @Group etc_id Utility Library Application Programming Interface
91055 +
91056 + @Description External routines.
91057 +
91058 + @{
91059 +*//***************************************************************************/
91060 +
91061 +/**************************************************************************//**
91062 + @Group mem_id Slab Memory Manager
91063 +
91064 + @Description Slab Memory Manager module functions, definitions and enums.
91065 +
91066 + @{
91067 +*//***************************************************************************/
91068 +
91069 +/* Each block is of the following structure:
91070 + *
91071 + *
91072 + * +-----------+----------+---------------------------+-----------+-----------+
91073 + * | Alignment | Prefix | Data | Postfix | Alignment |
91074 + * | field | field | field | field | Padding |
91075 + * | | | | | |
91076 + * +-----------+----------+---------------------------+-----------+-----------+
91077 + * and at the beginning of all bytes, an additional optional padding might reside
91078 + * to ensure that the first blocks data field is aligned as requested.
91079 + */
91080 +
91081 +
91082 +#define MEM_MAX_NAME_LENGTH 8
91083 +
91084 +/**************************************************************************//*
91085 + @Description Memory Segment structure
91086 +*//***************************************************************************/
91087 +
91088 +typedef struct
91089 +{
91090 + char name[MEM_MAX_NAME_LENGTH];
91091 + /* The segment's name */
91092 + uint8_t **p_Bases; /* Base addresses of the segments */
91093 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
91094 + t_Handle h_Spinlock;
91095 + uint16_t dataSize; /* Size of each data block */
91096 + uint16_t prefixSize; /* How many bytes to reserve before the data */
91097 + uint16_t postfixSize; /* How many bytes to reserve after the data */
91098 + uint16_t alignment; /* Requested alignment for the data field */
91099 + int allocOwner; /* Memory allocation owner */
91100 + uint32_t getFailures; /* Number of times get failed */
91101 + uint32_t num; /* Number of blocks in segment */
91102 + uint32_t current; /* Current block */
91103 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
91104 +#ifdef DEBUG_MEM_LEAKS
91105 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
91106 + uint32_t blockOffset;
91107 + uint32_t blockSize;
91108 +#endif /* DEBUG_MEM_LEAKS */
91109 +} t_MemorySegment;
91110 +
91111 +
91112 +
91113 +/**************************************************************************//**
91114 + @Function MEM_Init
91115 +
91116 + @Description Create a new memory segment.
91117 +
91118 + @Param[in] name - Name of memory partition.
91119 + @Param[in] p_Handle - Handle to new segment is returned through here.
91120 + @Param[in] num - Number of blocks in new segment.
91121 + @Param[in] dataSize - Size of blocks in segment.
91122 + @Param[in] prefixSize - How many bytes to allocate before the data.
91123 + @Param[in] postfixSize - How many bytes to allocate after the data.
91124 + @Param[in] alignment - Requested alignment for data field (in bytes).
91125 +
91126 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91127 +*//***************************************************************************/
91128 +t_Error MEM_Init(char name[],
91129 + t_Handle *p_Handle,
91130 + uint32_t num,
91131 + uint16_t dataSize,
91132 + uint16_t prefixSize,
91133 + uint16_t postfixSize,
91134 + uint16_t alignment);
91135 +
91136 +/**************************************************************************//**
91137 + @Function MEM_InitSmart
91138 +
91139 + @Description Create a new memory segment.
91140 +
91141 + @Param[in] name - Name of memory partition.
91142 + @Param[in] p_Handle - Handle to new segment is returned through here.
91143 + @Param[in] num - Number of blocks in new segment.
91144 + @Param[in] dataSize - Size of blocks in segment.
91145 + @Param[in] prefixSize - How many bytes to allocate before the data.
91146 + @Param[in] postfixSize - How many bytes to allocate after the data.
91147 + @Param[in] alignment - Requested alignment for data field (in bytes).
91148 + @Param[in] memPartitionId - Memory partition ID for allocation.
91149 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
91150 + continuously or not.
91151 +
91152 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91153 +*//***************************************************************************/
91154 +t_Error MEM_InitSmart(char name[],
91155 + t_Handle *p_Handle,
91156 + uint32_t num,
91157 + uint16_t dataSize,
91158 + uint16_t prefixSize,
91159 + uint16_t postfixSize,
91160 + uint16_t alignment,
91161 + uint8_t memPartitionId,
91162 + bool consecutiveMem);
91163 +
91164 +/**************************************************************************//**
91165 + @Function MEM_InitByAddress
91166 +
91167 + @Description Create a new memory segment with a specified base address.
91168 +
91169 + @Param[in] name - Name of memory partition.
91170 + @Param[in] p_Handle - Handle to new segment is returned through here.
91171 + @Param[in] num - Number of blocks in new segment.
91172 + @Param[in] dataSize - Size of blocks in segment.
91173 + @Param[in] prefixSize - How many bytes to allocate before the data.
91174 + @Param[in] postfixSize - How many bytes to allocate after the data.
91175 + @Param[in] alignment - Requested alignment for data field (in bytes).
91176 + @Param[in] address - The required base address.
91177 +
91178 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91179 + *//***************************************************************************/
91180 +t_Error MEM_InitByAddress(char name[],
91181 + t_Handle *p_Handle,
91182 + uint32_t num,
91183 + uint16_t dataSize,
91184 + uint16_t prefixSize,
91185 + uint16_t postfixSize,
91186 + uint16_t alignment,
91187 + uint8_t *address);
91188 +
91189 +/**************************************************************************//**
91190 + @Function MEM_Free
91191 +
91192 + @Description Free a specific memory segment.
91193 +
91194 + @Param[in] h_Mem - Handle to memory segment.
91195 +
91196 + @Return None.
91197 +*//***************************************************************************/
91198 +void MEM_Free(t_Handle h_Mem);
91199 +
91200 +/**************************************************************************//**
91201 + @Function MEM_Get
91202 +
91203 + @Description Get a block of memory from a segment.
91204 +
91205 + @Param[in] h_Mem - Handle to memory segment.
91206 +
91207 + @Return Pointer to new memory block on success,0 otherwise.
91208 +*//***************************************************************************/
91209 +void * MEM_Get(t_Handle h_Mem);
91210 +
91211 +/**************************************************************************//**
91212 + @Function MEM_GetN
91213 +
91214 + @Description Get up to N blocks of memory from a segment.
91215 +
91216 + The blocks are assumed to be of a fixed size (one size per segment).
91217 +
91218 + @Param[in] h_Mem - Handle to memory segment.
91219 + @Param[in] num - Number of blocks to allocate.
91220 + @Param[out] array - Array of at least num pointers to which the addresses
91221 + of the allocated blocks are written.
91222 +
91223 + @Return The number of blocks actually allocated.
91224 +
91225 + @Cautions Interrupts are disabled for all of the allocation loop.
91226 + Although this loop is very short for each block (several machine
91227 + instructions), you should not allocate a very large number
91228 + of blocks via this routine.
91229 +*//***************************************************************************/
91230 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
91231 +
91232 +/**************************************************************************//**
91233 + @Function MEM_Put
91234 +
91235 + @Description Put a block of memory back to a segment.
91236 +
91237 + @Param[in] h_Mem - Handle to memory segment.
91238 + @Param[in] p_Block - The block to return.
91239 +
91240 + @Return Pointer to new memory block on success,0 otherwise.
91241 +*//***************************************************************************/
91242 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
91243 +
91244 +/**************************************************************************//**
91245 + @Function MEM_ComputePartitionSize
91246 +
91247 + @Description calculate a tight upper boundary of the size of a partition with
91248 + given attributes.
91249 +
91250 + The returned value is suitable if one wants to use MEM_InitByAddress().
91251 +
91252 + @Param[in] num - The number of blocks in the segment.
91253 + @Param[in] dataSize - Size of block to get.
91254 + @Param[in] prefixSize - The prefix size
91255 + @Param postfixSize - The postfix size
91256 + @Param[in] alignment - The requested alignment value (in bytes)
91257 +
91258 + @Return The memory block size a segment with the given attributes needs.
91259 +*//***************************************************************************/
91260 +uint32_t MEM_ComputePartitionSize(uint32_t num,
91261 + uint16_t dataSize,
91262 + uint16_t prefixSize,
91263 + uint16_t postfixSize,
91264 + uint16_t alignment);
91265 +
91266 +#ifdef DEBUG_MEM_LEAKS
91267 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
91268 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
91269 +#endif /* !(defined(__MWERKS__) && ... */
91270 +
91271 +/**************************************************************************//**
91272 + @Function MEM_CheckLeaks
91273 +
91274 + @Description Report MEM object leaks.
91275 +
91276 + This routine is automatically called by the MEM_Free() routine,
91277 + but it can also be invoked while the MEM object is alive.
91278 +
91279 + @Param[in] h_Mem - Handle to memory segment.
91280 +
91281 + @Return None.
91282 +*//***************************************************************************/
91283 +void MEM_CheckLeaks(t_Handle h_Mem);
91284 +
91285 +#else /* not DEBUG_MEM_LEAKS */
91286 +#define MEM_CheckLeaks(h_Mem)
91287 +#endif /* not DEBUG_MEM_LEAKS */
91288 +
91289 +/**************************************************************************//**
91290 + @Description Get base of MEM
91291 +*//***************************************************************************/
91292 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
91293 +
91294 +/**************************************************************************//**
91295 + @Description Get size of MEM block
91296 +*//***************************************************************************/
91297 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
91298 +
91299 +/**************************************************************************//**
91300 + @Description Get prefix size of MEM block
91301 +*//***************************************************************************/
91302 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
91303 +
91304 +/**************************************************************************//**
91305 + @Description Get postfix size of MEM block
91306 +*//***************************************************************************/
91307 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
91308 +
91309 +/**************************************************************************//**
91310 + @Description Get alignment of MEM block (in bytes)
91311 +*//***************************************************************************/
91312 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
91313 +
91314 +/**************************************************************************//**
91315 + @Description Get the number of blocks in the segment
91316 +*//***************************************************************************/
91317 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
91318 +
91319 +/** @} */ /* end of MEM group */
91320 +/** @} */ /* end of etc_id group */
91321 +
91322 +
91323 +#endif /* __MEM_EXT_H */
91324 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91325 new file mode 100644
91326 index 00000000..1b3a2fac
91327 --- /dev/null
91328 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91329 @@ -0,0 +1,208 @@
91330 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91331 + * All rights reserved.
91332 + *
91333 + * Redistribution and use in source and binary forms, with or without
91334 + * modification, are permitted provided that the following conditions are met:
91335 + * * Redistributions of source code must retain the above copyright
91336 + * notice, this list of conditions and the following disclaimer.
91337 + * * Redistributions in binary form must reproduce the above copyright
91338 + * notice, this list of conditions and the following disclaimer in the
91339 + * documentation and/or other materials provided with the distribution.
91340 + * * Neither the name of Freescale Semiconductor nor the
91341 + * names of its contributors may be used to endorse or promote products
91342 + * derived from this software without specific prior written permission.
91343 + *
91344 + *
91345 + * ALTERNATIVELY, this software may be distributed under the terms of the
91346 + * GNU General Public License ("GPL") as published by the Free Software
91347 + * Foundation, either version 2 of that License or (at your option) any
91348 + * later version.
91349 + *
91350 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91351 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91352 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91353 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91354 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91355 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91356 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91357 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91358 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91359 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91360 + */
91361 +
91362 +
91363 +/**************************************************************************//**
91364 +
91365 + @File memcpy_ext.h
91366 +
91367 + @Description Efficient functions for copying and setting blocks of memory.
91368 +*//***************************************************************************/
91369 +
91370 +#ifndef __MEMCPY_EXT_H
91371 +#define __MEMCPY_EXT_H
91372 +
91373 +#include "std_ext.h"
91374 +
91375 +
91376 +/**************************************************************************//**
91377 + @Group etc_id Utility Library Application Programming Interface
91378 +
91379 + @Description External routines.
91380 +
91381 + @{
91382 +*//***************************************************************************/
91383 +
91384 +/**************************************************************************//**
91385 + @Group mem_cpy Memory Copy
91386 +
91387 + @Description Memory Copy module functions,definitions and enums.
91388 +
91389 + @{
91390 +*//***************************************************************************/
91391 +
91392 +/**************************************************************************//**
91393 + @Function MemCpy32
91394 +
91395 + @Description Copies one memory buffer into another one in 4-byte chunks!
91396 + Which should be more efficient than byte by byte.
91397 +
91398 + For large buffers (over 60 bytes) this function is about 4 times
91399 + more efficient than the trivial memory copy. For short buffers
91400 + it is reduced to the trivial copy and may be a bit worse.
91401 +
91402 + @Param[in] pDst - The address of the destination buffer.
91403 + @Param[in] pSrc - The address of the source buffer.
91404 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91405 +
91406 + @Return pDst (the address of the destination buffer).
91407 +
91408 + @Cautions There is no parameter or boundary checking! It is up to the user
91409 + to supply non-null parameters as source & destination and size
91410 + that actually fits into the destination buffer.
91411 +*//***************************************************************************/
91412 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91413 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91414 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91415 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91416 +
91417 +/**************************************************************************//**
91418 + @Function MemCpy64
91419 +
91420 + @Description Copies one memory buffer into another one in 8-byte chunks!
91421 + Which should be more efficient than byte by byte.
91422 +
91423 + For large buffers (over 60 bytes) this function is about 8 times
91424 + more efficient than the trivial memory copy. For short buffers
91425 + it is reduced to the trivial copy and may be a bit worse.
91426 +
91427 + Some testing suggests that MemCpy32() preforms better than
91428 + MemCpy64() over small buffers. On average they break even at
91429 + 100 byte buffers. For buffers larger than that MemCpy64 is
91430 + superior.
91431 +
91432 + @Param[in] pDst - The address of the destination buffer.
91433 + @Param[in] pSrc - The address of the source buffer.
91434 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91435 +
91436 + @Return pDst (the address of the destination buffer).
91437 +
91438 + @Cautions There is no parameter or boundary checking! It is up to the user
91439 + to supply non null parameters as source & destination and size
91440 + that actually fits into their buffer.
91441 +
91442 + Do not use under Linux.
91443 +*//***************************************************************************/
91444 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91445 +
91446 +/**************************************************************************//**
91447 + @Function MemSet32
91448 +
91449 + @Description Sets all bytes of a memory buffer to a specific value, in
91450 + 4-byte chunks.
91451 +
91452 + @Param[in] pDst - The address of the destination buffer.
91453 + @Param[in] val - Value to set destination bytes to.
91454 + @Param[in] size - The number of bytes that will be set to val.
91455 +
91456 + @Return pDst (the address of the destination buffer).
91457 +
91458 + @Cautions There is no parameter or boundary checking! It is up to the user
91459 + to supply non null parameter as destination and size
91460 + that actually fits into the destination buffer.
91461 +*//***************************************************************************/
91462 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91463 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91464 +
91465 +/**************************************************************************//**
91466 + @Function MemSet64
91467 +
91468 + @Description Sets all bytes of a memory buffer to a specific value, in
91469 + 8-byte chunks.
91470 +
91471 + @Param[in] pDst - The address of the destination buffer.
91472 + @Param[in] val - Value to set destination bytes to.
91473 + @Param[in] size - The number of bytes that will be set to val.
91474 +
91475 + @Return pDst (the address of the destination buffer).
91476 +
91477 + @Cautions There is no parameter or boundary checking! It is up to the user
91478 + to supply non null parameter as destination and size
91479 + that actually fits into the destination buffer.
91480 +*//***************************************************************************/
91481 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91482 +
91483 +/**************************************************************************//**
91484 + @Function MemDisp
91485 +
91486 + @Description Displays a block of memory in chunks of 32 bits.
91487 +
91488 + @Param[in] addr - The address of the memory to display.
91489 + @Param[in] size - The number of bytes that will be displayed.
91490 +
91491 + @Return None.
91492 +
91493 + @Cautions There is no parameter or boundary checking! It is up to the user
91494 + to supply non null parameter as destination and size
91495 + that actually fits into the destination buffer.
91496 +*//***************************************************************************/
91497 +void MemDisp(uint8_t *addr, int size);
91498 +
91499 +/**************************************************************************//**
91500 + @Function MemCpy8
91501 +
91502 + @Description Trivial copy one memory buffer into another byte by byte
91503 +
91504 + @Param[in] pDst - The address of the destination buffer.
91505 + @Param[in] pSrc - The address of the source buffer.
91506 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91507 +
91508 + @Return pDst (the address of the destination buffer).
91509 +
91510 + @Cautions There is no parameter or boundary checking! It is up to the user
91511 + to supply non-null parameters as source & destination and size
91512 + that actually fits into the destination buffer.
91513 +*//***************************************************************************/
91514 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91515 +
91516 +/**************************************************************************//**
91517 + @Function MemSet8
91518 +
91519 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91520 +
91521 + @Param[in] pDst - The address of the destination buffer.
91522 + @Param[in] c - Value to set destination bytes to.
91523 + @Param[in] size - The number of bytes that will be set to val.
91524 +
91525 + @Return pDst (the address of the destination buffer).
91526 +
91527 + @Cautions There is no parameter or boundary checking! It is up to the user
91528 + to supply non null parameter as destination and size
91529 + that actually fits into the destination buffer.
91530 +*//***************************************************************************/
91531 +void * MemSet8(void* pDst, int c, uint32_t size);
91532 +
91533 +/** @} */ /* end of mem_cpy group */
91534 +/** @} */ /* end of etc_id group */
91535 +
91536 +
91537 +#endif /* __MEMCPY_EXT_H */
91538 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91539 new file mode 100644
91540 index 00000000..fa7c85e3
91541 --- /dev/null
91542 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91543 @@ -0,0 +1,310 @@
91544 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91545 + * All rights reserved.
91546 + *
91547 + * Redistribution and use in source and binary forms, with or without
91548 + * modification, are permitted provided that the following conditions are met:
91549 + * * Redistributions of source code must retain the above copyright
91550 + * notice, this list of conditions and the following disclaimer.
91551 + * * Redistributions in binary form must reproduce the above copyright
91552 + * notice, this list of conditions and the following disclaimer in the
91553 + * documentation and/or other materials provided with the distribution.
91554 + * * Neither the name of Freescale Semiconductor nor the
91555 + * names of its contributors may be used to endorse or promote products
91556 + * derived from this software without specific prior written permission.
91557 + *
91558 + *
91559 + * ALTERNATIVELY, this software may be distributed under the terms of the
91560 + * GNU General Public License ("GPL") as published by the Free Software
91561 + * Foundation, either version 2 of that License or (at your option) any
91562 + * later version.
91563 + *
91564 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91565 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91566 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91567 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91568 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91569 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91570 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91571 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91572 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91573 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91574 + */
91575 +
91576 +
91577 +/**************************************************************************//**
91578 + @File mm_ext.h
91579 +
91580 + @Description Memory Manager Application Programming Interface
91581 +*//***************************************************************************/
91582 +#ifndef __MM_EXT
91583 +#define __MM_EXT
91584 +
91585 +#include "std_ext.h"
91586 +
91587 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91588 + where maximum alignment defined as
91589 + MM_MAX_ALIGNMENT power of 2 */
91590 +
91591 +#define MM_MAX_NAME_LEN 32
91592 +
91593 +/**************************************************************************//**
91594 + @Group etc_id Utility Library Application Programming Interface
91595 +
91596 + @Description External routines.
91597 +
91598 + @{
91599 +*//***************************************************************************/
91600 +
91601 +/**************************************************************************//**
91602 + @Group mm_grp Flexible Memory Manager
91603 +
91604 + @Description Flexible Memory Manager module functions,definitions and enums.
91605 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91606 +
91607 + @{
91608 +*//***************************************************************************/
91609 +
91610 +
91611 +/**************************************************************************//**
91612 + @Function MM_Init
91613 +
91614 + @Description Initializes a new MM object.
91615 +
91616 + It initializes a new memory block consisting of base address
91617 + and size of the available memory by calling to MemBlock_Init
91618 + routine. It is also initializes a new free block for each
91619 + by calling FreeBlock_Init routine, which is pointed to
91620 + the almost all memory started from the required alignment
91621 + from the base address and to the end of the memory.
91622 + The handle to the new MM object is returned via "MM"
91623 + argument (passed by reference).
91624 +
91625 + @Param[in] h_MM - Handle to the MM object.
91626 + @Param[in] base - Base address of the MM.
91627 + @Param[in] size - Size of the MM.
91628 +
91629 + @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.
91630 +*//***************************************************************************/
91631 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91632 +
91633 +/**************************************************************************//**
91634 + @Function MM_Get
91635 +
91636 + @Description Allocates a block of memory according to the given size and the alignment.
91637 +
91638 + The Alignment argument tells from which
91639 + free list allocate a block of memory. 2^alignment indicates
91640 + the alignment that the base address of the allocated block
91641 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91642 + are available for the alignment argument.
91643 + The routine passes through the specific free list of free
91644 + blocks and seeks for a first block that have anough memory
91645 + that is required (best fit).
91646 + After the block is found and data is allocated, it calls
91647 + the internal MM_CutFree routine to update all free lists
91648 + do not include a just allocated block. Of course, each
91649 + free list contains a free blocks with the same alignment.
91650 + It is also creates a busy block that holds
91651 + information about an allocated block.
91652 +
91653 + @Param[in] h_MM - Handle to the MM object.
91654 + @Param[in] size - Size of the MM.
91655 + @Param[in] alignment - Index as a power of two defines a required
91656 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91657 + @Param[in] name - The name that specifies an allocated block.
91658 +
91659 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91660 +*//***************************************************************************/
91661 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91662 +
91663 +/**************************************************************************//**
91664 + @Function MM_GetBase
91665 +
91666 + @Description Gets the base address of the required MM objects.
91667 +
91668 + @Param[in] h_MM - Handle to the MM object.
91669 +
91670 + @Return base address of the block.
91671 +*//***************************************************************************/
91672 +uint64_t MM_GetBase(t_Handle h_MM);
91673 +
91674 +/**************************************************************************//**
91675 + @Function MM_GetForce
91676 +
91677 + @Description Force memory allocation.
91678 +
91679 + It means to allocate a block of memory of the given
91680 + size from the given base address.
91681 + The routine checks if the required block can be allocated
91682 + (that is it is free) and then, calls the internal MM_CutFree
91683 + routine to update all free lists do not include that block.
91684 +
91685 + @Param[in] h_MM - Handle to the MM object.
91686 + @Param[in] base - Base address of the MM.
91687 + @Param[in] size - Size of the MM.
91688 + @Param[in] name - Name that specifies an allocated block.
91689 +
91690 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91691 +*//***************************************************************************/
91692 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91693 +
91694 +/**************************************************************************//**
91695 + @Function MM_GetForceMin
91696 +
91697 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91698 +
91699 + The Alignment argument tells from which
91700 + free list allocate a block of memory. 2^alignment indicates
91701 + the alignment that the base address of the allocated block
91702 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91703 + are available for the alignment argument.
91704 + The minimum baser address forces the location of the block
91705 + to be from a given address onward.
91706 + The routine passes through the specific free list of free
91707 + blocks and seeks for the first base address equal or smaller
91708 + than the required minimum address and end address larger than
91709 + than the required base + its size - i.e. that may contain
91710 + the required block.
91711 + After the block is found and data is allocated, it calls
91712 + the internal MM_CutFree routine to update all free lists
91713 + do not include a just allocated block. Of course, each
91714 + free list contains a free blocks with the same alignment.
91715 + It is also creates a busy block that holds
91716 + information about an allocated block.
91717 +
91718 + @Param[in] h_MM - Handle to the MM object.
91719 + @Param[in] size - Size of the MM.
91720 + @Param[in] alignment - Index as a power of two defines a required
91721 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91722 + @Param[in] min - The minimum base address of the block.
91723 + @Param[in] name - Name that specifies an allocated block.
91724 +
91725 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91726 +*//***************************************************************************/
91727 +uint64_t MM_GetForceMin(t_Handle h_MM,
91728 + uint64_t size,
91729 + uint64_t alignment,
91730 + uint64_t min,
91731 + char *name);
91732 +
91733 +/**************************************************************************//**
91734 + @Function MM_Put
91735 +
91736 + @Description Puts a block of memory of the given base address back to the memory.
91737 +
91738 + It checks if there is a busy block with the
91739 + given base address. If not, it returns 0, that
91740 + means can't free a block. Otherwise, it gets parameters of
91741 + the busy block and after it updates lists of free blocks,
91742 + removes that busy block from the list by calling to MM_CutBusy
91743 + routine.
91744 + After that it calls to MM_AddFree routine to add a new free
91745 + block to the free lists.
91746 +
91747 + @Param[in] h_MM - Handle to the MM object.
91748 + @Param[in] base - Base address of the MM.
91749 +
91750 + @Return The size of bytes released, 0 if failed.
91751 +*//***************************************************************************/
91752 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91753 +
91754 +/**************************************************************************//**
91755 + @Function MM_PutForce
91756 +
91757 + @Description Releases a block of memory of the required size from the required base address.
91758 +
91759 + First, it calls to MM_CutBusy routine
91760 + to cut a free block from the busy list. And then, calls to
91761 + MM_AddFree routine to add the free block to the free lists.
91762 +
91763 + @Param[in] h_MM - Handle to the MM object.
91764 + @Param[in] base - Base address of of a block to free.
91765 + @Param[in] size - Size of a block to free.
91766 +
91767 + @Return The number of bytes released, 0 on failure.
91768 +*//***************************************************************************/
91769 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91770 +
91771 +/**************************************************************************//**
91772 + @Function MM_Add
91773 +
91774 + @Description Adds a new memory block for memory allocation.
91775 +
91776 + When a new memory block is initialized and added to the
91777 + memory list, it calls to MM_AddFree routine to add the
91778 + new free block to the free lists.
91779 +
91780 + @Param[in] h_MM - Handle to the MM object.
91781 + @Param[in] base - Base address of the memory block.
91782 + @Param[in] size - Size of the memory block.
91783 +
91784 + @Return E_OK on success, otherwise returns an error code.
91785 +*//***************************************************************************/
91786 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91787 +
91788 +/**************************************************************************//**
91789 + @Function MM_Dump
91790 +
91791 + @Description Prints results of free and busy lists.
91792 +
91793 + @Param[in] h_MM - Handle to the MM object.
91794 +*//***************************************************************************/
91795 +void MM_Dump(t_Handle h_MM);
91796 +
91797 +/**************************************************************************//**
91798 + @Function MM_Free
91799 +
91800 + @Description Releases memory allocated for MM object.
91801 +
91802 + @Param[in] h_MM - Handle of the MM object.
91803 +*//***************************************************************************/
91804 +void MM_Free(t_Handle h_MM);
91805 +
91806 +/**************************************************************************//**
91807 + @Function MM_GetMemBlock
91808 +
91809 + @Description Returns base address of the memory block specified by the index.
91810 +
91811 + If index is 0, returns base address
91812 + of the first memory block, 1 - returns base address
91813 + of the second memory block, etc.
91814 + Note, those memory blocks are allocated by the
91815 + application before MM_Init or MM_Add and have to
91816 + be released by the application before or after invoking
91817 + the MM_Free routine.
91818 +
91819 + @Param[in] h_MM - Handle to the MM object.
91820 + @Param[in] index - Index of the memory block.
91821 +
91822 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91823 +*//***************************************************************************/
91824 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91825 +
91826 +/**************************************************************************//**
91827 + @Function MM_InRange
91828 +
91829 + @Description Checks if a specific address is in the memory range of the passed MM object.
91830 +
91831 + @Param[in] h_MM - Handle to the MM object.
91832 + @Param[in] addr - The address to be checked.
91833 +
91834 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91835 +*//***************************************************************************/
91836 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91837 +
91838 +/**************************************************************************//**
91839 + @Function MM_GetFreeMemSize
91840 +
91841 + @Description Returns the size (in bytes) of free memory.
91842 +
91843 + @Param[in] h_MM - Handle to the MM object.
91844 +
91845 + @Return Free memory size in bytes.
91846 +*//***************************************************************************/
91847 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
91848 +
91849 +
91850 +/** @} */ /* end of mm_grp group */
91851 +/** @} */ /* end of etc_id group */
91852 +
91853 +#endif /* __MM_EXT_H */
91854 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91855 new file mode 100644
91856 index 00000000..52f7a9dc
91857 --- /dev/null
91858 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91859 @@ -0,0 +1,118 @@
91860 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91861 + * All rights reserved.
91862 + *
91863 + * Redistribution and use in source and binary forms, with or without
91864 + * modification, are permitted provided that the following conditions are met:
91865 + * * Redistributions of source code must retain the above copyright
91866 + * notice, this list of conditions and the following disclaimer.
91867 + * * Redistributions in binary form must reproduce the above copyright
91868 + * notice, this list of conditions and the following disclaimer in the
91869 + * documentation and/or other materials provided with the distribution.
91870 + * * Neither the name of Freescale Semiconductor nor the
91871 + * names of its contributors may be used to endorse or promote products
91872 + * derived from this software without specific prior written permission.
91873 + *
91874 + *
91875 + * ALTERNATIVELY, this software may be distributed under the terms of the
91876 + * GNU General Public License ("GPL") as published by the Free Software
91877 + * Foundation, either version 2 of that License or (at your option) any
91878 + * later version.
91879 + *
91880 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91881 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91882 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91883 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91884 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91885 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91886 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91887 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91888 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91889 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91890 + */
91891 +
91892 +
91893 +/**************************************************************************//**
91894 + @File sprint_ext.h
91895 +
91896 + @Description Debug routines (externals).
91897 +
91898 +*//***************************************************************************/
91899 +
91900 +#ifndef __SPRINT_EXT_H
91901 +#define __SPRINT_EXT_H
91902 +
91903 +
91904 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
91905 +#include <linux/kernel.h>
91906 +
91907 +#elif defined(NCSW_VXWORKS)
91908 +#include "private/stdioP.h"
91909 +
91910 +#else
91911 +#include <stdio.h>
91912 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
91913 +
91914 +#include "std_ext.h"
91915 +
91916 +
91917 +/**************************************************************************//**
91918 + @Group etc_id Utility Library Application Programming Interface
91919 +
91920 + @Description External routines.
91921 +
91922 + @{
91923 +*//***************************************************************************/
91924 +
91925 +/**************************************************************************//**
91926 + @Group sprint_id Sprint
91927 +
91928 + @Description Sprint & Sscan module functions,definitions and enums.
91929 +
91930 + @{
91931 +*//***************************************************************************/
91932 +
91933 +/**************************************************************************//**
91934 + @Function Sprint
91935 +
91936 + @Description Format a string and place it in a buffer.
91937 +
91938 + @Param[in] buff - The buffer to place the result into.
91939 + @Param[in] str - The format string to use.
91940 + @Param[in] ... - Arguments for the format string.
91941 +
91942 + @Return Number of bytes formatted.
91943 +*//***************************************************************************/
91944 +int Sprint(char *buff, const char *str, ...);
91945 +
91946 +/**************************************************************************//**
91947 + @Function Snprint
91948 +
91949 + @Description Format a string and place it in a buffer.
91950 +
91951 + @Param[in] buf - The buffer to place the result into.
91952 + @Param[in] size - The size of the buffer, including the trailing null space.
91953 + @Param[in] fmt - The format string to use.
91954 + @Param[in] ... - Arguments for the format string.
91955 +
91956 + @Return Number of bytes formatted.
91957 +*//***************************************************************************/
91958 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
91959 +
91960 +/**************************************************************************//**
91961 + @Function Sscan
91962 +
91963 + @Description Unformat a buffer into a list of arguments.
91964 +
91965 + @Param[in] buf - input buffer.
91966 + @Param[in] fmt - formatting of buffer.
91967 + @Param[out] ... - resulting arguments.
91968 +
91969 + @Return Number of bytes unformatted.
91970 +*//***************************************************************************/
91971 +int Sscan(const char * buf, const char * fmt, ...);
91972 +
91973 +/** @} */ /* end of sprint_id group */
91974 +/** @} */ /* end of etc_id group */
91975 +
91976 +
91977 +#endif /* __SPRINT_EXT_H */
91978 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91979 new file mode 100644
91980 index 00000000..c7b9b46f
91981 --- /dev/null
91982 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91983 @@ -0,0 +1,37 @@
91984 +/*
91985 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91986 + *
91987 + * Redistribution and use in source and binary forms, with or without
91988 + * modification, are permitted provided that the following conditions are met:
91989 + * * Redistributions of source code must retain the above copyright
91990 + * notice, this list of conditions and the following disclaimer.
91991 + * * Redistributions in binary form must reproduce the above copyright
91992 + * notice, this list of conditions and the following disclaimer in the
91993 + * documentation and/or other materials provided with the distribution.
91994 + * * Neither the name of Freescale Semiconductor nor the
91995 + * names of its contributors may be used to endorse or promote products
91996 + * derived from this software without specific prior written permission.
91997 + *
91998 + *
91999 + * ALTERNATIVELY, this software may be distributed under the terms of the
92000 + * GNU General Public License ("GPL") as published by the Free Software
92001 + * Foundation, either version 2 of that License or (at your option) any
92002 + * later version.
92003 + *
92004 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92005 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92006 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92007 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92008 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92009 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92010 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92011 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92012 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92013 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92014 + */
92015 +
92016 +#ifndef FL_E500_MACROS_H
92017 +#define FL_E500_MACROS_H
92018 +
92019 +#endif /* FL_E500_MACROS_H */
92020 +
92021 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
92022 new file mode 100644
92023 index 00000000..b3f516fb
92024 --- /dev/null
92025 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
92026 @@ -0,0 +1,52 @@
92027 +/*
92028 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92029 + *
92030 + * Redistribution and use in source and binary forms, with or without
92031 + * modification, are permitted provided that the following conditions are met:
92032 + * * Redistributions of source code must retain the above copyright
92033 + * notice, this list of conditions and the following disclaimer.
92034 + * * Redistributions in binary form must reproduce the above copyright
92035 + * notice, this list of conditions and the following disclaimer in the
92036 + * documentation and/or other materials provided with the distribution.
92037 + * * Neither the name of Freescale Semiconductor nor the
92038 + * names of its contributors may be used to endorse or promote products
92039 + * derived from this software without specific prior written permission.
92040 + *
92041 + *
92042 + * ALTERNATIVELY, this software may be distributed under the terms of the
92043 + * GNU General Public License ("GPL") as published by the Free Software
92044 + * Foundation, either version 2 of that License or (at your option) any
92045 + * later version.
92046 + *
92047 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92048 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92049 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92050 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92051 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92052 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92053 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92054 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92055 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92056 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92057 + */
92058 +
92059 +#ifndef __GENERAL_H
92060 +#define __GENERAL_H
92061 +
92062 +#include "std_ext.h"
92063 +#if !defined(NCSW_LINUX)
92064 +#include "errno.h"
92065 +#endif
92066 +
92067 +
92068 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
92069 +
92070 +#ifndef CONFIG_FMAN_ARM
92071 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
92072 +#define ioread32be(addr) GET_UINT32(*addr)
92073 +#endif
92074 +
92075 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
92076 +
92077 +
92078 +#endif /* __GENERAL_H */
92079 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
92080 new file mode 100755
92081 index 00000000..8b194e99
92082 --- /dev/null
92083 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
92084 @@ -0,0 +1,78 @@
92085 +/*
92086 + * Copyright 2008-2013 Freescale Semiconductor Inc.
92087 + *
92088 + * Redistribution and use in source and binary forms, with or without
92089 + * modification, are permitted provided that the following conditions are met:
92090 + * * Redistributions of source code must retain the above copyright
92091 + * notice, this list of conditions and the following disclaimer.
92092 + * * Redistributions in binary form must reproduce the above copyright
92093 + * notice, this list of conditions and the following disclaimer in the
92094 + * documentation and/or other materials provided with the distribution.
92095 + * * Neither the name of Freescale Semiconductor nor the
92096 + * names of its contributors may be used to endorse or promote products
92097 + * derived from this software without specific prior written permission.
92098 + *
92099 + *
92100 + * ALTERNATIVELY, this software may be distributed under the terms of the
92101 + * GNU General Public License ("GPL") as published by the Free Software
92102 + * Foundation, either version 2 of that License or (at your option) any
92103 + * later version.
92104 + *
92105 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92106 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92107 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92108 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92109 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92110 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92111 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92112 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92113 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92114 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92115 + */
92116 +
92117 +
92118 +#ifndef __FMAN_COMMON_H
92119 +#define __FMAN_COMMON_H
92120 +
92121 +/**************************************************************************//**
92122 + @Description NIA Description
92123 +*//***************************************************************************/
92124 +#define NIA_ORDER_RESTOR 0x00800000
92125 +#define NIA_ENG_FM_CTL 0x00000000
92126 +#define NIA_ENG_PRS 0x00440000
92127 +#define NIA_ENG_KG 0x00480000
92128 +#define NIA_ENG_PLCR 0x004C0000
92129 +#define NIA_ENG_BMI 0x00500000
92130 +#define NIA_ENG_QMI_ENQ 0x00540000
92131 +#define NIA_ENG_QMI_DEQ 0x00580000
92132 +#define NIA_ENG_MASK 0x007C0000
92133 +
92134 +#define NIA_FM_CTL_AC_CC 0x00000006
92135 +#define NIA_FM_CTL_AC_HC 0x0000000C
92136 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
92137 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
92138 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
92139 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
92140 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
92141 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
92142 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
92143 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
92144 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
92145 +
92146 +
92147 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
92148 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
92149 +#define NIA_BMI_AC_RELEASE 0x000000C0
92150 +#define NIA_BMI_AC_DISCARD 0x000000C1
92151 +#define NIA_BMI_AC_TX 0x00000274
92152 +#define NIA_BMI_AC_FETCH 0x00000208
92153 +#define NIA_BMI_AC_MASK 0x000003FF
92154 +
92155 +#define NIA_KG_DIRECT 0x00000100
92156 +#define NIA_KG_CC_EN 0x00000200
92157 +#define NIA_PLCR_ABSOLUTE 0x00008000
92158 +
92159 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
92160 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
92161 +
92162 +#endif /* __FMAN_COMMON_H */
92163 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
92164 new file mode 100644
92165 index 00000000..caa87fc6
92166 --- /dev/null
92167 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
92168 @@ -0,0 +1,273 @@
92169 +/*
92170 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92171 + *
92172 + * Redistribution and use in source and binary forms, with or without
92173 + * modification, are permitted provided that the following conditions are met:
92174 + * * Redistributions of source code must retain the above copyright
92175 + * notice, this list of conditions and the following disclaimer.
92176 + * * Redistributions in binary form must reproduce the above copyright
92177 + * notice, this list of conditions and the following disclaimer in the
92178 + * documentation and/or other materials provided with the distribution.
92179 + * * Neither the name of Freescale Semiconductor nor the
92180 + * names of its contributors may be used to endorse or promote products
92181 + * derived from this software without specific prior written permission.
92182 + *
92183 + *
92184 + * ALTERNATIVELY, this software may be distributed under the terms of the
92185 + * GNU General Public License ("GPL") as published by the Free Software
92186 + * Foundation, either version 2 of that License or (at your option) any
92187 + * later version.
92188 + *
92189 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92190 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92191 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92192 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92193 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92194 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92195 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92196 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92197 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92198 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92199 + */
92200 +
92201 +#ifndef __FSL_ENET_H
92202 +#define __FSL_ENET_H
92203 +
92204 +/**
92205 + @Description Ethernet MAC-PHY Interface
92206 +*/
92207 +
92208 +enum enet_interface {
92209 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
92210 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
92211 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
92212 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
92213 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
92214 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
92215 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
92216 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
92217 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
92218 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
92219 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
92220 +};
92221 +
92222 +/**
92223 + @Description Ethernet Speed (nominal data rate)
92224 +*/
92225 +enum enet_speed {
92226 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
92227 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
92228 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
92229 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
92230 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
92231 +};
92232 +
92233 +enum mac_type {
92234 + E_MAC_DTSEC,
92235 + E_MAC_TGEC,
92236 + E_MAC_MEMAC
92237 +};
92238 +
92239 +/**************************************************************************//**
92240 + @Description Enum for inter-module interrupts registration
92241 +*//***************************************************************************/
92242 +enum fman_event_modules {
92243 + E_FMAN_MOD_PRS, /**< Parser event */
92244 + E_FMAN_MOD_KG, /**< Keygen event */
92245 + E_FMAN_MOD_PLCR, /**< Policer event */
92246 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
92247 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
92248 + E_FMAN_MOD_TMR, /**< Timer event */
92249 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
92250 + E_FMAN_MOD_MACSEC,
92251 + E_FMAN_MOD_DUMMY_LAST
92252 +};
92253 +
92254 +/**************************************************************************//**
92255 + @Description Enum for interrupts types
92256 +*//***************************************************************************/
92257 +enum fman_intr_type {
92258 + E_FMAN_INTR_TYPE_ERR,
92259 + E_FMAN_INTR_TYPE_NORMAL
92260 +};
92261 +
92262 +/**************************************************************************//**
92263 + @Description enum for defining MAC types
92264 +*//***************************************************************************/
92265 +enum fman_mac_type {
92266 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
92267 + E_FMAN_MAC_1G /**< 1G MAC */
92268 +};
92269 +
92270 +enum fman_mac_exceptions {
92271 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
92272 + /**< 10GEC MDIO scan event interrupt */
92273 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
92274 + /**< 10GEC MDIO command completion interrupt */
92275 + E_FMAN_MAC_EX_10G_REM_FAULT,
92276 + /**< 10GEC, mEMAC Remote fault interrupt */
92277 + E_FMAN_MAC_EX_10G_LOC_FAULT,
92278 + /**< 10GEC, mEMAC Local fault interrupt */
92279 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
92280 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
92281 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
92282 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
92283 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
92284 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
92285 + E_FMAN_MAC_EX_10G_TX_ER,
92286 + /**< 10GEC Transmit frame error interrupt */
92287 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
92288 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
92289 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
92290 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
92291 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
92292 + /**< 10GEC Receive jabber frame interrupt */
92293 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
92294 + /**< 10GEC Receive oversized frame interrupt */
92295 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
92296 + /**< 10GEC Receive runt frame interrupt */
92297 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
92298 + /**< 10GEC Receive fragment frame interrupt */
92299 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
92300 + /**< 10GEC Receive payload length error interrupt */
92301 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
92302 + /**< 10GEC Receive CRC error interrupt */
92303 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
92304 + /**< 10GEC Receive alignment error interrupt */
92305 + E_FMAN_MAC_EX_1G_BAB_RX,
92306 + /**< dTSEC Babbling receive error */
92307 + E_FMAN_MAC_EX_1G_RX_CTL,
92308 + /**< dTSEC Receive control (pause frame) interrupt */
92309 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
92310 + /**< dTSEC Graceful transmit stop complete */
92311 + E_FMAN_MAC_EX_1G_BAB_TX,
92312 + /**< dTSEC Babbling transmit error */
92313 + E_FMAN_MAC_EX_1G_TX_CTL,
92314 + /**< dTSEC Transmit control (pause frame) interrupt */
92315 + E_FMAN_MAC_EX_1G_TX_ERR,
92316 + /**< dTSEC Transmit error */
92317 + E_FMAN_MAC_EX_1G_LATE_COL,
92318 + /**< dTSEC Late collision */
92319 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
92320 + /**< dTSEC Collision retry limit */
92321 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
92322 + /**< dTSEC Transmit FIFO underrun */
92323 + E_FMAN_MAC_EX_1G_MAG_PCKT,
92324 + /**< dTSEC Magic Packet detection */
92325 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
92326 + /**< dTSEC MII management read completion */
92327 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
92328 + /**< dTSEC MII management write completion */
92329 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
92330 + /**< dTSEC Graceful receive stop complete */
92331 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
92332 + /**< dTSEC Internal data error on transmit */
92333 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
92334 + /**< dTSEC Internal data error on receive */
92335 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
92336 + /**< dTSEC Time-Stamp Receive Error */
92337 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
92338 + /**< dTSEC MIB counter overflow */
92339 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
92340 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
92341 + not supported on T4240/B4860 rev1 chips */
92342 +};
92343 +
92344 +#define ENET_IF_SGMII_BASEX 0x80000000
92345 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
92346 + and phy or backplane;
92347 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
92348 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
92349 + 10Mbps, 100Mbps or 1000Mbps */
92350 +
92351 +enum enet_mode {
92352 + E_ENET_MODE_INVALID = 0,
92353 + /**< Invalid Ethernet mode */
92354 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
92355 + /**< 10 Mbps MII */
92356 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
92357 + /**< 100 Mbps MII */
92358 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
92359 + /**< 10 Mbps RMII */
92360 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
92361 + /**< 100 Mbps RMII */
92362 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
92363 + /**< 10 Mbps SMII */
92364 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
92365 + /**< 100 Mbps SMII */
92366 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
92367 + /**< 1000 Mbps GMII */
92368 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
92369 + /**< 10 Mbps RGMII */
92370 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
92371 + /**< 100 Mbps RGMII */
92372 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
92373 + /**< 1000 Mbps RGMII */
92374 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
92375 + /**< 1000 Mbps TBI */
92376 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
92377 + /**< 1000 Mbps RTBI */
92378 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
92379 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
92380 + SGMII phy according to Cisco SGMII specification */
92381 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
92382 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
92383 + SGMII phy according to Cisco SGMII specification */
92384 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
92385 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
92386 + SGMII phy according to Cisco SGMII specification */
92387 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92388 + | E_ENET_SPEED_10),
92389 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
92390 + MAC and SGMII phy or backplane */
92391 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92392 + | E_ENET_SPEED_100),
92393 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
92394 + MAC and SGMII phy or backplane */
92395 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92396 + | E_ENET_SPEED_1000),
92397 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
92398 + MAC and SGMII phy or backplane */
92399 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
92400 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
92401 + QSGMII phy according to Cisco QSGMII specification */
92402 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
92403 + | E_ENET_SPEED_1000),
92404 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
92405 + MAC and QSGMII phy or backplane */
92406 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
92407 + /**< 10000 Mbps XGMII */
92408 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
92409 + /**< 10000 Mbps XFI */
92410 +};
92411 +
92412 +enum fmam_mac_statistics_level {
92413 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
92414 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
92415 + Optimized for performance */
92416 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92417 + optimized for performance */
92418 +};
92419 +
92420 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92421 + | (_speed))
92422 +
92423 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92424 + ((mode) & 0x0FFF0000)
92425 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92426 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92427 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92428 + ((uint64_t)(_enet_addr)[1] << 32) | \
92429 + ((uint64_t)(_enet_addr)[2] << 24) | \
92430 + ((uint64_t)(_enet_addr)[3] << 16) | \
92431 + ((uint64_t)(_enet_addr)[4] << 8) | \
92432 + ((uint64_t)(_enet_addr)[5]))
92433 +
92434 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92435 + do { \
92436 + int i; \
92437 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92438 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92439 + } while (0)
92440 +
92441 +#endif /* __FSL_ENET_H */
92442 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92443 new file mode 100755
92444 index 00000000..96a63fa7
92445 --- /dev/null
92446 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92447 @@ -0,0 +1,825 @@
92448 +/*
92449 + * Copyright 2013 Freescale Semiconductor Inc.
92450 + *
92451 + * Redistribution and use in source and binary forms, with or without
92452 + * modification, are permitted provided that the following conditions are met:
92453 + * * Redistributions of source code must retain the above copyright
92454 + * notice, this list of conditions and the following disclaimer.
92455 + * * Redistributions in binary form must reproduce the above copyright
92456 + * notice, this list of conditions and the following disclaimer in the
92457 + * documentation and/or other materials provided with the distribution.
92458 + * * Neither the name of Freescale Semiconductor nor the
92459 + * names of its contributors may be used to endorse or promote products
92460 + * derived from this software without specific prior written permission.
92461 + *
92462 + *
92463 + * ALTERNATIVELY, this software may be distributed under the terms of the
92464 + * GNU General Public License ("GPL") as published by the Free Software
92465 + * Foundation, either version 2 of that License or (at your option) any
92466 + * later version.
92467 + *
92468 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92469 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92470 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92471 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92472 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92473 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92474 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92475 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92476 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92477 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92478 + */
92479 +
92480 +#ifndef __FSL_FMAN_H
92481 +#define __FSL_FMAN_H
92482 +
92483 +#include "common/general.h"
92484 +
92485 +struct fman_ext_pool_params {
92486 + uint8_t id; /**< External buffer pool id */
92487 + uint16_t size; /**< External buffer pool buffer size */
92488 +};
92489 +
92490 +struct fman_ext_pools {
92491 + uint8_t num_pools_used; /**< Number of pools use by this port */
92492 + struct fman_ext_pool_params *ext_buf_pool;
92493 + /**< Parameters for each port */
92494 +};
92495 +
92496 +struct fman_backup_bm_pools {
92497 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92498 + must be smaller than the total number
92499 + of pools defined for the specified
92500 + port.*/
92501 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92502 + specifying which pools should be used
92503 + only as backup. Pool id's specified
92504 + here must be a subset of the pools
92505 + used by the specified port.*/
92506 +};
92507 +
92508 +/**************************************************************************//**
92509 + @Description A structure for defining BM pool depletion criteria
92510 +*//***************************************************************************/
92511 +struct fman_buf_pool_depletion {
92512 + bool buf_pool_depletion_enabled;
92513 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92514 + will be sent after a number of pools
92515 + (all together!) are depleted */
92516 + uint8_t num_pools; /**< the number of depleted pools that
92517 + will invoke pause frames transmission.
92518 + */
92519 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92520 + considered for depletion (Note - this
92521 + pool must be used by this port!). */
92522 + bool single_pool_mode_enable; /**< select mode in which pause frames
92523 + will be sent after a single-pool
92524 + is depleted; */
92525 + bool *pools_to_consider_for_single_mode;
92526 + /**< For each pool, TRUE if it should be
92527 + considered for depletion (Note - this
92528 + pool must be used by this port!) */
92529 + bool has_pfc_priorities;
92530 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92531 + the Priority Enable Vector in the PFC
92532 + frame which is transmitted */
92533 +};
92534 +
92535 +/**************************************************************************//**
92536 + @Description Enum for defining port DMA swap mode
92537 +*//***************************************************************************/
92538 +enum fman_dma_swap_option {
92539 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92540 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92541 + in PowerPc Little Endian mode. */
92542 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92543 + in Big Endian mode */
92544 +};
92545 +
92546 +/**************************************************************************//**
92547 + @Description Enum for defining port DMA cache attributes
92548 +*//***************************************************************************/
92549 +enum fman_dma_cache_option {
92550 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92551 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92552 +};
92553 +
92554 +typedef struct t_FmPrsResult fm_prs_result_t;
92555 +typedef enum e_EnetMode enet_mode_t;
92556 +typedef t_Handle handle_t;
92557 +
92558 +struct fman_revision_info {
92559 + uint8_t majorRev; /**< Major revision */
92560 + uint8_t minorRev; /**< Minor revision */
92561 +};
92562 +
92563 +/* sizes */
92564 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92565 +#define OFFSET_UNITS 16
92566 +#define MAX_INT_OFFSET 240
92567 +#define MAX_IC_SIZE 256
92568 +#define MAX_EXT_OFFSET 496
92569 +#define MAX_EXT_BUFFER_OFFSET 511
92570 +
92571 +/**************************************************************************
92572 + @Description Memory Mapped Registers
92573 +***************************************************************************/
92574 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92575 +
92576 +struct fman_fpm_regs {
92577 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92578 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92579 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92580 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92581 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92582 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92583 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92584 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92585 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92586 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92587 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92588 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92589 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92590 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92591 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92592 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92593 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92594 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92595 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92596 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92597 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92598 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92599 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92600 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92601 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92602 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92603 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92604 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92605 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92606 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92607 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92608 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92609 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92610 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92611 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92612 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92613 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92614 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92615 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92616 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92617 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92618 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92619 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92620 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92621 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92622 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92623 + uint32_t res0600[0x400 - 384];
92624 +};
92625 +
92626 +struct fman_bmi_regs {
92627 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92628 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92629 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92630 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92631 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92632 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92633 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92634 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92635 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92636 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92637 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92638 + uint32_t res009c; /**< 0x9c */
92639 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92640 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92641 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92642 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92643 + uint32_t res0200; /**< 0x200 */
92644 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92645 + uint32_t res0300; /**< 0x300 */
92646 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92647 +};
92648 +
92649 +struct fman_qmi_regs {
92650 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92651 + uint32_t res0004; /**< 0x04 */
92652 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92653 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92654 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92655 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92656 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92657 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92658 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92659 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92660 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92661 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92662 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92663 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92664 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92665 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92666 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92667 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92668 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92669 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92670 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92671 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92672 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92673 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92674 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92675 + uint32_t res007c; /**< 0x7c */
92676 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92677 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92678 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92679 + struct {
92680 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92681 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92682 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92683 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92684 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92685 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92686 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92687 + uint32_t res001c; /**< 0x1c */
92688 + } dbg_traps[3]; /**< 0x90 - 0xef */
92689 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92690 +};
92691 +
92692 +struct fman_dma_regs {
92693 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92694 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92695 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92696 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92697 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92698 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92699 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92700 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92701 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92702 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92703 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92704 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92705 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92706 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92707 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92708 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92709 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92710 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92711 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92712 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92713 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92714 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92715 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92716 + uint32_t res005c; /**< 0x5c */
92717 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92718 + uint32_t res00e0[0x400 - 56];
92719 +};
92720 +
92721 +struct fman_rg {
92722 + struct fman_fpm_regs *fpm_rg;
92723 + struct fman_dma_regs *dma_rg;
92724 + struct fman_bmi_regs *bmi_rg;
92725 + struct fman_qmi_regs *qmi_rg;
92726 +};
92727 +
92728 +enum fman_dma_cache_override {
92729 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92730 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92731 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92732 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92733 +};
92734 +
92735 +enum fman_dma_aid_mode {
92736 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92737 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92738 +};
92739 +
92740 +enum fman_dma_dbg_cnt_mode {
92741 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92742 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92743 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92744 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92745 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92746 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92747 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92748 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92749 +};
92750 +
92751 +enum fman_dma_emergency_level {
92752 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92753 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92754 +};
92755 +
92756 +enum fman_catastrophic_err {
92757 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92758 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92759 +};
92760 +
92761 +enum fman_dma_err {
92762 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92763 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92764 +};
92765 +
92766 +struct fman_cfg {
92767 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92768 + bool en_counters;
92769 + uint8_t disp_limit_tsh;
92770 + uint8_t prs_disp_tsh;
92771 + uint8_t plcr_disp_tsh;
92772 + uint8_t kg_disp_tsh;
92773 + uint8_t bmi_disp_tsh;
92774 + uint8_t qmi_enq_disp_tsh;
92775 + uint8_t qmi_deq_disp_tsh;
92776 + uint8_t fm_ctl1_disp_tsh;
92777 + uint8_t fm_ctl2_disp_tsh;
92778 + enum fman_dma_cache_override dma_cache_override;
92779 + enum fman_dma_aid_mode dma_aid_mode;
92780 + bool dma_aid_override;
92781 + uint8_t dma_axi_dbg_num_of_beats;
92782 + uint8_t dma_cam_num_of_entries;
92783 + uint32_t dma_watchdog;
92784 + uint8_t dma_comm_qtsh_asrt_emer;
92785 + uint8_t dma_write_buf_tsh_asrt_emer;
92786 + uint8_t dma_read_buf_tsh_asrt_emer;
92787 + uint8_t dma_comm_qtsh_clr_emer;
92788 + uint8_t dma_write_buf_tsh_clr_emer;
92789 + uint8_t dma_read_buf_tsh_clr_emer;
92790 + uint32_t dma_sos_emergency;
92791 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92792 + bool dma_stop_on_bus_error;
92793 + bool dma_en_emergency;
92794 + uint32_t dma_emergency_bus_select;
92795 + enum fman_dma_emergency_level dma_emergency_level;
92796 + bool dma_en_emergency_smoother;
92797 + uint32_t dma_emergency_switch_counter;
92798 + bool halt_on_external_activ;
92799 + bool halt_on_unrecov_ecc_err;
92800 + enum fman_catastrophic_err catastrophic_err;
92801 + enum fman_dma_err dma_err;
92802 + bool en_muram_test_mode;
92803 + bool en_iram_test_mode;
92804 + bool external_ecc_rams_enable;
92805 + uint16_t tnum_aging_period;
92806 + uint32_t exceptions;
92807 + uint16_t clk_freq;
92808 + bool pedantic_dma;
92809 + uint32_t cam_base_addr;
92810 + uint32_t fifo_base_addr;
92811 + uint32_t total_fifo_size;
92812 + uint8_t total_num_of_tasks;
92813 + bool qmi_deq_option_support;
92814 + uint32_t qmi_def_tnums_thresh;
92815 + bool fman_partition_array;
92816 + uint8_t num_of_fman_ctrl_evnt_regs;
92817 +};
92818 +
92819 +/**************************************************************************//**
92820 + @Description Exceptions
92821 +*//***************************************************************************/
92822 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92823 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92824 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92825 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92826 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92827 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92828 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92829 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92830 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92831 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92832 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92833 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92834 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92835 +#define FMAN_EX_IRAM_ECC 0x00040000
92836 +#define FMAN_EX_NURAM_ECC 0x00020000
92837 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92838 +
92839 +enum fman_exceptions {
92840 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92841 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92842 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92843 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92844 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92845 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92846 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
92847 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
92848 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
92849 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
92850 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
92851 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
92852 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
92853 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
92854 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
92855 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
92856 +};
92857 +
92858 +enum fman_counters {
92859 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
92860 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
92861 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
92862 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
92863 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
92864 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
92865 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
92866 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
92867 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
92868 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
92869 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
92870 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
92871 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
92872 +};
92873 +
92874 +#define FPM_PRT_FM_CTL1 0x00000001
92875 +#define FPM_PRT_FM_CTL2 0x00000002
92876 +
92877 +/**************************************************************************//**
92878 + @Description DMA definitions
92879 +*//***************************************************************************/
92880 +
92881 +/* masks */
92882 +#define DMA_MODE_AID_OR 0x20000000
92883 +#define DMA_MODE_SBER 0x10000000
92884 +#define DMA_MODE_BER 0x00200000
92885 +#define DMA_MODE_EB 0x00100000
92886 +#define DMA_MODE_ECC 0x00000020
92887 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
92888 +#define DMA_MODE_SECURE_PROT 0x00000800
92889 +#define DMA_MODE_EMER_READ 0x00080000
92890 +#define DMA_MODE_EMER_WRITE 0x00040000
92891 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
92892 +#define DMA_MODE_CEN_MASK 0x0000E000
92893 +#define DMA_MODE_DBG_MASK 0x00000380
92894 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
92895 +
92896 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
92897 +
92898 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
92899 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
92900 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
92901 +
92902 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
92903 +#define DMA_LOW_LIODN_MASK 0x00000FFF
92904 +
92905 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
92906 +#define DMA_STATUS_BUS_ERR 0x08000000
92907 +#define DMA_STATUS_READ_ECC 0x04000000
92908 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
92909 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
92910 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
92911 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
92912 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
92913 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
92914 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
92915 +
92916 +#define FM_LIODN_BASE_MASK 0x00000FFF
92917 +
92918 +/* shifts */
92919 +#define DMA_MODE_CACHE_OR_SHIFT 30
92920 +#define DMA_MODE_BUS_PRI_SHIFT 16
92921 +#define DMA_MODE_AXI_DBG_SHIFT 24
92922 +#define DMA_MODE_CEN_SHIFT 13
92923 +#define DMA_MODE_BUS_PROT_SHIFT 10
92924 +#define DMA_MODE_DBG_SHIFT 7
92925 +#define DMA_MODE_EMER_LVL_SHIFT 6
92926 +#define DMA_MODE_AID_MODE_SHIFT 4
92927 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
92928 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
92929 +
92930 +#define DMA_THRESH_COMMQ_SHIFT 24
92931 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
92932 +
92933 +#define DMA_LIODN_SHIFT 16
92934 +
92935 +#define DMA_TRANSFER_PORTID_SHIFT 24
92936 +#define DMA_TRANSFER_TNUM_SHIFT 16
92937 +
92938 +/* sizes */
92939 +#define DMA_MAX_WATCHDOG 0xffffffff
92940 +
92941 +/* others */
92942 +#define DMA_CAM_SIZEOF_ENTRY 0x40
92943 +#define DMA_CAM_ALIGN 0x1000
92944 +#define DMA_CAM_UNITS 8
92945 +
92946 +/**************************************************************************//**
92947 + @Description General defines
92948 +*//***************************************************************************/
92949 +
92950 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
92951 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
92952 +
92953 +/**************************************************************************//**
92954 + @Description FPM defines
92955 +*//***************************************************************************/
92956 +
92957 +/* masks */
92958 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
92959 +#define FPM_EV_MASK_STALL 0x40000000
92960 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
92961 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
92962 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
92963 +#define FPM_EV_MASK_STALL_EN 0x00004000
92964 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
92965 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
92966 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
92967 +
92968 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
92969 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
92970 +#define FPM_RAM_MURAM_ECC 0x00008000
92971 +#define FPM_RAM_IRAM_ECC 0x00004000
92972 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
92973 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
92974 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
92975 +
92976 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
92977 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
92978 +
92979 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
92980 +#define FPM_REV1_MINOR_MASK 0x000000FF
92981 +
92982 +#define FPM_REV2_INTEG_MASK 0x00FF0000
92983 +#define FPM_REV2_ERR_MASK 0x0000FF00
92984 +#define FPM_REV2_CFG_MASK 0x000000FF
92985 +
92986 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
92987 +#define FPM_TS_CTL_EN 0x80000000
92988 +
92989 +#define FPM_PRC_REALSE_STALLED 0x00800000
92990 +
92991 +#define FPM_PS_STALLED 0x00800000
92992 +#define FPM_PS_FM_CTL1_SEL 0x80000000
92993 +#define FPM_PS_FM_CTL2_SEL 0x40000000
92994 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
92995 +
92996 +#define FPM_RSTC_FM_RESET 0x80000000
92997 +#define FPM_RSTC_10G0_RESET 0x04000000
92998 +#define FPM_RSTC_1G0_RESET 0x40000000
92999 +#define FPM_RSTC_1G1_RESET 0x20000000
93000 +#define FPM_RSTC_1G2_RESET 0x10000000
93001 +#define FPM_RSTC_1G3_RESET 0x08000000
93002 +#define FPM_RSTC_1G4_RESET 0x02000000
93003 +
93004 +
93005 +#define FPM_DISP_LIMIT_MASK 0x1F000000
93006 +#define FPM_THR1_PRS_MASK 0xFF000000
93007 +#define FPM_THR1_KG_MASK 0x00FF0000
93008 +#define FPM_THR1_PLCR_MASK 0x0000FF00
93009 +#define FPM_THR1_BMI_MASK 0x000000FF
93010 +
93011 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
93012 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
93013 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
93014 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
93015 +
93016 +/* shifts */
93017 +#define FPM_DISP_LIMIT_SHIFT 24
93018 +
93019 +#define FPM_THR1_PRS_SHIFT 24
93020 +#define FPM_THR1_KG_SHIFT 16
93021 +#define FPM_THR1_PLCR_SHIFT 8
93022 +#define FPM_THR1_BMI_SHIFT 0
93023 +
93024 +#define FPM_THR2_QMI_ENQ_SHIFT 24
93025 +#define FPM_THR2_QMI_DEQ_SHIFT 0
93026 +#define FPM_THR2_FM_CTL1_SHIFT 16
93027 +#define FPM_THR2_FM_CTL2_SHIFT 8
93028 +
93029 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
93030 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
93031 +
93032 +#define FPM_REV1_MAJOR_SHIFT 8
93033 +#define FPM_REV1_MINOR_SHIFT 0
93034 +
93035 +#define FPM_REV2_INTEG_SHIFT 16
93036 +#define FPM_REV2_ERR_SHIFT 8
93037 +#define FPM_REV2_CFG_SHIFT 0
93038 +
93039 +#define FPM_TS_INT_SHIFT 16
93040 +
93041 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
93042 +
93043 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
93044 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
93045 +
93046 +#define FPM_DISP_LIMIT_SHIFT 24
93047 +
93048 +/* Interrupts defines */
93049 +#define FPM_EVENT_FM_CTL_0 0x00008000
93050 +#define FPM_EVENT_FM_CTL 0x0000FF00
93051 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
93052 +
93053 +/* others */
93054 +#define FPM_MAX_DISP_LIMIT 31
93055 +#define FPM_RSTC_FM_RESET 0x80000000
93056 +#define FPM_RSTC_1G0_RESET 0x40000000
93057 +#define FPM_RSTC_1G1_RESET 0x20000000
93058 +#define FPM_RSTC_1G2_RESET 0x10000000
93059 +#define FPM_RSTC_1G3_RESET 0x08000000
93060 +#define FPM_RSTC_10G0_RESET 0x04000000
93061 +#define FPM_RSTC_1G4_RESET 0x02000000
93062 +#define FPM_RSTC_1G5_RESET 0x01000000
93063 +#define FPM_RSTC_1G6_RESET 0x00800000
93064 +#define FPM_RSTC_1G7_RESET 0x00400000
93065 +#define FPM_RSTC_10G1_RESET 0x00200000
93066 +/**************************************************************************//**
93067 + @Description BMI defines
93068 +*//***************************************************************************/
93069 +/* masks */
93070 +#define BMI_INIT_START 0x80000000
93071 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
93072 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
93073 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
93074 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
93075 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
93076 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
93077 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
93078 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
93079 +#define BMI_FIFO_SIZE_MASK 0x000003FF
93080 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
93081 +#define BMI_CFG2_DMAS_MASK 0x0000003F
93082 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
93083 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
93084 +
93085 +/* shifts */
93086 +#define BMI_CFG2_TASKS_SHIFT 16
93087 +#define BMI_CFG2_DMAS_SHIFT 0
93088 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
93089 +#define BMI_FIFO_SIZE_SHIFT 0
93090 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
93091 +#define BMI_NUM_OF_TASKS_SHIFT 24
93092 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
93093 +#define BMI_NUM_OF_DMAS_SHIFT 8
93094 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
93095 +
93096 +/* others */
93097 +#define BMI_FIFO_ALIGN 0x100
93098 +#define FMAN_BMI_FIFO_UNITS 0x100
93099 +
93100 +
93101 +/**************************************************************************//**
93102 + @Description QMI defines
93103 +*//***************************************************************************/
93104 +/* masks */
93105 +#define QMI_CFG_ENQ_EN 0x80000000
93106 +#define QMI_CFG_DEQ_EN 0x40000000
93107 +#define QMI_CFG_EN_COUNTERS 0x10000000
93108 +#define QMI_CFG_SOFT_RESET 0x01000000
93109 +#define QMI_CFG_DEQ_MASK 0x0000003F
93110 +#define QMI_CFG_ENQ_MASK 0x00003F00
93111 +
93112 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
93113 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
93114 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
93115 +
93116 +/* shifts */
93117 +#define QMI_CFG_ENQ_SHIFT 8
93118 +#define QMI_TAPC_TAP 22
93119 +
93120 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
93121 +
93122 +/**************************************************************************//**
93123 + @Description IRAM defines
93124 +*//***************************************************************************/
93125 +/* masks */
93126 +#define IRAM_IADD_AIE 0x80000000
93127 +#define IRAM_READY 0x80000000
93128 +
93129 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
93130 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
93131 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
93132 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
93133 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
93134 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
93135 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
93136 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
93137 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
93138 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
93139 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
93140 + uint8_t event_reg_id);
93141 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
93142 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
93143 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93144 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
93145 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
93146 + uint8_t port_id);
93147 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93148 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
93149 + uint8_t port_id);
93150 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93151 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
93152 + uint8_t port_id);
93153 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
93154 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
93155 + uint8_t reg_id);
93156 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
93157 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
93158 + uint8_t *minor);
93159 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
93160 + enum fman_counters reg_name);
93161 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
93162 +
93163 +
93164 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
93165 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
93166 + uint32_t enable_events);
93167 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
93168 + uint8_t port_id,
93169 + uint8_t num_fman_ctrls,
93170 + uint32_t or_fman_ctrl);
93171 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
93172 + uint8_t port_id,
93173 + bool independent_mode,
93174 + bool is_rx_port);
93175 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93176 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93177 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
93178 + uint8_t port_id,
93179 + uint16_t liodn_base,
93180 + uint16_t liodn_offset);
93181 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
93182 + uint8_t port_id,
93183 + uint32_t size_of_fifo,
93184 + uint32_t extra_size_of_fifo);
93185 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
93186 + uint8_t port_id,
93187 + uint8_t num_of_tasks,
93188 + uint8_t num_of_extra_tasks);
93189 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
93190 + uint8_t port_id,
93191 + uint8_t num_of_open_dmas,
93192 + uint8_t num_of_extra_open_dmas,
93193 + uint8_t total_num_of_dmas);
93194 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
93195 +int fman_set_exception(struct fman_rg *fman_rg,
93196 + enum fman_exceptions exception,
93197 + bool enable);
93198 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
93199 + bool enable);
93200 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
93201 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
93202 + uint32_t congestion_group_id,
93203 + uint8_t piority_bit_map,
93204 + uint32_t reg_num);
93205 +
93206 +
93207 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
93208 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93209 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
93210 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
93211 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
93212 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
93213 +void fman_free_resources(struct fman_rg *fman_rg);
93214 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93215 +void fman_reset(struct fman_fpm_regs *fpm_rg);
93216 +void fman_resume(struct fman_fpm_regs *fpm_rg);
93217 +
93218 +
93219 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
93220 + uint8_t count1ubit,
93221 + uint16_t fm_clk_freq);
93222 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93223 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
93224 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93225 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93226 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
93227 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93228 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
93229 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
93230 +int fman_modify_counter(struct fman_rg *fman_rg,
93231 + enum fman_counters reg_name,
93232 + uint32_t val);
93233 +void fman_force_intr(struct fman_rg *fman_rg,
93234 + enum fman_exceptions exception);
93235 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
93236 + uint8_t port_id,
93237 + uint8_t base_storage_profile,
93238 + uint8_t log2_num_of_profiles);
93239 +
93240 +/**************************************************************************//**
93241 + @Description default values
93242 +*//***************************************************************************/
93243 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
93244 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
93245 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
93246 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
93247 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
93248 +#define DEFAULT_AID_OVERRIDE FALSE
93249 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
93250 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
93251 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
93252 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
93253 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
93254 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
93255 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
93256 +#define DEFAULT_DMA_SOS_EMERGENCY 0
93257 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
93258 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
93259 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
93260 +#define DEFAULT_DISP_LIMIT 0
93261 +#define DEFAULT_PRS_DISP_TH 16
93262 +#define DEFAULT_PLCR_DISP_TH 16
93263 +#define DEFAULT_KG_DISP_TH 16
93264 +#define DEFAULT_BMI_DISP_TH 16
93265 +#define DEFAULT_QMI_ENQ_DISP_TH 16
93266 +#define DEFAULT_QMI_DEQ_DISP_TH 16
93267 +#define DEFAULT_FM_CTL1_DISP_TH 16
93268 +#define DEFAULT_FM_CTL2_DISP_TH 16
93269 +#define DEFAULT_TNUM_AGING_PERIOD 4
93270 +
93271 +
93272 +#endif /* __FSL_FMAN_H */
93273 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93274 new file mode 100644
93275 index 00000000..6004e478
93276 --- /dev/null
93277 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93278 @@ -0,0 +1,1096 @@
93279 +/*
93280 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93281 + *
93282 + * Redistribution and use in source and binary forms, with or without
93283 + * modification, are permitted provided that the following conditions are met:
93284 + * * Redistributions of source code must retain the above copyright
93285 + * notice, this list of conditions and the following disclaimer.
93286 + * * Redistributions in binary form must reproduce the above copyright
93287 + * notice, this list of conditions and the following disclaimer in the
93288 + * documentation and/or other materials provided with the distribution.
93289 + * * Neither the name of Freescale Semiconductor nor the
93290 + * names of its contributors may be used to endorse or promote products
93291 + * derived from this software without specific prior written permission.
93292 + *
93293 + *
93294 + * ALTERNATIVELY, this software may be distributed under the terms of the
93295 + * GNU General Public License ("GPL") as published by the Free Software
93296 + * Foundation, either version 2 of that License or (at your option) any
93297 + * later version.
93298 + *
93299 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93300 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93301 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93302 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93303 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93304 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93305 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93306 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93307 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93308 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93309 + */
93310 +
93311 +#ifndef __FSL_FMAN_DTSEC_H
93312 +#define __FSL_FMAN_DTSEC_H
93313 +
93314 +#include "common/general.h"
93315 +#include "fsl_enet.h"
93316 +
93317 +/**
93318 + * DOC: dTSEC Init sequence
93319 + *
93320 + * To prepare dTSEC block for transfer use the following call sequence:
93321 + *
93322 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
93323 + * use is to obtain the default dTSEC configuration parameters.
93324 + *
93325 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
93326 + * to customize the dTSEC behavior.
93327 + *
93328 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
93329 + * dTSEC is initialized while both Tx and Rx are disabled.
93330 + *
93331 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
93332 + * This is used by dTSEC to match against received packets.
93333 + *
93334 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
93335 + * after the PHY establishes the link.
93336 + *
93337 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
93338 + * reception.
93339 + */
93340 +
93341 +/**
93342 + * DOC: dTSEC Graceful stop
93343 + *
93344 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
93345 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
93346 + * but return before this stop is complete. To query for graceful stop
93347 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
93348 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
93349 + * enable graceful stop interrupts.
93350 + *
93351 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
93352 + * fman_dtsec_start_rx().
93353 + */
93354 +
93355 +/**
93356 + * DOC: dTSEC interrupt handling
93357 + *
93358 + * This code does not provide an interrupt handler for dTSEC. Instead this
93359 + * handler should be implemented and registered to the operating system by the
93360 + * caller. Some primitives for accessing the event status and mask registers
93361 + * are provided.
93362 + *
93363 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
93364 + */
93365 +
93366 +/**
93367 + * DOC: dTSEC Events
93368 + *
93369 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
93370 + * event register at any time to check for pending interrupts. If an event
93371 + * occurs and its corresponding enable bit is set in the interrupt mask
93372 + * register, the event also causes a hardware interrupt at the PIC.
93373 + *
93374 + * To poll for event status use the fman_dtsec_get_event() function.
93375 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
93376 + * fman_dtsec_disable_interrupt() functions.
93377 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
93378 + * serviced event bit.
93379 + *
93380 + * The following events may be signaled by dTSEC hardware:
93381 + *
93382 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
93383 + * a frame was received with length in excess of the MAC's maximum frame length
93384 + * register.
93385 + *
93386 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
93387 + * control frame was received while Rx pause frame handling is enabled.
93388 + * Also see fman_dtsec_handle_rx_pause().
93389 + *
93390 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
93391 + * counters has exceeded the size of its register.
93392 + *
93393 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
93394 + * complete. The transmitter is in a stopped state, in which only pause frames
93395 + * can be transmitted.
93396 + * Also see fman_dtsec_stop_tx().
93397 + *
93398 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
93399 + * has exceeded the value in the MAC's Maximum Frame Length register.
93400 + *
93401 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
93402 + * indicates that a control frame was transmitted.
93403 + *
93404 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
93405 + * occurred on the transmitted channel. This bit is set whenever any transmit
93406 + * error occurs which causes the dTSEC to discard all or part of a frame
93407 + * (LC, CRL, XFUN).
93408 + *
93409 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
93410 + * occurred beyond the collision window (slot time) in half-duplex mode.
93411 + * The frame is truncated with a bad CRC and the remainder of the frame
93412 + * is discarded.
93413 + *
93414 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
93415 + * of successive transmission collisions has exceeded the MAC's half-duplex
93416 + * register's retransmission maximum count. The frame is discarded without
93417 + * being transmitted and transmission of the next frame commences. This only
93418 + * occurs while in half-duplex mode.
93419 + * The number of retransmit attempts can be set in
93420 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
93421 + *
93422 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93423 + * transmit FIFO became empty before the complete frame was transmitted.
93424 + * The frame is truncated with a bad CRC and the remainder of the frame is
93425 + * discarded.
93426 + *
93427 + * %DTSEC_IEVENT_MAG - TBD
93428 + *
93429 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93430 + *
93431 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93432 + *
93433 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93434 + * know if the system has completed the stop and it is safe to write to receive
93435 + * registers (status, control or configuration registers) that are used by the
93436 + * system during normal operation.
93437 + *
93438 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93439 + * that the dTSEC has detected a parity error on its stored transmit data, which
93440 + * is likely to compromise the validity of recently transferred frames.
93441 + *
93442 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93443 + * the dTSEC has detected a parity error on its stored receive data, which is
93444 + * likely to compromise the validity of recently transferred frames.
93445 + */
93446 +/* Interrupt Mask Register (IMASK) */
93447 +#define DTSEC_IMASK_BREN 0x80000000
93448 +#define DTSEC_IMASK_RXCEN 0x40000000
93449 +#define DTSEC_IMASK_MSROEN 0x04000000
93450 +#define DTSEC_IMASK_GTSCEN 0x02000000
93451 +#define DTSEC_IMASK_BTEN 0x01000000
93452 +#define DTSEC_IMASK_TXCEN 0x00800000
93453 +#define DTSEC_IMASK_TXEEN 0x00400000
93454 +#define DTSEC_IMASK_LCEN 0x00040000
93455 +#define DTSEC_IMASK_CRLEN 0x00020000
93456 +#define DTSEC_IMASK_XFUNEN 0x00010000
93457 +#define DTSEC_IMASK_ABRTEN 0x00008000
93458 +#define DTSEC_IMASK_IFERREN 0x00004000
93459 +#define DTSEC_IMASK_MAGEN 0x00000800
93460 +#define DTSEC_IMASK_MMRDEN 0x00000400
93461 +#define DTSEC_IMASK_MMWREN 0x00000200
93462 +#define DTSEC_IMASK_GRSCEN 0x00000100
93463 +#define DTSEC_IMASK_TDPEEN 0x00000002
93464 +#define DTSEC_IMASK_RDPEEN 0x00000001
93465 +
93466 +#define DTSEC_EVENTS_MASK \
93467 + ((uint32_t)(DTSEC_IMASK_BREN | \
93468 + DTSEC_IMASK_RXCEN | \
93469 + DTSEC_IMASK_BTEN | \
93470 + DTSEC_IMASK_TXCEN | \
93471 + DTSEC_IMASK_TXEEN | \
93472 + DTSEC_IMASK_ABRTEN | \
93473 + DTSEC_IMASK_LCEN | \
93474 + DTSEC_IMASK_CRLEN | \
93475 + DTSEC_IMASK_XFUNEN | \
93476 + DTSEC_IMASK_IFERREN | \
93477 + DTSEC_IMASK_MAGEN | \
93478 + DTSEC_IMASK_TDPEEN | \
93479 + DTSEC_IMASK_RDPEEN))
93480 +
93481 +/* dtsec timestamp event bits */
93482 +#define TMR_PEMASK_TSREEN 0x00010000
93483 +#define TMR_PEVENT_TSRE 0x00010000
93484 +
93485 +/* Group address bit indication */
93486 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93487 +/* size in bytes of L2 address */
93488 +#define MAC_ADDRLEN 6
93489 +
93490 +#define DEFAULT_HALFDUP_ON FALSE
93491 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93492 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93493 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93494 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93495 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93496 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93497 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93498 +#define DEFAULT_RX_DROP_BCAST FALSE
93499 +#define DEFAULT_RX_SHORT_FRM TRUE
93500 +#define DEFAULT_RX_LEN_CHECK FALSE
93501 +#define DEFAULT_TX_PAD_CRC TRUE
93502 +#define DEFAULT_TX_CRC FALSE
93503 +#define DEFAULT_RX_CTRL_ACC FALSE
93504 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93505 +#define DEFAULT_TBIPA 5
93506 +#define DEFAULT_RX_PREPEND 0
93507 +#define DEFAULT_PTP_TSU_EN TRUE
93508 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93509 +#define DEFAULT_PREAMBLE_LEN 7
93510 +#define DEFAULT_RX_PREAMBLE FALSE
93511 +#define DEFAULT_TX_PREAMBLE FALSE
93512 +#define DEFAULT_LOOPBACK FALSE
93513 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93514 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93515 +#define DEFAULT_RX_FLOW TRUE
93516 +#define DEFAULT_TX_FLOW TRUE
93517 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93518 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93519 +#define DEFAULT_RX_PROMISC FALSE
93520 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93521 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93522 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93523 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93524 +#define DEFAULT_MAXIMUM_FRAME 0x600
93525 +#define DEFAULT_TBI_PHY_ADDR 5
93526 +#define DEFAULT_WAKE_ON_LAN FALSE
93527 +
93528 +/* register related defines (bits, field offsets..) */
93529 +#define DTSEC_ID1_ID 0xffff0000
93530 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93531 +#define DTSEC_ID1_REV_MN 0x000000ff
93532 +
93533 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93534 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93535 +
93536 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93537 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93538 +#define DTSEC_ECNTRL_STEN 0x00001000
93539 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93540 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93541 +#define DTSEC_ECNTRL_TBIM 0x00000020
93542 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93543 +#define DTSEC_ECNTRL_RPM 0x00000010
93544 +#define DTSEC_ECNTRL_R100M 0x00000008
93545 +#define DTSEC_ECNTRL_RMM 0x00000004
93546 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93547 +
93548 +#define DTSEC_TCTRL_THDF 0x00000800
93549 +#define DTSEC_TCTRL_TTSE 0x00000040
93550 +#define DTSEC_TCTRL_GTS 0x00000020
93551 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93552 +
93553 +/* PTV offsets */
93554 +#define PTV_PTE_OFST 16
93555 +
93556 +#define RCTRL_CFA 0x00008000
93557 +#define RCTRL_GHTX 0x00000400
93558 +#define RCTRL_RTSE 0x00000040
93559 +#define RCTRL_GRS 0x00000020
93560 +#define RCTRL_BC_REJ 0x00000010
93561 +#define RCTRL_MPROM 0x00000008
93562 +#define RCTRL_RSF 0x00000004
93563 +#define RCTRL_UPROM 0x00000001
93564 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93565 +
93566 +#define TMR_CTL_ESFDP 0x00000800
93567 +#define TMR_CTL_ESFDE 0x00000400
93568 +
93569 +#define MACCFG1_SOFT_RESET 0x80000000
93570 +#define MACCFG1_LOOPBACK 0x00000100
93571 +#define MACCFG1_RX_FLOW 0x00000020
93572 +#define MACCFG1_TX_FLOW 0x00000010
93573 +#define MACCFG1_TX_EN 0x00000001
93574 +#define MACCFG1_RX_EN 0x00000004
93575 +#define MACCFG1_RESET_RxMC 0x00080000
93576 +#define MACCFG1_RESET_TxMC 0x00040000
93577 +#define MACCFG1_RESET_RxFUN 0x00020000
93578 +#define MACCFG1_RESET_TxFUN 0x00010000
93579 +
93580 +#define MACCFG2_NIBBLE_MODE 0x00000100
93581 +#define MACCFG2_BYTE_MODE 0x00000200
93582 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93583 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93584 +#define MACCFG2_LENGTH_CHECK 0x00000010
93585 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93586 +#define MACCFG2_PAD_CRC_EN 0x00000004
93587 +#define MACCFG2_CRC_EN 0x00000002
93588 +#define MACCFG2_FULL_DUPLEX 0x00000001
93589 +
93590 +#define PREAMBLE_LENGTH_SHIFT 12
93591 +
93592 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93593 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93594 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93595 +
93596 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93597 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93598 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93599 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93600 +
93601 +#define HAFDUP_ALT_BEB 0x00080000
93602 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93603 +#define HAFDUP_NO_BACKOFF 0x00020000
93604 +#define HAFDUP_EXCESS_DEFER 0x00010000
93605 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93606 +
93607 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93608 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93609 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93610 +
93611 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93612 +
93613 +/* CAR1/2 bits */
93614 +#define DTSEC_CAR1_TR64 0x80000000
93615 +#define DTSEC_CAR1_TR127 0x40000000
93616 +#define DTSEC_CAR1_TR255 0x20000000
93617 +#define DTSEC_CAR1_TR511 0x10000000
93618 +#define DTSEC_CAR1_TRK1 0x08000000
93619 +#define DTSEC_CAR1_TRMAX 0x04000000
93620 +#define DTSEC_CAR1_TRMGV 0x02000000
93621 +
93622 +#define DTSEC_CAR1_RBYT 0x00010000
93623 +#define DTSEC_CAR1_RPKT 0x00008000
93624 +#define DTSEC_CAR1_RFCS 0x00004000
93625 +#define DTSEC_CAR1_RMCA 0x00002000
93626 +#define DTSEC_CAR1_RBCA 0x00001000
93627 +#define DTSEC_CAR1_RXCF 0x00000800
93628 +#define DTSEC_CAR1_RXPF 0x00000400
93629 +#define DTSEC_CAR1_RXUO 0x00000200
93630 +#define DTSEC_CAR1_RALN 0x00000100
93631 +#define DTSEC_CAR1_RFLR 0x00000080
93632 +#define DTSEC_CAR1_RCDE 0x00000040
93633 +#define DTSEC_CAR1_RCSE 0x00000020
93634 +#define DTSEC_CAR1_RUND 0x00000010
93635 +#define DTSEC_CAR1_ROVR 0x00000008
93636 +#define DTSEC_CAR1_RFRG 0x00000004
93637 +#define DTSEC_CAR1_RJBR 0x00000002
93638 +#define DTSEC_CAR1_RDRP 0x00000001
93639 +
93640 +#define DTSEC_CAR2_TJBR 0x00080000
93641 +#define DTSEC_CAR2_TFCS 0x00040000
93642 +#define DTSEC_CAR2_TXCF 0x00020000
93643 +#define DTSEC_CAR2_TOVR 0x00010000
93644 +#define DTSEC_CAR2_TUND 0x00008000
93645 +#define DTSEC_CAR2_TFRG 0x00004000
93646 +#define DTSEC_CAR2_TBYT 0x00002000
93647 +#define DTSEC_CAR2_TPKT 0x00001000
93648 +#define DTSEC_CAR2_TMCA 0x00000800
93649 +#define DTSEC_CAR2_TBCA 0x00000400
93650 +#define DTSEC_CAR2_TXPF 0x00000200
93651 +#define DTSEC_CAR2_TDFR 0x00000100
93652 +#define DTSEC_CAR2_TEDF 0x00000080
93653 +#define DTSEC_CAR2_TSCL 0x00000040
93654 +#define DTSEC_CAR2_TMCL 0x00000020
93655 +#define DTSEC_CAR2_TLCL 0x00000010
93656 +#define DTSEC_CAR2_TXCL 0x00000008
93657 +#define DTSEC_CAR2_TNCL 0x00000004
93658 +#define DTSEC_CAR2_TDRP 0x00000001
93659 +
93660 +#define CAM1_ERRORS_ONLY \
93661 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93662 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93663 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93664 + | DTSEC_CAR1_RDRP)
93665 +
93666 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93667 +
93668 +/*
93669 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93670 + * (or Ethernet) statistics.
93671 + */
93672 +#define CAM1_MIB_GRP_1 \
93673 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93674 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93675 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93676 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93677 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93678 +
93679 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93680 +
93681 +/* memory map */
93682 +
93683 +struct dtsec_regs {
93684 + /* dTSEC General Control and Status Registers */
93685 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93686 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93687 + uint32_t ievent; /* 0x008 Interrupt event register */
93688 + uint32_t imask; /* 0x00C Interrupt mask register */
93689 + uint32_t reserved0010[1];
93690 + uint32_t ecntrl; /* 0x014 E control register */
93691 + uint32_t ptv; /* 0x018 Pause time value register */
93692 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93693 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93694 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93695 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93696 + uint32_t reserved002c[5];
93697 + uint32_t tctrl; /* 0x040 Transmit control register */
93698 + uint32_t reserved0044[3];
93699 + uint32_t rctrl; /* 0x050 Receive control register */
93700 + uint32_t reserved0054[11];
93701 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93702 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93703 + uint32_t reserved00c0[16];
93704 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93705 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93706 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93707 + uint32_t hafdup; /* 0x10C Half-duplex */
93708 + uint32_t maxfrm; /* 0x110 Maximum frame */
93709 + uint32_t reserved0114[10];
93710 + uint32_t ifstat; /* 0x13C Interface status */
93711 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93712 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93713 + struct {
93714 + uint32_t exact_match1; /* octets 1-4 */
93715 + uint32_t exact_match2; /* octets 5-6 */
93716 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93717 + uint32_t reserved01c0[16];
93718 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93719 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93720 + * counter */
93721 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93722 + * counter */
93723 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93724 + * counter */
93725 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93726 + * counter */
93727 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93728 + * counter */
93729 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93730 + * VLAN frame count */
93731 + uint32_t rbyt; /* 0x21C receive byte counter */
93732 + uint32_t rpkt; /* 0x220 receive packet counter */
93733 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93734 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93735 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93736 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93737 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93738 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93739 + uint32_t raln; /* 0x23C receive alignment error counter */
93740 + uint32_t rflr; /* 0x240 receive frame length error counter */
93741 + uint32_t rcde; /* 0x244 receive code error counter */
93742 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93743 + uint32_t rund; /* 0x24C receive undersize packet counter */
93744 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93745 + uint32_t rfrg; /* 0x254 receive fragments counter */
93746 + uint32_t rjbr; /* 0x258 receive jabber counter */
93747 + uint32_t rdrp; /* 0x25C receive drop */
93748 + uint32_t tbyt; /* 0x260 transmit byte counter */
93749 + uint32_t tpkt; /* 0x264 transmit packet counter */
93750 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93751 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93752 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93753 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93754 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93755 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93756 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93757 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93758 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93759 + uint32_t tncl; /* 0x28C transmit total collision counter */
93760 + uint32_t reserved0290[1];
93761 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93762 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93763 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93764 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93765 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93766 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93767 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93768 + uint32_t car1; /* 0x2B0 carry register one register* */
93769 + uint32_t car2; /* 0x2B4 carry register two register* */
93770 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93771 + uint32_t cam2; /* 0x2BC carry register two mask register */
93772 + uint32_t reserved02c0[848];
93773 +};
93774 +
93775 +/**
93776 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93777 + *
93778 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93779 + * good or bad frame, of any type, transmitted or received, which
93780 + * is 64 bytes in length.
93781 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93782 + * each good or bad frame of any type, transmitted or received,
93783 + * which is 65-127 bytes in length.
93784 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93785 + * for each good or bad frame, of any type, transmitted or
93786 + * received, which is 128-255 bytes in length.
93787 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93788 + * for each good or bad frame, of any type, transmitted or
93789 + * received, which is 256-511 bytes in length.
93790 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93791 + * for each good or bad frame, of any type, transmitted or
93792 + * received, which is 512-1023 bytes in length.
93793 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93794 + * for each good or bad frame, of any type, transmitted or
93795 + * received, which is 1024-1518 bytes in length.
93796 + * @rfrg: Receive fragments count. Increments for each received frame
93797 + * which is less than 64 bytes in length and contains an invalid
93798 + * FCS. This includes integral and non-integral lengths.
93799 + * @rjbr: Receive jabber count. Increments for received frames which
93800 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93801 + * invalid FCS. This includes alignment errors.
93802 + * @rdrp: Receive dropped packets count. Increments for received frames
93803 + * which are streamed to system but are later dropped due to lack
93804 + * of system resources. Does not increment for frames rejected due
93805 + * to address filtering.
93806 + * @raln: Receive alignment error count. Increments for each received
93807 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93808 + * an invalid FCS and is not an integral number of bytes.
93809 + * @rund: Receive undersize packet count. Increments each time a frame is
93810 + * received which is less than 64 bytes in length and contains a
93811 + * valid FCS and is otherwise well formed. This count does not
93812 + * include range length errors.
93813 + * @rovr: Receive oversize packet count. Increments each time a frame is
93814 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93815 + * contains a valid FCS and is otherwise well formed.
93816 + * @rbyt: Receive byte count. Increments by the byte count of frames
93817 + * received, including those in bad packets, excluding preamble and
93818 + * SFD but including FCS bytes.
93819 + * @rpkt: Receive packet count. Increments for each received frame
93820 + * (including bad packets, all unicast, broadcast, and multicast
93821 + * packets).
93822 + * @rmca: Receive multicast packet count. Increments for each multicast
93823 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93824 + * 1522 (VLAN), excluding broadcast frames. This count does not
93825 + * include range/length errors.
93826 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93827 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93828 + * 1522 (VLAN), excluding multicast frames. Does not include
93829 + * range/length errors.
93830 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93831 + * or an underrun has occurred.
93832 + * @tncl: Transmit total collision counter. Increments by the number of
93833 + * collisions experienced during the transmission of a frame. Does
93834 + * not increment for aborted frames.
93835 + *
93836 + * The structure contains a group of dTSEC HW specific counters relating to the
93837 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93838 + * is counting only the carry events of the corresponding HW counters.
93839 + *
93840 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93841 + * and SFD but including FCS bytes.
93842 + */
93843 +struct dtsec_mib_grp_1_counters {
93844 + uint64_t rdrp;
93845 + uint64_t tdrp;
93846 + uint64_t rbyt;
93847 + uint64_t rpkt;
93848 + uint64_t rbca;
93849 + uint64_t rmca;
93850 + uint64_t raln;
93851 + uint64_t rund;
93852 + uint64_t rovr;
93853 + uint64_t rfrg;
93854 + uint64_t rjbr;
93855 + uint64_t tncl;
93856 + uint64_t tr64;
93857 + uint64_t tr127;
93858 + uint64_t tr255;
93859 + uint64_t tr511;
93860 + uint64_t tr1k;
93861 + uint64_t trmax;
93862 +};
93863 +
93864 +enum dtsec_stat_counters {
93865 + E_DTSEC_STAT_TR64,
93866 + E_DTSEC_STAT_TR127,
93867 + E_DTSEC_STAT_TR255,
93868 + E_DTSEC_STAT_TR511,
93869 + E_DTSEC_STAT_TR1K,
93870 + E_DTSEC_STAT_TRMAX,
93871 + E_DTSEC_STAT_TRMGV,
93872 + E_DTSEC_STAT_RBYT,
93873 + E_DTSEC_STAT_RPKT,
93874 + E_DTSEC_STAT_RMCA,
93875 + E_DTSEC_STAT_RBCA,
93876 + E_DTSEC_STAT_RXPF,
93877 + E_DTSEC_STAT_RALN,
93878 + E_DTSEC_STAT_RFLR,
93879 + E_DTSEC_STAT_RCDE,
93880 + E_DTSEC_STAT_RCSE,
93881 + E_DTSEC_STAT_RUND,
93882 + E_DTSEC_STAT_ROVR,
93883 + E_DTSEC_STAT_RFRG,
93884 + E_DTSEC_STAT_RJBR,
93885 + E_DTSEC_STAT_RDRP,
93886 + E_DTSEC_STAT_TFCS,
93887 + E_DTSEC_STAT_TBYT,
93888 + E_DTSEC_STAT_TPKT,
93889 + E_DTSEC_STAT_TMCA,
93890 + E_DTSEC_STAT_TBCA,
93891 + E_DTSEC_STAT_TXPF,
93892 + E_DTSEC_STAT_TNCL,
93893 + E_DTSEC_STAT_TDRP
93894 +};
93895 +
93896 +enum dtsec_stat_level {
93897 + /* No statistics */
93898 + E_MAC_STAT_NONE = 0,
93899 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
93900 + E_MAC_STAT_MIB_GRP1,
93901 + /* Only error counters are available. Optimized for performance */
93902 + E_MAC_STAT_PARTIAL,
93903 + /* All counters available. Not optimized for performance */
93904 + E_MAC_STAT_FULL
93905 +};
93906 +
93907 +
93908 +/**
93909 + * struct dtsec_cfg - dTSEC configuration
93910 + *
93911 + * @halfdup_on: Transmit half-duplex flow control, under software
93912 + * control for 10/100-Mbps half-duplex media. If set,
93913 + * back pressure is applied to media by raising carrier.
93914 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
93915 + * If this is exceeded dTSEC aborts transmission due to
93916 + * excessive collisions. The standard specifies the
93917 + * attempt limit to be 15.
93918 + * @halfdup_coll_window:The number of bytes of the frame during which
93919 + * collisions may occur. The default value of 55
93920 + * corresponds to the frame byte at the end of the
93921 + * standard 512-bit slot time window. If collisions are
93922 + * detected after this byte, the late collision event is
93923 + * asserted and transmission of current frame is aborted.
93924 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
93925 + * will be discarded by dTSEC.
93926 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
93927 + * of length 14..63 bytes.
93928 + * @rx_len_check: Length check for received frames. If set, the MAC
93929 + * checks the frame's length field on receive to ensure it
93930 + * matches the actual data field length. This only works
93931 + * for received frames with length field less than 1500.
93932 + * No check is performed for larger frames.
93933 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
93934 + * transmitted short frames and appends a CRC to every
93935 + * frame regardless of padding requirement.
93936 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
93937 + * to all frames. If frames presented to the MAC have a
93938 + * valid length and contain a valid CRC, @tx_crc should be
93939 + * reset.
93940 + * This field is ignored if @tx_pad_crc is set.
93941 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
93942 + * standard control frame behavior, and all Ethernet frames
93943 + * that have an ethertype of 0x8808 are treated as normal
93944 + * Ethernet frames and passed up to the packet interface on
93945 + * a DA match. Received pause control frames are passed to
93946 + * the packet interface only if Rx flow control is also
93947 + * disabled. See fman_dtsec_handle_rx_pause() function.
93948 + * @tx_pause_time: Transmit pause time value. This pause value is used as
93949 + * part of the pause frame to be sent when a transmit pause
93950 + * frame is initiated. If set to 0 this disables
93951 + * transmission of pause frames.
93952 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
93953 + * received Ethernet 7-byte preamble and passes it to the
93954 + * packet interface at the start of each received frame.
93955 + * This field should be reset for internal MAC loop-back
93956 + * mode.
93957 + * @tx_preamble: User defined preamble enable for transmitted frames.
93958 + * If set, a user-defined preamble must passed to the MAC
93959 + * and it is transmitted instead of the standard preamble.
93960 + * @preamble_len: Length, in bytes, of the preamble field preceding each
93961 + * Ethernet start-of-frame delimiter byte. The default
93962 + * value of 0x7 should be used in order to guarantee
93963 + * reliable operation with IEEE 802.3 compliant hardware.
93964 + * @rx_prepend: Packet alignment padding length. The specified number
93965 + * of bytes (1-31) of zero padding are inserted before the
93966 + * start of each received frame. For Ethernet, where
93967 + * optional preamble extraction is enabled, the padding
93968 + * appears before the preamble, otherwise the padding
93969 + * precedes the layer 2 header.
93970 + *
93971 + * This structure contains basic dTSEC configuration and must be passed to
93972 + * fman_dtsec_init() function. A default set of configuration values can be
93973 + * obtained by calling fman_dtsec_defconfig().
93974 + */
93975 +struct dtsec_cfg {
93976 + bool halfdup_on;
93977 + bool halfdup_alt_backoff_en;
93978 + bool halfdup_excess_defer;
93979 + bool halfdup_no_backoff;
93980 + bool halfdup_bp_no_backoff;
93981 + uint8_t halfdup_alt_backoff_val;
93982 + uint16_t halfdup_retransmit;
93983 + uint16_t halfdup_coll_window;
93984 + bool rx_drop_bcast;
93985 + bool rx_short_frm;
93986 + bool rx_len_check;
93987 + bool tx_pad_crc;
93988 + bool tx_crc;
93989 + bool rx_ctrl_acc;
93990 + unsigned short tx_pause_time;
93991 + unsigned short tbipa;
93992 + bool ptp_tsu_en;
93993 + bool ptp_exception_en;
93994 + bool rx_preamble;
93995 + bool tx_preamble;
93996 + unsigned char preamble_len;
93997 + unsigned char rx_prepend;
93998 + bool loopback;
93999 + bool rx_time_stamp_en;
94000 + bool tx_time_stamp_en;
94001 + bool rx_flow;
94002 + bool tx_flow;
94003 + bool rx_group_hash_exd;
94004 + bool rx_promisc;
94005 + uint8_t tbi_phy_addr;
94006 + uint16_t tx_pause_time_extd;
94007 + uint16_t maximum_frame;
94008 + uint32_t non_back_to_back_ipg1;
94009 + uint32_t non_back_to_back_ipg2;
94010 + uint32_t min_ifg_enforcement;
94011 + uint32_t back_to_back_ipg;
94012 + bool wake_on_lan;
94013 +};
94014 +
94015 +
94016 +/**
94017 + * fman_dtsec_defconfig() - Get default dTSEC configuration
94018 + * @cfg: pointer to configuration structure.
94019 + *
94020 + * Call this function to obtain a default set of configuration values for
94021 + * initializing dTSEC. The user can overwrite any of the values before calling
94022 + * fman_dtsec_init(), if specific configuration needs to be applied.
94023 + */
94024 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
94025 +
94026 +/**
94027 + * fman_dtsec_init() - Init dTSEC hardware block
94028 + * @regs: Pointer to dTSEC register block
94029 + * @cfg: dTSEC configuration data
94030 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
94031 + * @iface_speed: 1G or 10G
94032 + * @macaddr: MAC station address to be assigned to the device
94033 + * @fm_rev_maj: major rev number
94034 + * @fm_rev_min: minor rev number
94035 + * @exceptions_mask: initial exceptions mask
94036 + *
94037 + * This function initializes dTSEC and applies basic configuration.
94038 + *
94039 + * dTSEC initialization sequence:
94040 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
94041 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
94042 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
94043 + *
94044 + * Returns: 0 if successful, an error code otherwise.
94045 + */
94046 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
94047 + enum enet_interface iface_mode,
94048 + enum enet_speed iface_speed,
94049 + uint8_t *macaddr, uint8_t fm_rev_maj,
94050 + uint8_t fm_rev_min,
94051 + uint32_t exception_mask);
94052 +
94053 +/**
94054 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
94055 + * @regs: Pointer to dTSEC register block
94056 + * @apply_rx: enable rx side
94057 + * @apply_tx: enable tx side
94058 + *
94059 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
94060 + */
94061 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94062 +
94063 +/**
94064 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
94065 + * @regs: Pointer to dTSEC register block
94066 + * @apply_rx: disable rx side
94067 + * @apply_tx: disable tx side
94068 + *
94069 + * This function disables Tx and Rx in dTSEC.
94070 + */
94071 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94072 +
94073 +/**
94074 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
94075 + * @regs: Pointer to dTSEC register block
94076 + *
94077 + * Returns dtsec_id content
94078 + *
94079 + * Call this function to obtain the dTSEC hardware version.
94080 + */
94081 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
94082 +
94083 +/**
94084 + * fman_dtsec_set_mac_address() - Set MAC station address
94085 + * @regs: Pointer to dTSEC register block
94086 + * @macaddr: MAC address array
94087 + *
94088 + * This function sets MAC station address. To enable unicast reception call
94089 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
94090 + * match the destination address of received unicast frames against this
94091 + * address.
94092 + */
94093 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94094 +
94095 +/**
94096 + * fman_dtsec_get_mac_address() - Query MAC station address
94097 + * @regs: Pointer to dTSEC register block
94098 + * @macaddr: MAC address array
94099 + */
94100 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94101 +
94102 +/**
94103 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
94104 + * @regs: Pointer to dTSEC register block
94105 + * @enable: Enable unicast promiscuous mode
94106 + *
94107 + * Use this function to enable/disable dTSEC L2 address filtering. If the
94108 + * address filtering is disabled all unicast packets are accepted.
94109 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
94110 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
94111 + * multicast addresses.
94112 + */
94113 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
94114 +
94115 +/**
94116 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
94117 + * (magic packet support)
94118 + * @regs: Pointer to dTSEC register block
94119 + * @en: Enable Wake On Lan support in dTSEC
94120 + *
94121 + */
94122 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
94123 +
94124 +/**
94125 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
94126 + * @regs: Pointer to dTSEC register block
94127 + * @iface_mode: dTSEC interface mode
94128 + * @speed: Link speed
94129 + * @full_dx: True for full-duplex, false for half-duplex.
94130 + *
94131 + * This function configures the MAC to function and the desired rates. Use it
94132 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
94133 + * changes (for instance following PHY auto-negociation).
94134 + *
94135 + * Returns: 0 if successful, an error code otherwise.
94136 + */
94137 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
94138 + enum enet_interface iface_mode,
94139 + enum enet_speed speed, bool full_dx);
94140 +
94141 +/**
94142 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
94143 + * @regs: Pointer to dTSEC register block
94144 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
94145 + *
94146 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
94147 + * so that the associated TBI PHY (i.e. the link) may be initialized.
94148 + *
94149 + * Returns: 0 if successful, an error code otherwise.
94150 + */
94151 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
94152 + uint8_t addr);
94153 +
94154 +/**
94155 + * fman_dtsec_set_max_frame_len() - Set max frame length
94156 + * @regs: Pointer to dTSEC register block
94157 + * @length: Max frame length.
94158 + *
94159 + * Sets maximum frame length for received and transmitted frames. Frames that
94160 + * exceeds this length are truncated.
94161 + */
94162 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
94163 +
94164 +/**
94165 + * fman_dtsec_get_max_frame_len() - Query max frame length
94166 + * @regs: Pointer to dTSEC register block
94167 + *
94168 + * Returns: the current value of the maximum frame length.
94169 + */
94170 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
94171 +
94172 +/**
94173 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
94174 + * @regs: Pointer to dTSEC register block
94175 + * @en: Enable pause frame handling in dTSEC
94176 + *
94177 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
94178 + * if dTSEC is set in half-duplex mode.
94179 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
94180 + * frames will be transferred to the packet interface just like regular Ethernet
94181 + * frames.
94182 + */
94183 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
94184 +
94185 +/**
94186 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
94187 + * @regs: Pointer to dTSEC register block
94188 + * @time: Time value included in pause frames
94189 + *
94190 + * Call this function to set the time value used in transmitted pause frames.
94191 + * If time is 0, transmission of pause frames is disabled
94192 + */
94193 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
94194 +
94195 +/**
94196 + * fman_dtsec_ack_event() - Acknowledge handled events
94197 + * @regs: Pointer to dTSEC register block
94198 + * @ev_mask: Events to acknowledge
94199 + *
94200 + * After handling events signaled by dTSEC in either polling or interrupt mode,
94201 + * call this function to reset the associated status bits in dTSEC event
94202 + * register.
94203 + */
94204 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
94205 +
94206 +/**
94207 + * fman_dtsec_get_event() - Returns currently asserted events
94208 + * @regs: Pointer to dTSEC register block
94209 + * @ev_mask: Mask of relevant events
94210 + *
94211 + * Call this function to obtain a bit-mask of events that are currently asserted
94212 + * in dTSEC, taken from IEVENT register.
94213 + *
94214 + * Returns: a bit-mask of events asserted in dTSEC.
94215 + */
94216 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
94217 +
94218 +/**
94219 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
94220 + * @regs: Pointer to dTSEC register block
94221 + *
94222 + * Call this function to obtain a bit-mask of enabled interrupts
94223 + * in dTSEC, taken from IMASK register.
94224 + *
94225 + * Returns: a bit-mask of enabled interrupts in dTSEC.
94226 + */
94227 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
94228 +
94229 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
94230 + uint8_t paddr_num);
94231 +
94232 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
94233 + uint64_t addr,
94234 + uint8_t paddr_num);
94235 +
94236 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
94237 +
94238 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
94239 +
94240 +/**
94241 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
94242 + * @regs: Pointer to dTSEC register block
94243 + * @ev_mask: Mask of relevant events
94244 + *
94245 + * Call this function to disable interrupts in dTSEC for the specified events.
94246 + * To enable interrupts use fman_dtsec_enable_interrupt().
94247 + */
94248 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94249 +
94250 +/**
94251 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
94252 + * @regs: Pointer to dTSEC register block
94253 + * @ev_mask: Mask of relevant events
94254 + *
94255 + * Call this function to enable interrupts in dTSEC for the specified events.
94256 + * To disable interrupts use fman_dtsec_disable_interrupt().
94257 + */
94258 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94259 +
94260 +/**
94261 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
94262 + * @regs: Pointer to dTSEC register block
94263 + * @en: true to enable timestamps, false to disable them
94264 + *
94265 + * Call this function to enable/disable dTSEC timestamps. This affects both
94266 + * Tx and Rx.
94267 + */
94268 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
94269 +
94270 +/**
94271 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
94272 + * @regs: Pointer to dTSEC register block
94273 + * @bucket: Bucket index
94274 + * @enable: true/false to enable/disable this bucket
94275 + *
94276 + * This function enables or disables the specified bucket. Enabling a bucket
94277 + * associated with an address configures dTSEC to accept received packets
94278 + * with that destination address.
94279 + * Multiple addresses may be associated with the same bucket. Disabling a
94280 + * bucket will affect all addresses associated with that bucket. A bucket that
94281 + * is enabled requires further filtering and verification in the upper layers
94282 + *
94283 + */
94284 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
94285 +
94286 +/**
94287 + * dtsec_set_hash_table() - insert a crc code into thr filter table
94288 + * @regs: Pointer to dTSEC register block
94289 + * @crc: crc to insert
94290 + * @mcast: true is this is a multicast address
94291 + * @ghtx: true if we are in ghtx mode
94292 + *
94293 + * This function inserts a crc code into the filter table.
94294 + */
94295 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
94296 + bool mcast, bool ghtx);
94297 +
94298 +/**
94299 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
94300 + * @regs: Pointer to dTSEC register block
94301 + * @mcast: Reset multicast entries
94302 + * @ucast: Reset unicast entries
94303 + *
94304 + * Resets all entries in L2 address filter table. After calling this function
94305 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
94306 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
94307 + * @ucast argument is ignored.
94308 + * This does not affect the primary nor the 15 additional addresses configured
94309 + * using dtsec_set_address() or dtsec_set_match_address().
94310 + */
94311 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
94312 + bool ucast);
94313 +
94314 +/**
94315 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
94316 + * @regs: Pointer to dTSEC register block
94317 + * @enable: Enable multicast promiscuous mode
94318 + *
94319 + * Call this to enable/disable L2 address filtering for multicast packets.
94320 + */
94321 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
94322 +
94323 +/* statistics APIs */
94324 +
94325 +/**
94326 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
94327 + * @regs: Pointer to dTSEC register block
94328 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
94329 + * to specify all the existing counters.
94330 + * If set to _none_, it disables all the counters.
94331 + *
94332 + * Enables the MIB statistics hw counters and sets up the carry interrupt
94333 + * masks for the counters corresponding to the @level input parameter.
94334 + *
94335 + * Returns: error if invalid @level value given.
94336 + */
94337 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
94338 + enum dtsec_stat_level level);
94339 +
94340 +/**
94341 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
94342 + * @regs: Pointer to dTSEC register block
94343 + */
94344 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
94345 +
94346 +/**
94347 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
94348 + * @regs: Pointer to dTSEC register block
94349 + * @car1: car1 register value
94350 + * @car2: car2 register value
94351 + *
94352 + * When set, the carry bits signal that an overflow occurred on the
94353 + * corresponding counters.
94354 + * Note that the carry bits (CAR1-2 registers) will assert the
94355 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
94356 + *
94357 + * Returns: true if overflow occurred, otherwise - false
94358 + */
94359 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
94360 + uint32_t *car1, uint32_t *car2);
94361 +
94362 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
94363 +
94364 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
94365 + enum dtsec_stat_counters reg_name);
94366 +
94367 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
94368 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
94369 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
94370 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
94371 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
94372 +
94373 +
94374 +#endif /* __FSL_FMAN_DTSEC_H */
94375 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94376 new file mode 100644
94377 index 00000000..0dda09c3
94378 --- /dev/null
94379 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94380 @@ -0,0 +1,107 @@
94381 +/*
94382 + * Copyright 2008-2013 Freescale Semiconductor Inc.
94383 + *
94384 + * Redistribution and use in source and binary forms, with or without
94385 + * modification, are permitted provided that the following conditions are met:
94386 + * * Redistributions of source code must retain the above copyright
94387 + * notice, this list of conditions and the following disclaimer.
94388 + * * Redistributions in binary form must reproduce the above copyright
94389 + * notice, this list of conditions and the following disclaimer in the
94390 + * documentation and/or other materials provided with the distribution.
94391 + * * Neither the name of Freescale Semiconductor nor the
94392 + * names of its contributors may be used to endorse or promote products
94393 + * derived from this software without specific prior written permission.
94394 + *
94395 + *
94396 + * ALTERNATIVELY, this software may be distributed under the terms of the
94397 + * GNU General Public License ("GPL") as published by the Free Software
94398 + * Foundation, either version 2 of that License or (at your option) any
94399 + * later version.
94400 + *
94401 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94402 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94403 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94404 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94405 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94406 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94407 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94408 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94409 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94410 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94411 + */
94412 +
94413 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
94414 +#define __FSL_FMAN_DTSEC_MII_ACC_H
94415 +
94416 +#include "common/general.h"
94417 +
94418 +
94419 +/* MII Management Configuration Register */
94420 +#define MIIMCFG_RESET_MGMT 0x80000000
94421 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
94422 +#define MIIMCFG_MGNTCLK_SHIFT 0
94423 +
94424 +/* MII Management Command Register */
94425 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94426 +#define MIIMCOM_READ_CYCLE 0x00000001
94427 +
94428 +/* MII Management Address Register */
94429 +#define MIIMADD_PHY_ADDR_SHIFT 8
94430 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94431 +
94432 +#define MIIMADD_REG_ADDR_SHIFT 0
94433 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94434 +
94435 +/* MII Management Indicator Register */
94436 +#define MIIMIND_BUSY 0x00000001
94437 +
94438 +
94439 +/* PHY Control Register */
94440 +#define PHY_CR_PHY_RESET 0x8000
94441 +#define PHY_CR_LOOPBACK 0x4000
94442 +#define PHY_CR_SPEED0 0x2000
94443 +#define PHY_CR_ANE 0x1000
94444 +#define PHY_CR_RESET_AN 0x0200
94445 +#define PHY_CR_FULLDUPLEX 0x0100
94446 +#define PHY_CR_SPEED1 0x0040
94447 +
94448 +#define PHY_TBICON_SRESET 0x8000
94449 +#define PHY_TBICON_SPEED2 0x0020
94450 +#define PHY_TBICON_CLK_SEL 0x0020
94451 +#define PHY_TBIANA_SGMII 0x4001
94452 +#define PHY_TBIANA_1000X 0x01a0
94453 +/* register map */
94454 +
94455 +/* MII Configuration Control Memory Map Registers */
94456 +struct dtsec_mii_reg {
94457 + uint32_t reserved1[72];
94458 + uint32_t miimcfg; /* MII Mgmt:configuration */
94459 + uint32_t miimcom; /* MII Mgmt:command */
94460 + uint32_t miimadd; /* MII Mgmt:address */
94461 + uint32_t miimcon; /* MII Mgmt:control 3 */
94462 + uint32_t miimstat; /* MII Mgmt:status */
94463 + uint32_t miimind; /* MII Mgmt:indicators */
94464 +};
94465 +
94466 +/* dTSEC MII API */
94467 +
94468 +/* functions to access the mii registers for phy configuration.
94469 + * this functionality may not be available for all dtsecs in the system.
94470 + * consult the reference manual for details */
94471 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94472 +/* frequency is in MHz.
94473 + * note that dtsec clock is 1/2 of fman clock */
94474 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94475 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94476 + uint8_t addr,
94477 + uint8_t reg,
94478 + uint16_t data,
94479 + uint16_t dtsec_freq);
94480 +
94481 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94482 + uint8_t addr,
94483 + uint8_t reg,
94484 + uint16_t *data,
94485 + uint16_t dtsec_freq);
94486 +
94487 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94488 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94489 new file mode 100644
94490 index 00000000..010e4b70
94491 --- /dev/null
94492 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94493 @@ -0,0 +1,514 @@
94494 +/*
94495 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94496 + *
94497 + * Redistribution and use in source and binary forms, with or without
94498 + * modification, are permitted provided that the following conditions are met:
94499 + * * Redistributions of source code must retain the above copyright
94500 + * notice, this list of conditions and the following disclaimer.
94501 + * * Redistributions in binary form must reproduce the above copyright
94502 + * notice, this list of conditions and the following disclaimer in the
94503 + * documentation and/or other materials provided with the distribution.
94504 + * * Neither the name of Freescale Semiconductor nor the
94505 + * names of its contributors may be used to endorse or promote products
94506 + * derived from this software without specific prior written permission.
94507 + *
94508 + *
94509 + * ALTERNATIVELY, this software may be distributed under the terms of the
94510 + * GNU General Public License ("GPL") as published by the Free Software
94511 + * Foundation, either version 2 of that License or (at your option) any
94512 + * later version.
94513 + *
94514 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94515 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94516 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94517 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94518 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94519 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94520 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94521 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94522 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94523 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94524 + */
94525 +
94526 +#ifndef __FSL_FMAN_KG_H
94527 +#define __FSL_FMAN_KG_H
94528 +
94529 +#include "common/general.h"
94530 +
94531 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94532 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94533 +/**< Total num of masks allowed on KG extractions */
94534 +#define FM_KG_EXTRACT_MASKS_NUM 4
94535 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94536 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94537 +
94538 +struct fman_kg_regs {
94539 + uint32_t fmkg_gcr;
94540 + uint32_t res004;
94541 + uint32_t res008;
94542 + uint32_t fmkg_eer;
94543 + uint32_t fmkg_eeer;
94544 + uint32_t res014;
94545 + uint32_t res018;
94546 + uint32_t fmkg_seer;
94547 + uint32_t fmkg_seeer;
94548 + uint32_t fmkg_gsr;
94549 + uint32_t fmkg_tpc;
94550 + uint32_t fmkg_serc;
94551 + uint32_t res030[4];
94552 + uint32_t fmkg_fdor;
94553 + uint32_t fmkg_gdv0r;
94554 + uint32_t fmkg_gdv1r;
94555 + uint32_t res04c[6];
94556 + uint32_t fmkg_feer;
94557 + uint32_t res068[38];
94558 + uint32_t fmkg_indirect[63];
94559 + uint32_t fmkg_ar;
94560 +};
94561 +
94562 +struct fman_kg_scheme_regs {
94563 + uint32_t kgse_mode; /**< MODE */
94564 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94565 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94566 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94567 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94568 + uint32_t kgse_fqb; /**< Frame Queue Base */
94569 + uint32_t kgse_hc; /**< Hash Command */
94570 + uint32_t kgse_ppc; /**< Policer Profile Command */
94571 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94572 + /**< Generic Extract Command */
94573 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94574 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94575 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94576 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94577 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94578 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94579 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94580 +};
94581 +
94582 +struct fman_kg_pe_regs{
94583 + uint32_t fmkg_pe_sp;
94584 + uint32_t fmkg_pe_cpp;
94585 +};
94586 +
94587 +struct fman_kg_cp_regs {
94588 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94589 +};
94590 +
94591 +
94592 +#define FM_KG_KGAR_GO 0x80000000
94593 +#define FM_KG_KGAR_READ 0x40000000
94594 +#define FM_KG_KGAR_WRITE 0x00000000
94595 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94596 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94597 +
94598 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94599 +#define KG_SCH_PP_NO_GEN 0x10000000
94600 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94601 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94602 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94603 +#define KG_SCH_BITMASK_MASK 0x000000FF
94604 +#define KG_SCH_GEN_VALID 0x80000000
94605 +#define KG_SCH_GEN_MASK 0x00FF0000
94606 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94607 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94608 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94609 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94610 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94611 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94612 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94613 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94614 +
94615 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94616 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94617 +
94618 +/* ECC capture register */
94619 +#define KG_FMKG_SERC_CAP 0x80000000
94620 +#define KG_FMKG_SERC_CET 0x40000000
94621 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94622 +#define KG_FMKG_SERC_CNT_SHIFT 16
94623 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94624 +
94625 +/* Masks */
94626 +#define FM_KG_KGGCR_EN 0x80000000
94627 +#define KG_SCH_GEN_VALID 0x80000000
94628 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94629 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94630 +#define KG_ERR_ADDR_MASK 0x00000FFF
94631 +#define KG_SCH_MODE_EN 0x80000000
94632 +
94633 +/* shifts */
94634 +#define FM_KG_KGAR_NUM_SHIFT 16
94635 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94636 +#define FM_KG_KGAR_WSEL_SHIFT 8
94637 +
94638 +#define FM_KG_SCH_GEN_HT_INVALID 0
94639 +
94640 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94641 +
94642 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94643 +switch (i) \
94644 +{ \
94645 + case 0: (shift) = 26; break; \
94646 + case 1: (shift) = 20; break; \
94647 + case 2: (shift) = 10; break; \
94648 + case 3: (shift) = 4; break; \
94649 + default: (shift) = 0; \
94650 +}
94651 +
94652 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94653 +switch (i) \
94654 +{ \
94655 + case 0: (shift) = 16; break; \
94656 + case 1: (shift) = 0; break; \
94657 + case 2: (shift) = 28; break; \
94658 + case 3: (shift) = 24; break; \
94659 + default: (shift) = 0; \
94660 +}
94661 +
94662 +#define KG_GET_MASK_SHIFT(shift, i) \
94663 +switch (i) \
94664 +{ \
94665 + case 0: shift = 24; break; \
94666 + case 1: shift = 16; break; \
94667 + case 2: shift = 8; break; \
94668 + case 3: shift = 0; break; \
94669 + default: shift = 0; \
94670 +}
94671 +
94672 +/* Port entry CPP register */
94673 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94674 +
94675 +/* Scheme registers */
94676 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94677 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94678 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94679 +
94680 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94681 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94682 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94683 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94684 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94685 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94686 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94687 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94688 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94689 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94690 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94691 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94692 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94693 +
94694 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94695 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94696 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94697 +
94698 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94699 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94700 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94701 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94702 +
94703 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94704 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94705 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94706 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94707 +
94708 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94709 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94710 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94711 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94712 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94713 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94714 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94715 +
94716 +enum fman_kg_gen_extract_src {
94717 + E_FMAN_KG_GEN_EXTRACT_ETH,
94718 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94719 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94720 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94721 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94722 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94723 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94724 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94725 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94726 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94727 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94728 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94729 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94730 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94731 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94732 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94733 + E_FMAN_KG_GEN_EXTRACT_GRE,
94734 + E_FMAN_KG_GEN_EXTRACT_TCP,
94735 + E_FMAN_KG_GEN_EXTRACT_UDP,
94736 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94737 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94738 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94739 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94740 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94741 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94742 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94743 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94744 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94745 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94746 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94747 +};
94748 +
94749 +struct fman_kg_ex_ecc_attr
94750 +{
94751 + bool valid;
94752 + bool double_ecc;
94753 + uint16_t addr;
94754 + uint8_t single_ecc_count;
94755 +};
94756 +
94757 +enum fman_kg_def_select
94758 +{
94759 + E_FMAN_KG_DEF_GLOBAL_0,
94760 + E_FMAN_KG_DEF_GLOBAL_1,
94761 + E_FMAN_KG_DEF_SCHEME_0,
94762 + E_FMAN_KG_DEF_SCHEME_1
94763 +};
94764 +
94765 +struct fman_kg_extract_def
94766 +{
94767 + enum fman_kg_def_select mac_addr;
94768 + enum fman_kg_def_select vlan_tci;
94769 + enum fman_kg_def_select etype;
94770 + enum fman_kg_def_select ppp_sid;
94771 + enum fman_kg_def_select ppp_pid;
94772 + enum fman_kg_def_select mpls;
94773 + enum fman_kg_def_select ip_addr;
94774 + enum fman_kg_def_select ptype;
94775 + enum fman_kg_def_select ip_tos_tc;
94776 + enum fman_kg_def_select ipv6_fl;
94777 + enum fman_kg_def_select ipsec_spi;
94778 + enum fman_kg_def_select l4_port;
94779 + enum fman_kg_def_select tcp_flg;
94780 +};
94781 +
94782 +enum fman_kg_gen_extract_type
94783 +{
94784 + E_FMAN_KG_HASH_EXTRACT,
94785 + E_FMAN_KG_OR_EXTRACT
94786 +};
94787 +
94788 +struct fman_kg_gen_extract_params
94789 +{
94790 + /* Hash or Or-ed extract */
94791 + enum fman_kg_gen_extract_type type;
94792 + enum fman_kg_gen_extract_src src;
94793 + bool no_validation;
94794 + /* Extraction offset from the header location specified above */
94795 + uint8_t offset;
94796 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94797 + * hash result shift for FMAN_KG_OR_EXTRACT */
94798 + uint8_t extract;
94799 + uint8_t mask;
94800 + /* Default value to use when header specified
94801 + * by fman_kg_gen_extract_src doesn't present */
94802 + enum fman_kg_def_select def_val;
94803 +};
94804 +
94805 +struct fman_kg_extract_mask
94806 +{
94807 + /**< Indication if mask is on known field extraction or
94808 + * on general extraction; TRUE for known field */
94809 + bool is_known;
94810 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94811 + * generic register index for generic extracts mask */
94812 + uint32_t field_or_gen_idx;
94813 + /**< Byte offset from start of the extracted data specified
94814 + * by field_or_gen_idx */
94815 + uint8_t offset;
94816 + /**< Byte mask (selected bits will be used) */
94817 + uint8_t mask;
94818 +};
94819 +
94820 +struct fman_kg_extract_params
94821 +{
94822 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94823 + uint32_t known_fields;
94824 + struct fman_kg_extract_def known_fields_def;
94825 + /* Number of entries in gen_extract */
94826 + uint8_t gen_extract_num;
94827 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94828 + /* Number of entries in masks */
94829 + uint8_t masks_num;
94830 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94831 + uint32_t def_scheme_0;
94832 + uint32_t def_scheme_1;
94833 +};
94834 +
94835 +struct fman_kg_hash_params
94836 +{
94837 + bool use_hash;
94838 + uint8_t shift_r;
94839 + uint32_t mask; /**< 24-bit mask */
94840 + bool sym; /**< Symmetric hash for src and dest pairs */
94841 +};
94842 +
94843 +struct fman_kg_pp_params
94844 +{
94845 + uint8_t base;
94846 + uint8_t shift;
94847 + uint8_t mask;
94848 + bool bypass_pp_gen;
94849 +};
94850 +
94851 +struct fman_kg_cc_params
94852 +{
94853 + uint8_t base_offset;
94854 + uint32_t qlcv_bits_sel;
94855 +};
94856 +
94857 +enum fman_pcd_engine
94858 +{
94859 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
94860 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
94861 + E_FMAN_PCD_KG, /**< Keygen indicated */
94862 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
94863 + E_FMAN_PCD_PLCR, /**< Policer indicated */
94864 + E_FMAN_PCD_PRS /**< Parser indicated */
94865 +};
94866 +
94867 +struct fman_kg_cls_plan_params
94868 +{
94869 + uint8_t entries_mask;
94870 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
94871 +};
94872 +
94873 +struct fman_kg_scheme_params
94874 +{
94875 + uint32_t match_vector;
94876 + struct fman_kg_extract_params extract_params;
94877 + struct fman_kg_hash_params hash_params;
94878 + uint32_t base_fqid;
94879 + /* What we do w/features supported per FM version ?? */
94880 + bool bypass_fqid_gen;
94881 + struct fman_kg_pp_params policer_params;
94882 + struct fman_kg_cc_params cc_params;
94883 + bool update_counter;
94884 + /**< counter_value: Set scheme counter to the specified value;
94885 + * relevant only when update_counter = TRUE. */
94886 + uint32_t counter_value;
94887 + enum fman_pcd_engine next_engine;
94888 + /**< Next engine action code */
94889 + uint32_t next_engine_action;
94890 +};
94891 +
94892 +
94893 +
94894 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
94895 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
94896 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
94897 +void fman_kg_get_event(struct fman_kg_regs *regs,
94898 + uint32_t *event,
94899 + uint32_t *scheme_idx);
94900 +void fman_kg_init(struct fman_kg_regs *regs,
94901 + uint32_t exceptions,
94902 + uint32_t dflt_nia);
94903 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
94904 +void fman_kg_enable(struct fman_kg_regs *regs);
94905 +void fman_kg_disable(struct fman_kg_regs *regs);
94906 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
94907 + uint8_t hwport_id,
94908 + uint32_t bind_cls_plans);
94909 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
94910 + uint8_t grp_mask,
94911 + uint32_t *bind_cls_plans);
94912 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
94913 + uint8_t hwport_id,
94914 + uint32_t schemes);
94915 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
94916 + uint8_t grp_id,
94917 + uint8_t entries_mask,
94918 + uint8_t hwport_id,
94919 + struct fman_kg_cp_regs *cls_plan_regs);
94920 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
94921 + struct fman_kg_cp_regs *cls_plan_regs);
94922 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
94923 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
94924 + uint8_t scheme_id,
94925 + uint8_t hwport_id,
94926 + uint32_t counter);
94927 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
94928 + uint8_t scheme_id,
94929 + uint8_t hwport_id,
94930 + uint32_t *counter);
94931 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
94932 + uint8_t scheme_id,
94933 + uint8_t hwport_id);
94934 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
94935 + uint8_t scheme_id,
94936 + uint8_t hwport_id,
94937 + struct fman_kg_scheme_regs *scheme_regs,
94938 + bool update_counter);
94939 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
94940 + struct fman_kg_scheme_regs *scheme_regs);
94941 +void fman_kg_get_capture(struct fman_kg_regs *regs,
94942 + struct fman_kg_ex_ecc_attr *ecc_attr,
94943 + bool clear);
94944 +void fman_kg_get_exception(struct fman_kg_regs *regs,
94945 + uint32_t *events,
94946 + uint32_t *scheme_ids,
94947 + bool clear);
94948 +void fman_kg_set_exception(struct fman_kg_regs *regs,
94949 + uint32_t exception,
94950 + bool enable);
94951 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
94952 + uint8_t def_id,
94953 + uint32_t val);
94954 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
94955 +
94956 +
94957 +
94958 +/**************************************************************************//**
94959 + @Description NIA Description
94960 +*//***************************************************************************/
94961 +#define KG_NIA_ORDER_RESTOR 0x00800000
94962 +#define KG_NIA_ENG_FM_CTL 0x00000000
94963 +#define KG_NIA_ENG_PRS 0x00440000
94964 +#define KG_NIA_ENG_KG 0x00480000
94965 +#define KG_NIA_ENG_PLCR 0x004C0000
94966 +#define KG_NIA_ENG_BMI 0x00500000
94967 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
94968 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
94969 +#define KG_NIA_ENG_MASK 0x007C0000
94970 +
94971 +#define KG_NIA_AC_MASK 0x0003FFFF
94972 +
94973 +#define KG_NIA_INVALID 0xFFFFFFFF
94974 +
94975 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
94976 + uint32_t next_engine_action)
94977 +{
94978 + uint32_t nia;
94979 +
94980 + if (next_engine_action & ~KG_NIA_AC_MASK)
94981 + return KG_NIA_INVALID;
94982 +
94983 + switch (next_engine) {
94984 + case E_FMAN_PCD_DONE:
94985 + nia = KG_NIA_ENG_BMI | next_engine_action;
94986 + break;
94987 +
94988 + case E_FMAN_PCD_KG:
94989 + nia = KG_NIA_ENG_KG | next_engine_action;
94990 + break;
94991 +
94992 + case E_FMAN_PCD_CC:
94993 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
94994 + break;
94995 +
94996 + case E_FMAN_PCD_PLCR:
94997 + nia = KG_NIA_ENG_PLCR | next_engine_action;
94998 + break;
94999 +
95000 + default:
95001 + nia = KG_NIA_INVALID;
95002 + }
95003 +
95004 + return nia;
95005 +}
95006 +
95007 +#endif /* __FSL_FMAN_KG_H */
95008 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
95009 new file mode 100644
95010 index 00000000..0dd8286b
95011 --- /dev/null
95012 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
95013 @@ -0,0 +1,427 @@
95014 +/*
95015 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95016 + *
95017 + * Redistribution and use in source and binary forms, with or without
95018 + * modification, are permitted provided that the following conditions are met:
95019 + * * Redistributions of source code must retain the above copyright
95020 + * notice, this list of conditions and the following disclaimer.
95021 + * * Redistributions in binary form must reproduce the above copyright
95022 + * notice, this list of conditions and the following disclaimer in the
95023 + * documentation and/or other materials provided with the distribution.
95024 + * * Neither the name of Freescale Semiconductor nor the
95025 + * names of its contributors may be used to endorse or promote products
95026 + * derived from this software without specific prior written permission.
95027 + *
95028 + *
95029 + * ALTERNATIVELY, this software may be distributed under the terms of the
95030 + * GNU General Public License ("GPL") as published by the Free Software
95031 + * Foundation, either version 2 of that License or (at your option) any
95032 + * later version.
95033 + *
95034 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95035 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95036 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95037 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95038 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95039 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95040 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95041 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95042 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95043 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95044 + */
95045 +
95046 +
95047 +#ifndef __FSL_FMAN_MEMAC_H
95048 +#define __FSL_FMAN_MEMAC_H
95049 +
95050 +#include "common/general.h"
95051 +#include "fsl_enet.h"
95052 +
95053 +
95054 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
95055 +
95056 +/* Control and Configuration Register (COMMAND_CONFIG) */
95057 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
95058 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
95059 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
95060 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
95061 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
95062 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
95063 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
95064 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
95065 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
95066 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
95067 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
95068 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
95069 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
95070 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
95071 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
95072 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
95073 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
95074 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
95075 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
95076 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
95077 +
95078 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
95079 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
95080 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
95081 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
95082 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
95083 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
95084 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
95085 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
95086 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
95087 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
95088 +
95089 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
95090 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95091 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95092 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
95093 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
95094 +
95095 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
95096 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95097 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95098 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
95099 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
95100 +
95101 +/* Interface Mode Register (IF_MODE) */
95102 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
95103 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
95104 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
95105 +#define IF_MODE_RGMII 0x00000004
95106 +#define IF_MODE_RGMII_AUTO 0x00008000
95107 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
95108 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
95109 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
95110 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
95111 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
95112 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
95113 +
95114 +/* Hash table Control Register (HASHTABLE_CTRL) */
95115 +#define HASH_CTRL_MCAST_SHIFT 26
95116 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
95117 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
95118 +
95119 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
95120 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
95121 +
95122 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
95123 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
95124 +
95125 +/* Statistics Configuration Register (STATN_CONFIG) */
95126 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
95127 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
95128 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
95129 +
95130 +/* Interrupt Mask Register (IMASK) */
95131 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
95132 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
95133 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
95134 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
95135 +
95136 +#define MEMAC_ALL_ERRS_IMASK \
95137 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
95138 + MEMAC_IMASK_TECC_ER | \
95139 + MEMAC_IMASK_RECC_ER | \
95140 + MEMAC_IMASK_MGI))
95141 +
95142 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
95143 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
95144 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
95145 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
95146 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
95147 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
95148 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
95149 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
95150 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
95151 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
95152 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
95153 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
95154 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
95155 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
95156 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
95157 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
95158 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
95159 +
95160 +enum memac_counters {
95161 + E_MEMAC_COUNTER_R64,
95162 + E_MEMAC_COUNTER_R127,
95163 + E_MEMAC_COUNTER_R255,
95164 + E_MEMAC_COUNTER_R511,
95165 + E_MEMAC_COUNTER_R1023,
95166 + E_MEMAC_COUNTER_R1518,
95167 + E_MEMAC_COUNTER_R1519X,
95168 + E_MEMAC_COUNTER_RFRG,
95169 + E_MEMAC_COUNTER_RJBR,
95170 + E_MEMAC_COUNTER_RDRP,
95171 + E_MEMAC_COUNTER_RALN,
95172 + E_MEMAC_COUNTER_TUND,
95173 + E_MEMAC_COUNTER_ROVR,
95174 + E_MEMAC_COUNTER_RXPF,
95175 + E_MEMAC_COUNTER_TXPF,
95176 + E_MEMAC_COUNTER_ROCT,
95177 + E_MEMAC_COUNTER_RMCA,
95178 + E_MEMAC_COUNTER_RBCA,
95179 + E_MEMAC_COUNTER_RPKT,
95180 + E_MEMAC_COUNTER_RUCA,
95181 + E_MEMAC_COUNTER_RERR,
95182 + E_MEMAC_COUNTER_TOCT,
95183 + E_MEMAC_COUNTER_TMCA,
95184 + E_MEMAC_COUNTER_TBCA,
95185 + E_MEMAC_COUNTER_TUCA,
95186 + E_MEMAC_COUNTER_TERR
95187 +};
95188 +
95189 +#define DEFAULT_PAUSE_QUANTA 0xf000
95190 +#define DEFAULT_FRAME_LENGTH 0x600
95191 +#define DEFAULT_TX_IPG_LENGTH 12
95192 +
95193 +/*
95194 + * memory map
95195 + */
95196 +
95197 +struct mac_addr {
95198 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
95199 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
95200 +};
95201 +
95202 +struct memac_regs {
95203 + /* General Control and Status */
95204 + uint32_t res0000[2];
95205 + uint32_t command_config; /* 0x008 Ctrl and cfg */
95206 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
95207 + uint32_t maxfrm; /* 0x014 Max frame length */
95208 + uint32_t res0018[1];
95209 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
95210 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
95211 + uint32_t res0024[2];
95212 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
95213 + uint32_t res0030[4];
95214 + uint32_t ievent; /* 0x040 Interrupt event */
95215 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
95216 + uint32_t res0048;
95217 + uint32_t imask; /* 0x04C Interrupt mask */
95218 + uint32_t res0050;
95219 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
95220 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
95221 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
95222 + uint32_t res0078[2];
95223 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
95224 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
95225 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
95226 + uint32_t res00c0[8];
95227 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
95228 + uint32_t res00e4[7];
95229 + /* Rx Statistics Counter */
95230 + uint32_t reoct_l;
95231 + uint32_t reoct_u;
95232 + uint32_t roct_l;
95233 + uint32_t roct_u;
95234 + uint32_t raln_l;
95235 + uint32_t raln_u;
95236 + uint32_t rxpf_l;
95237 + uint32_t rxpf_u;
95238 + uint32_t rfrm_l;
95239 + uint32_t rfrm_u;
95240 + uint32_t rfcs_l;
95241 + uint32_t rfcs_u;
95242 + uint32_t rvlan_l;
95243 + uint32_t rvlan_u;
95244 + uint32_t rerr_l;
95245 + uint32_t rerr_u;
95246 + uint32_t ruca_l;
95247 + uint32_t ruca_u;
95248 + uint32_t rmca_l;
95249 + uint32_t rmca_u;
95250 + uint32_t rbca_l;
95251 + uint32_t rbca_u;
95252 + uint32_t rdrp_l;
95253 + uint32_t rdrp_u;
95254 + uint32_t rpkt_l;
95255 + uint32_t rpkt_u;
95256 + uint32_t rund_l;
95257 + uint32_t rund_u;
95258 + uint32_t r64_l;
95259 + uint32_t r64_u;
95260 + uint32_t r127_l;
95261 + uint32_t r127_u;
95262 + uint32_t r255_l;
95263 + uint32_t r255_u;
95264 + uint32_t r511_l;
95265 + uint32_t r511_u;
95266 + uint32_t r1023_l;
95267 + uint32_t r1023_u;
95268 + uint32_t r1518_l;
95269 + uint32_t r1518_u;
95270 + uint32_t r1519x_l;
95271 + uint32_t r1519x_u;
95272 + uint32_t rovr_l;
95273 + uint32_t rovr_u;
95274 + uint32_t rjbr_l;
95275 + uint32_t rjbr_u;
95276 + uint32_t rfrg_l;
95277 + uint32_t rfrg_u;
95278 + uint32_t rcnp_l;
95279 + uint32_t rcnp_u;
95280 + uint32_t rdrntp_l;
95281 + uint32_t rdrntp_u;
95282 + uint32_t res01d0[12];
95283 + /* Tx Statistics Counter */
95284 + uint32_t teoct_l;
95285 + uint32_t teoct_u;
95286 + uint32_t toct_l;
95287 + uint32_t toct_u;
95288 + uint32_t res0210[2];
95289 + uint32_t txpf_l;
95290 + uint32_t txpf_u;
95291 + uint32_t tfrm_l;
95292 + uint32_t tfrm_u;
95293 + uint32_t tfcs_l;
95294 + uint32_t tfcs_u;
95295 + uint32_t tvlan_l;
95296 + uint32_t tvlan_u;
95297 + uint32_t terr_l;
95298 + uint32_t terr_u;
95299 + uint32_t tuca_l;
95300 + uint32_t tuca_u;
95301 + uint32_t tmca_l;
95302 + uint32_t tmca_u;
95303 + uint32_t tbca_l;
95304 + uint32_t tbca_u;
95305 + uint32_t res0258[2];
95306 + uint32_t tpkt_l;
95307 + uint32_t tpkt_u;
95308 + uint32_t tund_l;
95309 + uint32_t tund_u;
95310 + uint32_t t64_l;
95311 + uint32_t t64_u;
95312 + uint32_t t127_l;
95313 + uint32_t t127_u;
95314 + uint32_t t255_l;
95315 + uint32_t t255_u;
95316 + uint32_t t511_l;
95317 + uint32_t t511_u;
95318 + uint32_t t1023_l;
95319 + uint32_t t1023_u;
95320 + uint32_t t1518_l;
95321 + uint32_t t1518_u;
95322 + uint32_t t1519x_l;
95323 + uint32_t t1519x_u;
95324 + uint32_t res02a8[6];
95325 + uint32_t tcnp_l;
95326 + uint32_t tcnp_u;
95327 + uint32_t res02c8[14];
95328 + /* Line Interface Control */
95329 + uint32_t if_mode; /* 0x300 Interface Mode Control */
95330 + uint32_t if_status; /* 0x304 Interface Status */
95331 + uint32_t res0308[14];
95332 + /* HiGig/2 */
95333 + uint32_t hg_config; /* 0x340 Control and cfg */
95334 + uint32_t res0344[3];
95335 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
95336 + uint32_t res0354[3];
95337 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
95338 + uint32_t res0364[3];
95339 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
95340 + uint32_t hg_fifos_status; /* 0x374 fifos status */
95341 + uint32_t rhm; /* 0x378 rx messages counter */
95342 + uint32_t thm; /* 0x37C tx messages counter */
95343 +};
95344 +
95345 +struct memac_cfg {
95346 + bool reset_on_init;
95347 + bool rx_error_discard;
95348 + bool pause_ignore;
95349 + bool pause_forward_enable;
95350 + bool no_length_check_enable;
95351 + bool cmd_frame_enable;
95352 + bool send_idle_enable;
95353 + bool wan_mode_enable;
95354 + bool promiscuous_mode_enable;
95355 + bool tx_addr_ins_enable;
95356 + bool loopback_enable;
95357 + bool lgth_check_nostdr;
95358 + bool time_stamp_enable;
95359 + bool pad_enable;
95360 + bool phy_tx_ena_on;
95361 + bool rx_sfd_any;
95362 + bool rx_pbl_fwd;
95363 + bool tx_pbl_fwd;
95364 + bool debug_mode;
95365 + bool wake_on_lan;
95366 + uint16_t max_frame_length;
95367 + uint16_t pause_quanta;
95368 + uint32_t tx_ipg_length;
95369 +};
95370 +
95371 +
95372 +/**
95373 + * fman_memac_defconfig() - Get default MEMAC configuration
95374 + * @cfg: pointer to configuration structure.
95375 + *
95376 + * Call this function to obtain a default set of configuration values for
95377 + * initializing MEMAC. The user can overwrite any of the values before calling
95378 + * fman_memac_init(), if specific configuration needs to be applied.
95379 + */
95380 +void fman_memac_defconfig(struct memac_cfg *cfg);
95381 +
95382 +int fman_memac_init(struct memac_regs *regs,
95383 + struct memac_cfg *cfg,
95384 + enum enet_interface enet_interface,
95385 + enum enet_speed enet_speed,
95386 + bool slow_10g_if,
95387 + uint32_t exceptions);
95388 +
95389 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95390 +
95391 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95392 +
95393 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
95394 +
95395 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
95396 + uint8_t *adr,
95397 + uint8_t paddr_num);
95398 +
95399 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
95400 + uint8_t paddr_num);
95401 +
95402 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
95403 + enum memac_counters reg_name);
95404 +
95405 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
95406 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
95407 +
95408 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
95409 +
95410 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
95411 + bool enable);
95412 +
95413 +void fman_memac_reset_stat(struct memac_regs *regs);
95414 +
95415 +void fman_memac_reset(struct memac_regs *regs);
95416 +
95417 +void fman_memac_reset_filter_table(struct memac_regs *regs);
95418 +
95419 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
95420 +
95421 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
95422 +
95423 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
95424 + bool enable);
95425 +
95426 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
95427 +
95428 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
95429 +
95430 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
95431 +
95432 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95433 +
95434 +void fman_memac_adjust_link(struct memac_regs *regs,
95435 + enum enet_interface iface_mode,
95436 + enum enet_speed speed, bool full_dx);
95437 +
95438 +
95439 +
95440 +#endif /*__FSL_FMAN_MEMAC_H*/
95441 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95442 new file mode 100755
95443 index 00000000..b4304450
95444 --- /dev/null
95445 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95446 @@ -0,0 +1,78 @@
95447 +/*
95448 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95449 + *
95450 + * Redistribution and use in source and binary forms, with or without
95451 + * modification, are permitted provided that the following conditions are met:
95452 + * * Redistributions of source code must retain the above copyright
95453 + * notice, this list of conditions and the following disclaimer.
95454 + * * Redistributions in binary form must reproduce the above copyright
95455 + * notice, this list of conditions and the following disclaimer in the
95456 + * documentation and/or other materials provided with the distribution.
95457 + * * Neither the name of Freescale Semiconductor nor the
95458 + * names of its contributors may be used to endorse or promote products
95459 + * derived from this software without specific prior written permission.
95460 + *
95461 + *
95462 + * ALTERNATIVELY, this software may be distributed under the terms of the
95463 + * GNU General Public License ("GPL") as published by the Free Software
95464 + * Foundation, either version 2 of that License or (at your option) any
95465 + * later version.
95466 + *
95467 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95468 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95469 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95470 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95471 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95472 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95473 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95474 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95475 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95476 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95477 + */
95478 +
95479 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95480 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95481 +
95482 +#include "common/general.h"
95483 +#include "fsl_enet.h"
95484 +/* MII Management Registers */
95485 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95486 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95487 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95488 +#define MDIO_CFG_ENC45 0x00000040
95489 +#define MDIO_CFG_READ_ERR 0x00000002
95490 +#define MDIO_CFG_BSY 0x00000001
95491 +
95492 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95493 +#define MDIO_CTL_READ 0x00008000
95494 +
95495 +#define MDIO_DATA_BSY 0x80000000
95496 +
95497 +/*MEMAC Internal PHY Registers - SGMII */
95498 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95499 +#define PHY_SGMII_CR_RESET_AN 0x0200
95500 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95501 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95502 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95503 +#define PHY_SGMII_IF_MODE_AN 0x0002
95504 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95505 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95506 +
95507 +/*----------------------------------------------------*/
95508 +/* MII Configuration Control Memory Map Registers */
95509 +/*----------------------------------------------------*/
95510 +struct memac_mii_access_mem_map {
95511 + uint32_t mdio_cfg; /* 0x030 */
95512 + uint32_t mdio_ctrl; /* 0x034 */
95513 + uint32_t mdio_data; /* 0x038 */
95514 + uint32_t mdio_addr; /* 0x03c */
95515 +};
95516 +
95517 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95518 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95519 + enum enet_speed enet_speed);
95520 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95521 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95522 + enum enet_speed enet_speed);
95523 +
95524 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95525 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95526 new file mode 100755
95527 index 00000000..080a23e9
95528 --- /dev/null
95529 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95530 @@ -0,0 +1,593 @@
95531 +/*
95532 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95533 + *
95534 + * Redistribution and use in source and binary forms, with or without
95535 + * modification, are permitted provided that the following conditions are met:
95536 + * * Redistributions of source code must retain the above copyright
95537 + * notice, this list of conditions and the following disclaimer.
95538 + * * Redistributions in binary form must reproduce the above copyright
95539 + * notice, this list of conditions and the following disclaimer in the
95540 + * documentation and/or other materials provided with the distribution.
95541 + * * Neither the name of Freescale Semiconductor nor the
95542 + * names of its contributors may be used to endorse or promote products
95543 + * derived from this software without specific prior written permission.
95544 + *
95545 + *
95546 + * ALTERNATIVELY, this software may be distributed under the terms of the
95547 + * GNU General Public License ("GPL") as published by the Free Software
95548 + * Foundation, either version 2 of that License or (at your option) any
95549 + * later version.
95550 + *
95551 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95552 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95553 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95554 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95555 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95556 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95557 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95558 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95559 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95560 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95561 + */
95562 +
95563 +#ifndef __FSL_FMAN_PORT_H
95564 +#define __FSL_FMAN_PORT_H
95565 +
95566 +#include "fsl_fman_sp.h"
95567 +
95568 +/** @Collection Registers bit fields */
95569 +
95570 +/** @Description BMI defines */
95571 +#define BMI_EBD_EN 0x80000000
95572 +
95573 +#define BMI_PORT_CFG_EN 0x80000000
95574 +#define BMI_PORT_CFG_FDOVR 0x02000000
95575 +#define BMI_PORT_CFG_IM 0x01000000
95576 +
95577 +#define BMI_PORT_STATUS_BSY 0x80000000
95578 +
95579 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95580 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95581 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95582 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95583 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95584 +
95585 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95586 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95587 +
95588 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95589 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95590 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95591 +
95592 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95593 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95594 +
95595 +#define BMI_INT_BUF_MARG_SHIFT 28
95596 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95597 +
95598 +#define BMI_CMD_MR_LEAC 0x00200000
95599 +#define BMI_CMD_MR_SLEAC 0x00100000
95600 +#define BMI_CMD_MR_MA 0x00080000
95601 +#define BMI_CMD_MR_DEAS 0x00040000
95602 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95603 + BMI_CMD_MR_SLEAC | \
95604 + BMI_CMD_MR_MA | \
95605 + BMI_CMD_MR_DEAS)
95606 +#define BMI_CMD_TX_MR_DEF 0
95607 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95608 + BMI_CMD_MR_MA)
95609 +
95610 +#define BMI_CMD_ATTR_ORDER 0x80000000
95611 +#define BMI_CMD_ATTR_SYNC 0x02000000
95612 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95613 +
95614 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95615 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95616 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95617 +
95618 +#define BMI_COUNTERS_EN 0x80000000
95619 +
95620 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95621 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95622 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95623 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95624 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95625 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95626 +
95627 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95628 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95629 +
95630 +#define MAX_PERFORMANCE_TASK_COMP 64
95631 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95632 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95633 +#define MAX_PERFORMANCE_DMA_COMP 16
95634 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95635 +
95636 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95637 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95638 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95639 +
95640 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95641 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95642 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95643 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95644 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95645 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95646 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95647 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95648 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95649 +
95650 +/** @Description QMI defines */
95651 +#define QMI_PORT_CFG_EN 0x80000000
95652 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95653 +
95654 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95655 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95656 +
95657 +#define QMI_DEQ_CFG_PRI 0x80000000
95658 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95659 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95660 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95661 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95662 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95663 +#define QMI_DEQ_CFG_SP_MASK 0xf
95664 +#define QMI_DEQ_CFG_SP_SHIFT 20
95665 +
95666 +
95667 +/** @Description General port defines */
95668 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95669 + (((fm_rev_maj) == 4) ? 4 : 8)
95670 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95671 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95672 +#define FMAN_PORT_CG_MAP_NUM 8
95673 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95674 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95675 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95676 +
95677 +
95678 +/** @Collection FM Port Register Map */
95679 +
95680 +/** @Description BMI Rx port register map */
95681 +struct fman_port_rx_bmi_regs {
95682 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95683 + uint32_t fmbm_rst; /**< Rx Status */
95684 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95685 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95686 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95687 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95688 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95689 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95690 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95691 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95692 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95693 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95694 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95695 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95696 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95697 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95698 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95699 + /**< Rx Parse Results Array Init*/
95700 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95701 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95702 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95703 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95704 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95705 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95706 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95707 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95708 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95709 + /**< Buffer Manager pool Information-*/
95710 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95711 + /**< Allocate Counter-*/
95712 + uint32_t reserved0130[8];
95713 + /**< 0x130/0x140 - 0x15F reserved -*/
95714 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95715 + /**< Congestion Group Map*/
95716 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95717 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95718 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95719 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95720 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95721 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95722 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95723 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95724 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95725 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95726 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95727 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95728 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95729 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95730 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95731 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95732 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95733 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95734 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95735 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95736 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95737 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95738 +};
95739 +
95740 +/** @Description BMI Tx port register map */
95741 +struct fman_port_tx_bmi_regs {
95742 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95743 + uint32_t fmbm_tst; /**< Tx Status */
95744 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95745 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95746 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95747 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95748 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95749 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95750 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95751 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95752 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95753 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95754 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95755 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95756 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95757 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95758 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95759 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95760 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95761 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95762 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95763 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95764 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95765 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95766 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95767 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95768 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95769 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95770 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95771 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95772 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95773 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95774 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95775 +};
95776 +
95777 +/** @Description BMI O/H port register map */
95778 +struct fman_port_oh_bmi_regs {
95779 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95780 + uint32_t fmbm_ost; /**< O/H Status */
95781 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95782 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95783 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95784 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95785 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95786 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95787 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95788 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95789 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95790 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95791 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95792 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95793 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95794 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95795 + /**< O/H Parse Results Array Initialization */
95796 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95797 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95798 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95799 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95800 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95801 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95802 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95803 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95804 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95805 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95806 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95807 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95808 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95809 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95810 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95811 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95812 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95813 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95814 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95815 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95816 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95817 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95818 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95819 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95820 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95821 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95822 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95823 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95824 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95825 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95826 +};
95827 +
95828 +/** @Description BMI port register map */
95829 +union fman_port_bmi_regs {
95830 + struct fman_port_rx_bmi_regs rx;
95831 + struct fman_port_tx_bmi_regs tx;
95832 + struct fman_port_oh_bmi_regs oh;
95833 +};
95834 +
95835 +/** @Description QMI port register map */
95836 +struct fman_port_qmi_regs {
95837 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95838 + uint32_t fmqm_pns; /**< PortID n Status Register */
95839 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
95840 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
95841 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
95842 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
95843 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
95844 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
95845 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
95846 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
95847 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
95848 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
95849 +};
95850 +
95851 +
95852 +enum fman_port_dma_swap {
95853 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
95854 + E_FMAN_PORT_DMA_SWAP_LE,
95855 + /**< The transferred data should be swapped in PPC Little Endian mode */
95856 + E_FMAN_PORT_DMA_SWAP_BE
95857 + /**< The transferred data should be swapped in Big Endian mode */
95858 +};
95859 +
95860 +/* Default port color */
95861 +enum fman_port_color {
95862 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
95863 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
95864 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
95865 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
95866 +};
95867 +
95868 +/* QMI dequeue from the SP channel - types */
95869 +enum fman_port_deq_type {
95870 + E_FMAN_PORT_DEQ_BY_PRI,
95871 + /**< Priority precedence and Intra-Class scheduling */
95872 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
95873 + /**< Active FQ precedence and Intra-Class scheduling */
95874 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
95875 + /**< Active FQ precedence and override Intra-Class scheduling */
95876 +};
95877 +
95878 +/* QMI dequeue prefetch modes */
95879 +enum fman_port_deq_prefetch {
95880 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
95881 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
95882 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
95883 +};
95884 +
95885 +/* Parameters for defining performance counters behavior */
95886 +struct fman_port_perf_cnt_params {
95887 + uint8_t task_val; /**< Task compare value */
95888 + uint8_t queue_val;
95889 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
95890 + uint8_t dma_val; /**< Dma compare value */
95891 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
95892 +};
95893 +
95894 +/** @Description FM Port configuration structure, used at init */
95895 +struct fman_port_cfg {
95896 + struct fman_port_perf_cnt_params perf_cnt_params;
95897 + /* BMI parameters */
95898 + enum fman_port_dma_swap dma_swap_data;
95899 + bool dma_ic_stash_on;
95900 + bool dma_header_stash_on;
95901 + bool dma_sg_stash_on;
95902 + bool dma_write_optimize;
95903 + uint16_t ic_ext_offset;
95904 + uint8_t ic_int_offset;
95905 + uint16_t ic_size;
95906 + enum fman_port_color color;
95907 + bool sync_req;
95908 + bool discard_override;
95909 + uint8_t checksum_bytes_ignore;
95910 + uint8_t rx_cut_end_bytes;
95911 + uint32_t rx_pri_elevation;
95912 + uint32_t rx_fifo_thr;
95913 + uint8_t rx_fd_bits;
95914 + uint8_t int_buf_start_margin;
95915 + uint16_t ext_buf_start_margin;
95916 + uint16_t ext_buf_end_margin;
95917 + uint32_t tx_fifo_min_level;
95918 + uint32_t tx_fifo_low_comf_level;
95919 + uint8_t tx_fifo_deq_pipeline_depth;
95920 + bool stats_counters_enable;
95921 + bool perf_counters_enable;
95922 + /* QMI parameters */
95923 + bool deq_high_pri;
95924 + enum fman_port_deq_type deq_type;
95925 + enum fman_port_deq_prefetch deq_prefetch_opt;
95926 + uint16_t deq_byte_cnt;
95927 + bool queue_counters_enable;
95928 + bool no_scatter_gather;
95929 + int errata_A006675;
95930 + int errata_A006320;
95931 + int excessive_threshold_register;
95932 + int fmbm_rebm_has_sgd;
95933 + int fmbm_tfne_has_features;
95934 + int qmi_deq_options_support;
95935 +};
95936 +
95937 +enum fman_port_type {
95938 + E_FMAN_PORT_TYPE_OP = 0,
95939 + /**< Offline parsing port, shares id-s with
95940 + * host command, so must have exclusive id-s */
95941 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
95942 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
95943 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
95944 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
95945 + E_FMAN_PORT_TYPE_DUMMY,
95946 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
95947 + /**< Host command port, shares id-s with
95948 + * offline parsing ports, so must have exclusive id-s */
95949 +};
95950 +
95951 +struct fman_port_params {
95952 + uint32_t discard_mask;
95953 + uint32_t err_mask;
95954 + uint32_t dflt_fqid;
95955 + uint32_t err_fqid;
95956 + uint8_t deq_sp;
95957 + bool dont_release_buf;
95958 +};
95959 +
95960 +/* Port context - used by most API functions */
95961 +struct fman_port {
95962 + enum fman_port_type type;
95963 + uint8_t fm_rev_maj;
95964 + uint8_t fm_rev_min;
95965 + union fman_port_bmi_regs *bmi_regs;
95966 + struct fman_port_qmi_regs *qmi_regs;
95967 + bool im_en;
95968 + uint8_t ext_pools_num;
95969 +};
95970 +
95971 +/** @Description External buffer pools configuration */
95972 +struct fman_port_bpools {
95973 + uint8_t count; /**< Num of pools to set up */
95974 + bool counters_enable; /**< Enable allocate counters */
95975 + uint8_t grp_bp_depleted_num;
95976 + /**< Number of depleted pools - if reached the BMI indicates
95977 + * the MAC to send a pause frame */
95978 + struct {
95979 + uint8_t bpid; /**< BM pool ID */
95980 + uint16_t size;
95981 + /**< Pool's size - must be in ascending order */
95982 + bool is_backup;
95983 + /**< If this is a backup pool */
95984 + bool grp_bp_depleted;
95985 + /**< Consider this buffer in multiple pools depletion criteria*/
95986 + bool single_bp_depleted;
95987 + /**< Consider this buffer in single pool depletion criteria */
95988 + bool pfc_priorities_en;
95989 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
95990 +};
95991 +
95992 +enum fman_port_rate_limiter_scale_down {
95993 + E_FMAN_PORT_RATE_DOWN_NONE,
95994 + E_FMAN_PORT_RATE_DOWN_BY_2,
95995 + E_FMAN_PORT_RATE_DOWN_BY_4,
95996 + E_FMAN_PORT_RATE_DOWN_BY_8
95997 +};
95998 +
95999 +/* Rate limiter configuration */
96000 +struct fman_port_rate_limiter {
96001 + uint8_t count_1micro_bit;
96002 + bool high_burst_size_gran;
96003 + /**< Defines burst_size granularity for OP ports; when TRUE,
96004 + * burst_size below counts in frames, otherwise in 10^3 frames */
96005 + uint16_t burst_size;
96006 + /**< Max burst size, in KBytes for Tx port, according to
96007 + * high_burst_size_gran definition for OP port */
96008 + uint32_t rate;
96009 + /**< In Kbps for Tx port, in frames/sec for OP port */
96010 + enum fman_port_rate_limiter_scale_down rate_factor;
96011 +};
96012 +
96013 +/* BMI statistics counters */
96014 +enum fman_port_stats_counters {
96015 + E_FMAN_PORT_STATS_CNT_FRAME,
96016 + /**< Number of processed frames; valid for all ports */
96017 + E_FMAN_PORT_STATS_CNT_DISCARD,
96018 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
96019 + * frames discarded due to DMA error; valid for all ports */
96020 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
96021 + /**< Number of buffer deallocate operations; valid for all ports */
96022 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
96023 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
96024 + * valid for Rx ports only */
96025 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
96026 + /**< Number of Rx oversized frames, that is frames exceeding max frame
96027 + * size configured for the corresponding ETH controller;
96028 + * valid for Rx ports only */
96029 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
96030 + /**< Frames discarded due to lack of external buffers; valid for
96031 + * Rx ports only */
96032 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
96033 + /**< Frames discarded due to frame length error; valid for Tx and
96034 + * O/H ports only */
96035 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
96036 + /**< Frames discarded due to unsupported FD format; valid for Tx
96037 + * and O/H ports only */
96038 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
96039 + /**< Number of frames filtered out by PCD module; valid for
96040 + * Rx and OP ports only */
96041 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
96042 + /**< Frames rejected by QMAN that were not able to release their
96043 + * buffers due to DMA error; valid for Rx and O/H ports only */
96044 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
96045 + /**< Frames going through O/H port that were not able to to enter the
96046 + * return queue due to WRED algorithm; valid for O/H ports only */
96047 +};
96048 +
96049 +/* BMI performance counters */
96050 +enum fman_port_perf_counters {
96051 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
96052 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
96053 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
96054 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
96055 + * utilization; not valid for O/H ports */
96056 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
96057 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
96058 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
96059 + /**< Number of cycles in which Rx pause activation control is on;
96060 + * valid for Rx ports only */
96061 +};
96062 +
96063 +/* QMI counters */
96064 +enum fman_port_qmi_counters {
96065 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
96066 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
96067 + E_FMAN_PORT_DEQ_FROM_DFLT,
96068 + /**< Dequeue from default FQID counter not valid for Rx ports */
96069 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
96070 +};
96071 +
96072 +
96073 +/** @Collection FM Port API */
96074 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
96075 +int fman_port_init(struct fman_port *port,
96076 + struct fman_port_cfg *cfg,
96077 + struct fman_port_params *params);
96078 +int fman_port_enable(struct fman_port *port);
96079 +int fman_port_disable(const struct fman_port *port);
96080 +int fman_port_set_bpools(const struct fman_port *port,
96081 + const struct fman_port_bpools *bp);
96082 +int fman_port_set_rate_limiter(struct fman_port *port,
96083 + struct fman_port_rate_limiter *rate_limiter);
96084 +int fman_port_delete_rate_limiter(struct fman_port *port);
96085 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
96086 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
96087 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
96088 + uint8_t rx_fd_bits,
96089 + bool add);
96090 +int fman_port_set_perf_cnt_params(struct fman_port *port,
96091 + struct fman_port_perf_cnt_params *params);
96092 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
96093 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
96094 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
96095 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
96096 + uint8_t bpid,
96097 + bool enable);
96098 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
96099 + enum fman_port_stats_counters counter);
96100 +void fman_port_set_stats_counter(struct fman_port *port,
96101 + enum fman_port_stats_counters counter,
96102 + uint32_t value);
96103 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
96104 + enum fman_port_perf_counters counter);
96105 +void fman_port_set_perf_counter(struct fman_port *port,
96106 + enum fman_port_perf_counters counter,
96107 + uint32_t value);
96108 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
96109 + enum fman_port_qmi_counters counter);
96110 +void fman_port_set_qmi_counter(struct fman_port *port,
96111 + enum fman_port_qmi_counters counter,
96112 + uint32_t value);
96113 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
96114 +void fman_port_set_bpool_counter(struct fman_port *port,
96115 + uint8_t bpid,
96116 + uint32_t value);
96117 +int fman_port_add_congestion_grps(struct fman_port *port,
96118 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96119 +int fman_port_remove_congestion_grps(struct fman_port *port,
96120 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96121 +
96122 +
96123 +#endif /* __FSL_FMAN_PORT_H */
96124 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
96125 new file mode 100644
96126 index 00000000..b18997dc
96127 --- /dev/null
96128 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
96129 @@ -0,0 +1,102 @@
96130 +/*
96131 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96132 + *
96133 + * Redistribution and use in source and binary forms, with or without
96134 + * modification, are permitted provided that the following conditions are met:
96135 + * * Redistributions of source code must retain the above copyright
96136 + * notice, this list of conditions and the following disclaimer.
96137 + * * Redistributions in binary form must reproduce the above copyright
96138 + * notice, this list of conditions and the following disclaimer in the
96139 + * documentation and/or other materials provided with the distribution.
96140 + * * Neither the name of Freescale Semiconductor nor the
96141 + * names of its contributors may be used to endorse or promote products
96142 + * derived from this software without specific prior written permission.
96143 + *
96144 + *
96145 + * ALTERNATIVELY, this software may be distributed under the terms of the
96146 + * GNU General Public License ("GPL") as published by the Free Software
96147 + * Foundation, either version 2 of that License or (at your option) any
96148 + * later version.
96149 + *
96150 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96151 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96152 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96153 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96154 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96155 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96156 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96157 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96158 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96159 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96160 + */
96161 +
96162 +#ifndef __FSL_FMAN_PRS_H
96163 +#define __FSL_FMAN_PRS_H
96164 +
96165 +#include "common/general.h"
96166 +
96167 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
96168 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
96169 +
96170 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
96171 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
96172 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
96173 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
96174 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
96175 +#define PRS_MAX_CYCLE_LIMIT 8191
96176 +
96177 +#define DEFAULT_MAX_PRS_CYC_LIM 0
96178 +
96179 +struct fman_prs_regs {
96180 + uint32_t fmpr_rpclim;
96181 + uint32_t fmpr_rpimac;
96182 + uint32_t pmeec;
96183 + uint32_t res00c[5];
96184 + uint32_t fmpr_pevr;
96185 + uint32_t fmpr_pever;
96186 + uint32_t res028;
96187 + uint32_t fmpr_perr;
96188 + uint32_t fmpr_perer;
96189 + uint32_t res034;
96190 + uint32_t res038[10];
96191 + uint32_t fmpr_ppsc;
96192 + uint32_t res064;
96193 + uint32_t fmpr_pds;
96194 + uint32_t fmpr_l2rrs;
96195 + uint32_t fmpr_l3rrs;
96196 + uint32_t fmpr_l4rrs;
96197 + uint32_t fmpr_srrs;
96198 + uint32_t fmpr_l2rres;
96199 + uint32_t fmpr_l3rres;
96200 + uint32_t fmpr_l4rres;
96201 + uint32_t fmpr_srres;
96202 + uint32_t fmpr_spcs;
96203 + uint32_t fmpr_spscs;
96204 + uint32_t fmpr_hxscs;
96205 + uint32_t fmpr_mrcs;
96206 + uint32_t fmpr_mwcs;
96207 + uint32_t fmpr_mrscs;
96208 + uint32_t fmpr_mwscs;
96209 + uint32_t fmpr_fcscs;
96210 +};
96211 +
96212 +struct fman_prs_cfg {
96213 + uint32_t port_id_stat;
96214 + uint16_t max_prs_cyc_lim;
96215 + uint32_t prs_exceptions;
96216 +};
96217 +
96218 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96219 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
96220 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
96221 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96222 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
96223 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
96224 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
96225 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
96226 +void fman_prs_enable(struct fman_prs_regs *regs);
96227 +void fman_prs_disable(struct fman_prs_regs *regs);
96228 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
96229 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
96230 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
96231 +#endif /* __FSL_FMAN_PRS_H */
96232 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
96233 new file mode 100755
96234 index 00000000..f6b69a1f
96235 --- /dev/null
96236 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
96237 @@ -0,0 +1,449 @@
96238 +/*
96239 + * Copyright 2013 Freescale Semiconductor Inc.
96240 + *
96241 + * Redistribution and use in source and binary forms, with or without
96242 + * modification, are permitted provided that the following conditions are met:
96243 + * * Redistributions of source code must retain the above copyright
96244 + * notice, this list of conditions and the following disclaimer.
96245 + * * Redistributions in binary form must reproduce the above copyright
96246 + * notice, this list of conditions and the following disclaimer in the
96247 + * documentation and/or other materials provided with the distribution.
96248 + * * Neither the name of Freescale Semiconductor nor the
96249 + * names of its contributors may be used to endorse or promote products
96250 + * derived from this software without specific prior written permission.
96251 + *
96252 + *
96253 + * ALTERNATIVELY, this software may be distributed under the terms of the
96254 + * GNU General Public License ("GPL") as published by the Free Software
96255 + * Foundation, either version 2 of that License or (at your option) any
96256 + * later version.
96257 + *
96258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96268 + */
96269 +
96270 +#ifndef __FSL_FMAN_RTC_H
96271 +#define __FSL_FMAN_RTC_H
96272 +
96273 +#include "common/general.h"
96274 +
96275 +/* FM RTC Registers definitions */
96276 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
96277 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
96278 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
96279 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
96280 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
96281 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
96282 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
96283 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
96284 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
96285 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
96286 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
96287 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
96288 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
96289 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
96290 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
96291 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
96292 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
96293 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
96294 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
96295 +
96296 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
96297 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
96298 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
96299 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
96300 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
96301 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
96302 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
96303 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
96304 + FMAN_RTC_TMR_TEVENT_ETS1 |\
96305 + FMAN_RTC_TMR_TEVENT_ALM2 |\
96306 + FMAN_RTC_TMR_TEVENT_ALM1 |\
96307 + FMAN_RTC_TMR_TEVENT_PP1 |\
96308 + FMAN_RTC_TMR_TEVENT_PP2 |\
96309 + FMAN_RTC_TMR_TEVENT_PP3)
96310 +
96311 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
96312 +
96313 +/**************************************************************************//**
96314 + @Description FM RTC Alarm Polarity Options.
96315 +*//***************************************************************************/
96316 +enum fman_rtc_alarm_polarity {
96317 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
96318 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
96319 +};
96320 +
96321 +/**************************************************************************//**
96322 + @Description FM RTC Trigger Polarity Options.
96323 +*//***************************************************************************/
96324 +enum fman_rtc_trigger_polarity {
96325 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
96326 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
96327 +};
96328 +
96329 +/**************************************************************************//**
96330 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
96331 +*//***************************************************************************/
96332 +enum fman_src_clock {
96333 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
96334 + reference clock */
96335 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
96336 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
96337 +};
96338 +
96339 +/* RTC default values */
96340 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
96341 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
96342 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
96343 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
96344 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
96345 +#define DEFAULT_PULSE_REALIGN FALSE
96346 +
96347 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
96348 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
96349 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
96350 +
96351 +/**************************************************************************//**
96352 + @Description FM RTC timer alarm
96353 +*//***************************************************************************/
96354 +struct t_tmr_alarm{
96355 + uint32_t tmr_alarm_h; /**< */
96356 + uint32_t tmr_alarm_l; /**< */
96357 +};
96358 +
96359 +/**************************************************************************//**
96360 + @Description FM RTC timer Ex trigger
96361 +*//***************************************************************************/
96362 +struct t_tmr_ext_trigger{
96363 + uint32_t tmr_etts_h; /**< */
96364 + uint32_t tmr_etts_l; /**< */
96365 +};
96366 +
96367 +struct rtc_regs {
96368 + uint32_t tmr_id; /* 0x000 Module ID register */
96369 + uint32_t tmr_id2; /* 0x004 Controller ID register */
96370 + uint32_t reserved0008[30];
96371 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
96372 + uint32_t tmr_tevent; /* 0x0084 timer event register */
96373 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
96374 + uint32_t reserved008c[3];
96375 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
96376 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
96377 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
96378 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
96379 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
96380 + uint32_t reserved00ac;
96381 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
96382 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
96383 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
96384 + alarm */
96385 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
96386 + fixed period interval */
96387 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96388 + /* 0x00e0 time stamp general purpose external */
96389 + uint32_t reserved00f0[4];
96390 +};
96391 +
96392 +struct rtc_cfg {
96393 + enum fman_src_clock src_clk;
96394 + uint32_t ext_src_clk_freq;
96395 + uint32_t rtc_freq_hz;
96396 + bool timer_slave_mode;
96397 + bool invert_input_clk_phase;
96398 + bool invert_output_clk_phase;
96399 + uint32_t events_mask;
96400 + bool bypass; /**< Indicates if frequency compensation
96401 + is bypassed */
96402 + bool pulse_realign;
96403 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
96404 + enum fman_rtc_trigger_polarity trigger_polarity
96405 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96406 +};
96407 +
96408 +/**
96409 + * fman_rtc_defconfig() - Get default RTC configuration
96410 + * @cfg: pointer to configuration structure.
96411 + *
96412 + * Call this function to obtain a default set of configuration values for
96413 + * initializing RTC. The user can overwrite any of the values before calling
96414 + * fman_rtc_init(), if specific configuration needs to be applied.
96415 + */
96416 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
96417 +
96418 +/**
96419 + * fman_rtc_get_events() - Get the events
96420 + * @regs: Pointer to RTC register block
96421 + *
96422 + * Returns: The events
96423 + */
96424 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
96425 +
96426 +/**
96427 + * fman_rtc_get_interrupt_mask() - Get the events mask
96428 + * @regs: Pointer to RTC register block
96429 + *
96430 + * Returns: The events mask
96431 + */
96432 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
96433 +
96434 +
96435 +/**
96436 + * fman_rtc_set_interrupt_mask() - Set the events mask
96437 + * @regs: Pointer to RTC register block
96438 + * @mask: The mask to set
96439 + */
96440 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
96441 +
96442 +/**
96443 + * fman_rtc_get_event() - Check if specific events occurred
96444 + * @regs: Pointer to RTC register block
96445 + * @ev_mask: a mask of the events to check
96446 + *
96447 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96448 + */
96449 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96450 +
96451 +/**
96452 + * fman_rtc_check_and_clear_event() - Clear events which are on
96453 + * @regs: Pointer to RTC register block
96454 + *
96455 + * Returns: A mask of the events which were cleared
96456 + */
96457 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96458 +
96459 +/**
96460 + * fman_rtc_ack_event() - Clear events
96461 + * @regs: Pointer to RTC register block
96462 + * @events: The events to disable
96463 + */
96464 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96465 +
96466 +/**
96467 + * fman_rtc_enable_interupt() - Enable events interrupts
96468 + * @regs: Pointer to RTC register block
96469 + * @mask: The events to disable
96470 + */
96471 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96472 +
96473 +/**
96474 + * fman_rtc_disable_interupt() - Disable events interrupts
96475 + * @regs: Pointer to RTC register block
96476 + * @mask: The events to disable
96477 + */
96478 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96479 +
96480 +/**
96481 + * fman_rtc_get_timer_ctrl() - Get the control register
96482 + * @regs: Pointer to RTC register block
96483 + *
96484 + * Returns: The control register value
96485 + */
96486 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96487 +
96488 +/**
96489 + * fman_rtc_set_timer_ctrl() - Set timer control register
96490 + * @regs: Pointer to RTC register block
96491 + * @val: The value to set
96492 + */
96493 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96494 +
96495 +/**
96496 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96497 + * @regs: Pointer to RTC register block
96498 + *
96499 + * Returns: The timer counter
96500 + */
96501 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96502 +
96503 +/**
96504 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96505 + * @regs: Pointer to RTC register block
96506 + * @val: The value to set
96507 + */
96508 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96509 +
96510 +/**
96511 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96512 + * @regs: Pointer to RTC register block
96513 + * @id: The id of the trigger stamp
96514 + *
96515 + * Returns: The time stamp
96516 + */
96517 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96518 +
96519 +/**
96520 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96521 + * @regs: Pointer to RTC register block
96522 + * @index: The index of alarm to set
96523 + * @val: The value to set
96524 + */
96525 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96526 + uint32_t val);
96527 +
96528 +/**
96529 + * fman_rtc_set_timer_alarm() - Set timer alarm
96530 + * @regs: Pointer to RTC register block
96531 + * @index: The index of alarm to set
96532 + * @val: The value to set
96533 + */
96534 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96535 +
96536 +/**
96537 + * fman_rtc_set_timer_fiper() - Set timer fiper
96538 + * @regs: Pointer to RTC register block
96539 + * @index: The index of fiper to set
96540 + * @val: The value to set
96541 + */
96542 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96543 +
96544 +/**
96545 + * fman_rtc_set_timer_offset() - Set timer offset
96546 + * @regs: Pointer to RTC register block
96547 + * @val: The value to set
96548 + */
96549 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96550 +
96551 +/**
96552 + * fman_rtc_get_timer() - Get the timer counter
96553 + * @regs: Pointer to RTC register block
96554 + *
96555 + * Returns: The timer counter
96556 + */
96557 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96558 +{
96559 + uint64_t time;
96560 + /* TMR_CNT_L must be read first to get an accurate value */
96561 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96562 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96563 +
96564 + return time;
96565 +}
96566 +
96567 +/**
96568 + * fman_rtc_set_timer() - Set timer counter
96569 + * @regs: Pointer to RTC register block
96570 + * @val: The value to set
96571 + */
96572 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96573 +{
96574 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96575 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96576 +}
96577 +
96578 +/**
96579 + * fman_rtc_timers_soft_reset() - Soft reset
96580 + * @regs: Pointer to RTC register block
96581 + *
96582 + * Resets all the timer registers and state machines for the 1588 IP and
96583 + * the attached client 1588
96584 + */
96585 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96586 +
96587 +/**
96588 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96589 + * @regs: Pointer to RTC register block
96590 + * @id: The id of the trigger to clear
96591 + */
96592 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96593 +
96594 +/**
96595 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96596 + * @regs: Pointer to RTC register block
96597 + * @id: The id of the fiper to clear
96598 + */
96599 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96600 +
96601 +/**
96602 + * fman_rtc_enable() - Enable RTC hardware block
96603 + * @regs: Pointer to RTC register block
96604 + */
96605 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96606 +
96607 +/**
96608 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96609 + * @regs: Pointer to RTC register block
96610 + *
96611 + * Return: TRUE if enabled
96612 + */
96613 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96614 +
96615 +/**
96616 + * fman_rtc_disable() - Disable RTC hardware block
96617 + * @regs: Pointer to RTC register block
96618 + */
96619 +void fman_rtc_disable(struct rtc_regs *regs);
96620 +
96621 +/**
96622 + * fman_rtc_init() - Init RTC hardware block
96623 + * @cfg: RTC configuration data
96624 + * @regs: Pointer to RTC register block
96625 + * @num_alarms: Number of alarms in RTC
96626 + * @num_fipers: Number of fipers in RTC
96627 + * @num_ext_triggers: Number of external triggers in RTC
96628 + * @freq_compensation: Frequency compensation
96629 + * @output_clock_divisor: Output clock divisor
96630 + *
96631 + * This function initializes RTC and applies basic configuration.
96632 + */
96633 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96634 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96635 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96636 +
96637 +/**
96638 + * fman_rtc_set_alarm() - Set an alarm
96639 + * @regs: Pointer to RTC register block
96640 + * @id: id of alarm
96641 + * @val: value to write
96642 + * @enable: should interrupt be enabled
96643 + */
96644 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96645 +
96646 +/**
96647 + * fman_rtc_set_periodic_pulse() - Set an alarm
96648 + * @regs: Pointer to RTC register block
96649 + * @id: id of fiper
96650 + * @val: value to write
96651 + * @enable: should interrupt be enabled
96652 + */
96653 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96654 + bool enable);
96655 +
96656 +/**
96657 + * fman_rtc_set_ext_trigger() - Set an external trigger
96658 + * @regs: Pointer to RTC register block
96659 + * @id: id of trigger
96660 + * @enable: should interrupt be enabled
96661 + * @use_pulse_as_input: use the pulse as input
96662 + */
96663 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96664 + bool use_pulse_as_input);
96665 +
96666 +struct fm_rtc_alarm_params {
96667 + uint8_t alarm_id; /**< 0 or 1 */
96668 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96669 + alarm should go off - must be a
96670 + multiple of the RTC period */
96671 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96672 + be called when RTC reaches alarmTime */
96673 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96674 + expired.*/
96675 +};
96676 +
96677 +struct fm_rtc_periodic_pulse_params {
96678 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96679 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96680 + of the RTC period */
96681 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96682 + routine will be called every
96683 + periodicPulsePeriod. */
96684 +};
96685 +
96686 +#endif /* __FSL_FMAN_RTC_H */
96687 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96688 new file mode 100755
96689 index 00000000..f8ef7d56
96690 --- /dev/null
96691 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96692 @@ -0,0 +1,138 @@
96693 +/*
96694 + * Copyright 2013 Freescale Semiconductor Inc.
96695 + *
96696 + * Redistribution and use in source and binary forms, with or without
96697 + * modification, are permitted provided that the following conditions are met:
96698 + * * Redistributions of source code must retain the above copyright
96699 + * notice, this list of conditions and the following disclaimer.
96700 + * * Redistributions in binary form must reproduce the above copyright
96701 + * notice, this list of conditions and the following disclaimer in the
96702 + * documentation and/or other materials provided with the distribution.
96703 + * * Neither the name of Freescale Semiconductor nor the
96704 + * names of its contributors may be used to endorse or promote products
96705 + * derived from this software without specific prior written permission.
96706 + *
96707 + *
96708 + * ALTERNATIVELY, this software may be distributed under the terms of the
96709 + * GNU General Public License ("GPL") as published by the Free Software
96710 + * Foundation, either version 2 of that License or (at your option) any
96711 + * later version.
96712 + *
96713 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96714 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96715 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96716 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96717 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96718 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96719 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96720 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96721 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96722 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96723 + */
96724 +
96725 +#ifndef __FSL_FMAN_SP_H
96726 +#define __FSL_FMAN_SP_H
96727 +
96728 +#include "common/general.h"
96729 +#include "fsl_fman.h"
96730 +
96731 +
96732 +struct fm_pcd_storage_profile_regs{
96733 + uint32_t fm_sp_ebmpi[8];
96734 + /*offset 0 - 0xc*/
96735 + /**< Buffer Manager pool Information */
96736 +
96737 + uint32_t fm_sp_acnt; /*offset 0x20*/
96738 + uint32_t fm_sp_ebm; /*offset 0x24*/
96739 + uint32_t fm_sp_da; /*offset 0x28*/
96740 + uint32_t fm_sp_icp; /*offset 0x2c*/
96741 + uint32_t fm_sp_mpd; /*offset 0x30*/
96742 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96743 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96744 +};
96745 +
96746 +/**************************************************************************//**
96747 + @Description structure for defining internal context copying
96748 +*//***************************************************************************/
96749 +struct fman_sp_int_context_data_copy{
96750 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96751 + internal context is copied to (Rx)
96752 + or taken from (Tx, Op). */
96753 + uint8_t int_context_offset; /**< Offset within internal context to copy
96754 + from (Rx) or to copy to (Tx, Op).*/
96755 + uint16_t size; /**< Internal offset size to be copied */
96756 +};
96757 +
96758 +/**************************************************************************//**
96759 + @Description struct for defining external buffer margins
96760 +*//***************************************************************************/
96761 +struct fman_sp_buf_margins{
96762 + uint16_t start_margins; /**< Number of bytes to be left at the
96763 + beginning of the external buffer (must be
96764 + divisible by 16) */
96765 + uint16_t end_margins; /**< number of bytes to be left at the end of
96766 + the external buffer(must be divisible by 16)*/
96767 +};
96768 +
96769 +struct fm_storage_profile_params {
96770 + struct fman_ext_pools fm_ext_pools;
96771 + struct fman_backup_bm_pools backup_pools;
96772 + struct fman_sp_int_context_data_copy *int_context;
96773 + struct fman_sp_buf_margins *buf_margins;
96774 + enum fman_dma_swap_option dma_swap_data;
96775 + enum fman_dma_cache_option int_context_cache_attr;
96776 + enum fman_dma_cache_option header_cache_attr;
96777 + enum fman_dma_cache_option scatter_gather_cache_attr;
96778 + bool dma_write_optimize;
96779 + uint16_t liodn_offset;
96780 + bool no_scather_gather;
96781 + struct fman_buf_pool_depletion buf_pool_depletion;
96782 +};
96783 +
96784 +/**************************************************************************//**
96785 + @Description Registers bit fields
96786 +*//***************************************************************************/
96787 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96788 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96789 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96790 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96791 +#define FMAN_SP_SG_DISABLE 0x80000000
96792 +
96793 +/* shifts */
96794 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96795 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96796 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96797 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96798 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96799 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96800 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96801 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96802 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96803 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96804 +#define FMAN_SP_IC_SIZE_SHIFT 0
96805 +
96806 +/**************************************************************************//**
96807 + @Description defaults
96808 +*//***************************************************************************/
96809 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96810 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96811 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96812 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96813 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96814 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96815 +
96816 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96817 +
96818 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96819 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96820 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96821 + int max_num_of_pfc_priorities);
96822 +
96823 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96824 + uint16_t index);
96825 +
96826 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96827 + uint16_t index, uint32_t value);
96828 +
96829 +
96830 +#endif /* __FSL_FMAN_SP_H */
96831 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96832 new file mode 100644
96833 index 00000000..a0373141
96834 --- /dev/null
96835 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96836 @@ -0,0 +1,479 @@
96837 +/*
96838 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96839 + *
96840 + * Redistribution and use in source and binary forms, with or without
96841 + * modification, are permitted provided that the following conditions are met:
96842 + * * Redistributions of source code must retain the above copyright
96843 + * notice, this list of conditions and the following disclaimer.
96844 + * * Redistributions in binary form must reproduce the above copyright
96845 + * notice, this list of conditions and the following disclaimer in the
96846 + * documentation and/or other materials provided with the distribution.
96847 + * * Neither the name of Freescale Semiconductor nor the
96848 + * names of its contributors may be used to endorse or promote products
96849 + * derived from this software without specific prior written permission.
96850 + *
96851 + *
96852 + * ALTERNATIVELY, this software may be distributed under the terms of the
96853 + * GNU General Public License ("GPL") as published by the Free Software
96854 + * Foundation, either version 2 of that License or (at your option) any
96855 + * later version.
96856 + *
96857 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96858 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96859 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96860 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96861 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96862 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96863 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96864 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96865 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96866 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96867 + */
96868 +
96869 +#ifndef __FSL_FMAN_TGEC_H
96870 +#define __FSL_FMAN_TGEC_H
96871 +
96872 +#include "common/general.h"
96873 +#include "fsl_enet.h"
96874 +
96875 +
96876 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96877 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
96878 +
96879 +enum tgec_counters {
96880 + E_TGEC_COUNTER_R64,
96881 + E_TGEC_COUNTER_R127,
96882 + E_TGEC_COUNTER_R255,
96883 + E_TGEC_COUNTER_R511,
96884 + E_TGEC_COUNTER_R1023,
96885 + E_TGEC_COUNTER_R1518,
96886 + E_TGEC_COUNTER_R1519X,
96887 + E_TGEC_COUNTER_TRFRG,
96888 + E_TGEC_COUNTER_TRJBR,
96889 + E_TGEC_COUNTER_RDRP,
96890 + E_TGEC_COUNTER_RALN,
96891 + E_TGEC_COUNTER_TRUND,
96892 + E_TGEC_COUNTER_TROVR,
96893 + E_TGEC_COUNTER_RXPF,
96894 + E_TGEC_COUNTER_TXPF,
96895 + E_TGEC_COUNTER_ROCT,
96896 + E_TGEC_COUNTER_RMCA,
96897 + E_TGEC_COUNTER_RBCA,
96898 + E_TGEC_COUNTER_RPKT,
96899 + E_TGEC_COUNTER_RUCA,
96900 + E_TGEC_COUNTER_RERR,
96901 + E_TGEC_COUNTER_TOCT,
96902 + E_TGEC_COUNTER_TMCA,
96903 + E_TGEC_COUNTER_TBCA,
96904 + E_TGEC_COUNTER_TUCA,
96905 + E_TGEC_COUNTER_TERR
96906 +};
96907 +
96908 +/* Command and Configuration Register (COMMAND_CONFIG) */
96909 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
96910 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
96911 +#define CMD_CFG_NO_LEN_CHK 0x00020000
96912 +#define CMD_CFG_SEND_IDLE 0x00010000
96913 +#define CMD_CFG_RX_ER_DISC 0x00004000
96914 +#define CMD_CFG_CMD_FRM_EN 0x00002000
96915 +#define CMD_CFG_STAT_CLR 0x00001000
96916 +#define CMD_CFG_LOOPBACK_EN 0x00000400
96917 +#define CMD_CFG_TX_ADDR_INS 0x00000200
96918 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
96919 +#define CMD_CFG_PAUSE_FWD 0x00000080
96920 +#define CMD_CFG_PROMIS_EN 0x00000010
96921 +#define CMD_CFG_WAN_MODE 0x00000008
96922 +#define CMD_CFG_RX_EN 0x00000002
96923 +#define CMD_CFG_TX_EN 0x00000001
96924 +
96925 +/* Interrupt Mask Register (IMASK) */
96926 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
96927 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
96928 +#define TGEC_IMASK_REM_FAULT 0x00004000
96929 +#define TGEC_IMASK_LOC_FAULT 0x00002000
96930 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
96931 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
96932 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
96933 +#define TGEC_IMASK_TX_ER 0x00000200
96934 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
96935 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
96936 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
96937 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
96938 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
96939 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
96940 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
96941 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
96942 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
96943 +
96944 +#define TGEC_EVENTS_MASK \
96945 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
96946 + TGEC_IMASK_MDIO_CMD_CMPL | \
96947 + TGEC_IMASK_REM_FAULT | \
96948 + TGEC_IMASK_LOC_FAULT | \
96949 + TGEC_IMASK_TX_ECC_ER | \
96950 + TGEC_IMASK_TX_FIFO_UNFL | \
96951 + TGEC_IMASK_TX_FIFO_OVFL | \
96952 + TGEC_IMASK_TX_ER | \
96953 + TGEC_IMASK_RX_FIFO_OVFL | \
96954 + TGEC_IMASK_RX_ECC_ER | \
96955 + TGEC_IMASK_RX_JAB_FRM | \
96956 + TGEC_IMASK_RX_OVRSZ_FRM | \
96957 + TGEC_IMASK_RX_RUNT_FRM | \
96958 + TGEC_IMASK_RX_FRAG_FRM | \
96959 + TGEC_IMASK_RX_LEN_ER | \
96960 + TGEC_IMASK_RX_CRC_ER | \
96961 + TGEC_IMASK_RX_ALIGN_ER))
96962 +
96963 +/* Hashtable Control Register (HASHTABLE_CTRL) */
96964 +#define TGEC_HASH_MCAST_SHIFT 23
96965 +#define TGEC_HASH_MCAST_EN 0x00000200
96966 +#define TGEC_HASH_ADR_MSK 0x000001ff
96967 +
96968 +#define DEFAULT_WAN_MODE_ENABLE FALSE
96969 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
96970 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
96971 +#define DEFAULT_PAUSE_IGNORE FALSE
96972 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
96973 +#define DEFAULT_LOOPBACK_ENABLE FALSE
96974 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
96975 +#define DEFAULT_RX_ERROR_DISCARD FALSE
96976 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
96977 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
96978 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
96979 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
96980 +#define DEFAULT_TX_IPG_LENGTH 12
96981 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
96982 +#define DEFAULT_PAUSE_QUANT 0xf000
96983 +
96984 +/*
96985 + * 10G memory map
96986 + */
96987 +struct tgec_regs {
96988 + uint32_t tgec_id; /* 0x000 Controller ID */
96989 + uint32_t reserved001[1]; /* 0x004 */
96990 + uint32_t command_config; /* 0x008 Control and configuration */
96991 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
96992 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
96993 + uint32_t maxfrm; /* 0x014 Maximum frame length */
96994 + uint32_t pause_quant; /* 0x018 Pause quanta */
96995 + uint32_t rx_fifo_sections; /* 0x01c */
96996 + uint32_t tx_fifo_sections; /* 0x020 */
96997 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
96998 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
96999 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
97000 + uint32_t mdio_cfg_status; /* 0x030 */
97001 + uint32_t mdio_command; /* 0x034 */
97002 + uint32_t mdio_data; /* 0x038 */
97003 + uint32_t mdio_regaddr; /* 0x03c */
97004 + uint32_t status; /* 0x040 */
97005 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
97006 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
97007 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
97008 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
97009 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
97010 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
97011 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
97012 + uint32_t imask; /* 0x060 Interrupt mask */
97013 + uint32_t ievent; /* 0x064 Interrupt event */
97014 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
97015 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
97016 + uint32_t reserved070[4]; /* 0x070 */
97017 + /*10Ge Statistics Counter */
97018 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
97019 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
97020 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
97021 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
97022 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
97023 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
97024 + uint32_t raln_u; /* 98 aAlignmentErrors */
97025 + uint32_t raln_l; /* 9c aAlignmentErrors */
97026 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
97027 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
97028 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
97029 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
97030 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
97031 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
97032 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
97033 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
97034 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
97035 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
97036 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
97037 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
97038 + uint32_t toct_u; /* D0 ifOutOctets */
97039 + uint32_t toct_l; /* D4 ifOutOctets */
97040 + uint32_t roct_u; /* D8 ifInOctets */
97041 + uint32_t roct_l; /* Dc ifInOctets */
97042 + uint32_t ruca_u; /* E0 ifInUcastPkts */
97043 + uint32_t ruca_l; /* E4 ifInUcastPkts */
97044 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
97045 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
97046 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
97047 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
97048 + uint32_t terr_u; /* F8 ifOutErrors */
97049 + uint32_t terr_l; /* Fc ifOutErrors */
97050 + uint32_t reserved100[2]; /* 100-108*/
97051 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
97052 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
97053 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
97054 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
97055 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
97056 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
97057 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
97058 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
97059 + uint32_t reoct_u; /* 128 etherStatsOctets */
97060 + uint32_t reoct_l; /* 12c etherStatsOctets */
97061 + uint32_t rpkt_u; /* 130 etherStatsPkts */
97062 + uint32_t rpkt_l; /* 134 etherStatsPkts */
97063 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
97064 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
97065 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
97066 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
97067 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
97068 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
97069 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
97070 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
97071 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
97072 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
97073 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
97074 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
97075 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
97076 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
97077 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
97078 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
97079 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
97080 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
97081 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
97082 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
97083 + uint32_t trfrg_u; /* 188 etherStatsFragments */
97084 + uint32_t trfrg_l; /* 18C etherStatsFragments */
97085 + uint32_t rerr_u; /* 190 ifInErrors */
97086 + uint32_t rerr_l; /* 194 ifInErrors */
97087 +};
97088 +
97089 +/**
97090 + * struct tgec_cfg - TGEC configuration
97091 + *
97092 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
97093 + * any frame received with an error is discarded in the
97094 + * Core and not forwarded to the Client interface.
97095 + * When set to 0 (Reset value), erroneous Frames are
97096 + * forwarded to the Client interface with ff_rx_err
97097 + * asserted.
97098 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
97099 + * frames are ignored by the MAC. When set to 0
97100 + * (Reset value) the transmit process is stopped for the
97101 + * amount of time specified in the pause quanta received
97102 + * within a pause frame.
97103 + * @pause_forward_enable:
97104 + * Terminate / Forward Pause Frames. If set to 1 pause
97105 + * frames are forwarded to the user application. When set
97106 + * to 0 (Reset value) pause frames are terminated and
97107 + * discarded within the MAC.
97108 + * @no_length_check_enable:
97109 + * Payload Length Check Disable. When set to 0
97110 + * (Reset value), the Core checks the frame's payload
97111 + * length with the Frame Length/Type field, when set to 1
97112 + * the payload length check is disabled.
97113 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
97114 + * all Command Frames are accepted, when set to 0
97115 + * (Reset Value) only Pause Frames are accepted and all
97116 + * other Command Frames are rejected.
97117 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
97118 + * permanently sends XGMII Idle sequences even when faults
97119 + * are received.
97120 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
97121 + * (0, default) of operation.
97122 + * @promiscuous_mode_enable:
97123 + * Enables MAC promiscuous operation. When set to 1, all
97124 + * frames are received without any MAC address filtering,
97125 + * when set to 0 (Reset value) Unicast Frames with a
97126 + * destination address not matching the Core MAC Address
97127 + * (MAC Address programmed in Registers MAC_ADDR_0 and
97128 + * MAC_ADDR_1 or the MAC address programmed in Registers
97129 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
97130 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
97131 + * MAC overwrites the source MAC address received from the
97132 + * Client Interface with one of the MAC addresses. If set
97133 + * to 0 (Reset value), the source MAC address from the
97134 + * Client Interface is transmitted unmodified to the line.
97135 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
97136 + * loop_ena is set to '1', when set to 0 (Reset value)
97137 + * the signal loop_ena is set to 0.
97138 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
97139 + * depending on the value of this Bit
97140 + * @time_stamp_enable: This bit selects between enabling and disabling the
97141 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
97142 + * 0: IEEE 1588 is disabled
97143 + * @max_frame_length: Maximum supported received frame length.
97144 + * The 10GEC MAC supports reception of any frame size up
97145 + * to 16,352 bytes (0x3FE0). Typical settings are
97146 + * 0x05EE (1,518 bytes) for standard frames.
97147 + * Default setting is 0x0600 (1,536 bytes).
97148 + * Received frames that exceed this stated maximum
97149 + * are truncated.
97150 + * @pause_quant: Pause quanta value used with transmitted pause frames.
97151 + * Each quanta represents a 512 bit-times.
97152 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
97153 + * Depending on LAN or WAN mode of operation the value has
97154 + * the following meaning: - LAN Mode: Number of octets in
97155 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
97156 + * fully supported (see 10.6.1 page 49) for any setting. A
97157 + * default of 12 (reset value) must be set to conform to
97158 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
97159 + * be able to perform clock rate compensation. - WAN Mode:
97160 + * Stretch factor. Valid values are 4..15. The stretch
97161 + * factor is calculated as (value+1)*8. A default of 12
97162 + * (reset value) must be set to conform to IEEE 802.3ae
97163 + * (i.e. 13*8=104). A larger value shrinks the IPG
97164 + * (increasing bandwidth).
97165 + *
97166 + * This structure contains basic TGEC configuration and must be passed to
97167 + * fman_tgec_init() function. A default set of configuration values can be
97168 + * obtained by calling fman_tgec_defconfig().
97169 + */
97170 +struct tgec_cfg {
97171 + bool rx_error_discard;
97172 + bool pause_ignore;
97173 + bool pause_forward_enable;
97174 + bool no_length_check_enable;
97175 + bool cmd_frame_enable;
97176 + bool send_idle_enable;
97177 + bool wan_mode_enable;
97178 + bool promiscuous_mode_enable;
97179 + bool tx_addr_ins_enable;
97180 + bool loopback_enable;
97181 + bool lgth_check_nostdr;
97182 + bool time_stamp_enable;
97183 + uint16_t max_frame_length;
97184 + uint16_t pause_quant;
97185 + uint32_t tx_ipg_length;
97186 + bool skip_fman11_workaround;
97187 +};
97188 +
97189 +
97190 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
97191 +
97192 +/**
97193 + * fman_tgec_init() - Init tgec hardware block
97194 + * @regs: Pointer to tgec register block
97195 + * @cfg: tgec configuration data
97196 + * @exceptions_mask: initial exceptions mask
97197 + *
97198 + * This function initializes the tgec controller and applies its
97199 + * basic configuration.
97200 + *
97201 + * Returns: 0 if successful, an error code otherwise.
97202 + */
97203 +
97204 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
97205 + uint32_t exception_mask);
97206 +
97207 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97208 +
97209 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97210 +
97211 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
97212 +
97213 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
97214 +
97215 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
97216 +
97217 +/**
97218 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
97219 + * @regs: Pointer to TGEC register block
97220 + */
97221 +void fman_tgec_reset_stat(struct tgec_regs *regs);
97222 +
97223 +/**
97224 + * fman_tgec_get_counter() - Reads TGEC HW counters
97225 + * @regs: Pointer to TGEC register block
97226 + * @reg_name: Counter name according to the appropriate enum
97227 + *
97228 + * Returns: Required counter value
97229 + */
97230 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
97231 + enum tgec_counters reg_name);
97232 +
97233 +/**
97234 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
97235 + * @regs: Pointer to TGEC register block
97236 + * @value: Value to be written in Hashtable Control Register
97237 + */
97238 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
97239 +
97240 +/**
97241 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
97242 + * @regs: Pointer to TGEC register block
97243 + * @pause_time: Pause quanta value used with transmitted pause frames.
97244 + * Each quanta represents a 512 bit-times
97245 + */
97246 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
97247 +
97248 +/**
97249 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
97250 + * @regs: Pointer to TGEC register block
97251 + * @en: Ignore/Respond to pause frame quanta
97252 + *
97253 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
97254 + * 0 - MAC stops transmit process for the duration specified
97255 + * in the Pause frame quanta of a received Pause frame.
97256 + * 1 - MAC ignores received Pause frames.
97257 + */
97258 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
97259 +
97260 +/**
97261 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
97262 + * @regs: Pointer to TGEC register block
97263 + * @en: enable/disable timestamp functionality
97264 + *
97265 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
97266 + * IEEE 1588 timestamp functionality control:
97267 + * 0 disabled, 1 enabled
97268 + */
97269 +
97270 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
97271 +
97272 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
97273 +
97274 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
97275 +
97276 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
97277 +
97278 +/**
97279 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
97280 + * @regs: Pointer to TGEC register block
97281 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
97282 + *
97283 + * Sets the additional station MAC address
97284 + */
97285 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
97286 +
97287 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
97288 +
97289 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97290 +
97291 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97292 +
97293 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
97294 +
97295 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
97296 +
97297 +
97298 +/**
97299 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
97300 + * @regs: Pointer to TGEC register block
97301 + */
97302 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
97303 +
97304 +/**
97305 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
97306 + * main tgec configuration parameters
97307 + * @regs: Pointer to TGEC register block
97308 + *
97309 + * TODO
97310 + */
97311 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
97312 + *regs);
97313 +
97314 +
97315 +#endif /* __FSL_FMAN_TGEC_H */
97316 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97317 new file mode 100644
97318 index 00000000..0346cf60
97319 --- /dev/null
97320 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97321 @@ -0,0 +1,291 @@
97322 +/*
97323 + * Copyright 2012 Freescale Semiconductor Inc.
97324 + *
97325 + * Redistribution and use in source and binary forms, with or without
97326 + * modification, are permitted provided that the following conditions are met:
97327 + * * Redistributions of source code must retain the above copyright
97328 + * notice, this list of conditions and the following disclaimer.
97329 + * * Redistributions in binary form must reproduce the above copyright
97330 + * notice, this list of conditions and the following disclaimer in the
97331 + * documentation and/or other materials provided with the distribution.
97332 + * * Neither the name of Freescale Semiconductor nor the
97333 + * names of its contributors may be used to endorse or promote products
97334 + * derived from this software without specific prior written permission.
97335 + *
97336 + *
97337 + * ALTERNATIVELY, this software may be distributed under the terms of the
97338 + * GNU General Public License ("GPL") as published by the Free Software
97339 + * Foundation, either version 2 of that License or (at your option) any
97340 + * later version.
97341 + *
97342 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97343 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97344 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97345 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97346 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97347 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97348 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97349 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97350 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97351 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97352 + */
97353 +
97354 +/**
97355 +
97356 + @File dpaa_integration_ext.h
97357 +
97358 + @Description T4240 FM external definitions and structures.
97359 +*//***************************************************************************/
97360 +#ifndef __DPAA_INTEGRATION_EXT_H
97361 +#define __DPAA_INTEGRATION_EXT_H
97362 +
97363 +#include "std_ext.h"
97364 +
97365 +
97366 +#define DPAA_VERSION 11
97367 +
97368 +/**************************************************************************//**
97369 + @Description DPAA SW Portals Enumeration.
97370 +*//***************************************************************************/
97371 +typedef enum
97372 +{
97373 + e_DPAA_SWPORTAL0 = 0,
97374 + e_DPAA_SWPORTAL1,
97375 + e_DPAA_SWPORTAL2,
97376 + e_DPAA_SWPORTAL3,
97377 + e_DPAA_SWPORTAL4,
97378 + e_DPAA_SWPORTAL5,
97379 + e_DPAA_SWPORTAL6,
97380 + e_DPAA_SWPORTAL7,
97381 + e_DPAA_SWPORTAL8,
97382 + e_DPAA_SWPORTAL9,
97383 + e_DPAA_SWPORTAL10,
97384 + e_DPAA_SWPORTAL11,
97385 + e_DPAA_SWPORTAL12,
97386 + e_DPAA_SWPORTAL13,
97387 + e_DPAA_SWPORTAL14,
97388 + e_DPAA_SWPORTAL15,
97389 + e_DPAA_SWPORTAL16,
97390 + e_DPAA_SWPORTAL17,
97391 + e_DPAA_SWPORTAL18,
97392 + e_DPAA_SWPORTAL19,
97393 + e_DPAA_SWPORTAL20,
97394 + e_DPAA_SWPORTAL21,
97395 + e_DPAA_SWPORTAL22,
97396 + e_DPAA_SWPORTAL23,
97397 + e_DPAA_SWPORTAL24,
97398 + e_DPAA_SWPORTAL_DUMMY_LAST
97399 +} e_DpaaSwPortal;
97400 +
97401 +/**************************************************************************//**
97402 + @Description DPAA Direct Connect Portals Enumeration.
97403 +*//***************************************************************************/
97404 +typedef enum
97405 +{
97406 + e_DPAA_DCPORTAL0 = 0,
97407 + e_DPAA_DCPORTAL1,
97408 + e_DPAA_DCPORTAL2,
97409 + e_DPAA_DCPORTAL_DUMMY_LAST
97410 +} e_DpaaDcPortal;
97411 +
97412 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97413 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97414 +
97415 +/*****************************************************************************
97416 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97417 +******************************************************************************/
97418 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97419 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97420 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97421 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97422 + /**< FQIDs range - 24 bits */
97423 +
97424 +/**************************************************************************//**
97425 + @Description Work Queue Channel assignments in QMan.
97426 +*//***************************************************************************/
97427 +typedef enum
97428 +{
97429 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97430 + e_QM_FQ_CHANNEL_SWPORTAL1,
97431 + e_QM_FQ_CHANNEL_SWPORTAL2,
97432 + e_QM_FQ_CHANNEL_SWPORTAL3,
97433 + e_QM_FQ_CHANNEL_SWPORTAL4,
97434 + e_QM_FQ_CHANNEL_SWPORTAL5,
97435 + e_QM_FQ_CHANNEL_SWPORTAL6,
97436 + e_QM_FQ_CHANNEL_SWPORTAL7,
97437 + e_QM_FQ_CHANNEL_SWPORTAL8,
97438 + e_QM_FQ_CHANNEL_SWPORTAL9,
97439 + e_QM_FQ_CHANNEL_SWPORTAL10,
97440 + e_QM_FQ_CHANNEL_SWPORTAL11,
97441 + e_QM_FQ_CHANNEL_SWPORTAL12,
97442 + e_QM_FQ_CHANNEL_SWPORTAL13,
97443 + e_QM_FQ_CHANNEL_SWPORTAL14,
97444 + e_QM_FQ_CHANNEL_SWPORTAL15,
97445 + e_QM_FQ_CHANNEL_SWPORTAL16,
97446 + e_QM_FQ_CHANNEL_SWPORTAL17,
97447 + e_QM_FQ_CHANNEL_SWPORTAL18,
97448 + e_QM_FQ_CHANNEL_SWPORTAL19,
97449 + e_QM_FQ_CHANNEL_SWPORTAL20,
97450 + e_QM_FQ_CHANNEL_SWPORTAL21,
97451 + e_QM_FQ_CHANNEL_SWPORTAL22,
97452 + e_QM_FQ_CHANNEL_SWPORTAL23,
97453 + e_QM_FQ_CHANNEL_SWPORTAL24,
97454 +
97455 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97456 + e_QM_FQ_CHANNEL_POOL2,
97457 + e_QM_FQ_CHANNEL_POOL3,
97458 + e_QM_FQ_CHANNEL_POOL4,
97459 + e_QM_FQ_CHANNEL_POOL5,
97460 + e_QM_FQ_CHANNEL_POOL6,
97461 + e_QM_FQ_CHANNEL_POOL7,
97462 + e_QM_FQ_CHANNEL_POOL8,
97463 + e_QM_FQ_CHANNEL_POOL9,
97464 + e_QM_FQ_CHANNEL_POOL10,
97465 + e_QM_FQ_CHANNEL_POOL11,
97466 + e_QM_FQ_CHANNEL_POOL12,
97467 + e_QM_FQ_CHANNEL_POOL13,
97468 + e_QM_FQ_CHANNEL_POOL14,
97469 + e_QM_FQ_CHANNEL_POOL15,
97470 +
97471 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97472 + connected to FMan 0; assigned in incrementing order to
97473 + each sub-portal (SP) in the portal */
97474 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97475 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97476 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97477 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97478 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97479 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97480 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97481 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97482 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97483 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97484 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97485 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97486 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97487 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97488 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97489 +
97490 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97491 + e_QM_FQ_CHANNEL_RMAN_SP1,
97492 +
97493 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97494 + connected to SEC */
97495 +} e_QmFQChannel;
97496 +
97497 +/*****************************************************************************
97498 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97499 +******************************************************************************/
97500 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97501 +
97502 +/*****************************************************************************
97503 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97504 +******************************************************************************/
97505 +#define SEC_NUM_OF_DECOS 3
97506 +#define SEC_ALL_DECOS_MASK 0x00000003
97507 +
97508 +
97509 +/*****************************************************************************
97510 + FM INTEGRATION-SPECIFIC DEFINITIONS
97511 +******************************************************************************/
97512 +#define INTG_MAX_NUM_OF_FM 2
97513 +/* Ports defines */
97514 +#define FM_MAX_NUM_OF_1G_MACS 6
97515 +#define FM_MAX_NUM_OF_10G_MACS 2
97516 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97517 +#define FM_MAX_NUM_OF_OH_PORTS 6
97518 +
97519 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97520 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97521 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97522 +
97523 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97524 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97525 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97526 +
97527 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97528 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97529 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97530 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97531 +
97532 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97533 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97534 +
97535 +/* RAMs defines */
97536 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97537 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97538 +#define FM_NUM_OF_CTRL 4
97539 +
97540 +/* PCD defines */
97541 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97542 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97543 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97544 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97545 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97546 +
97547 +/* RTC defines */
97548 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97549 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97550 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97551 +
97552 +/* QMI defines */
97553 +#define QMI_MAX_NUM_OF_TNUMS 64
97554 +#define QMI_DEF_TNUMS_THRESH 32
97555 +/* FPM defines */
97556 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97557 +
97558 +/* DMA defines */
97559 +#define DMA_THRESH_MAX_COMMQ 83
97560 +#define DMA_THRESH_MAX_BUF 127
97561 +
97562 +/* BMI defines */
97563 +#define BMI_MAX_NUM_OF_TASKS 128
97564 +#define BMI_MAX_NUM_OF_DMAS 84
97565 +
97566 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97567 +#define PORT_MAX_WEIGHT 16
97568 +
97569 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97570 +
97571 +/* Unique T4240 */
97572 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97573 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97574 +#define FM_NO_OP_OBSERVED_POOLS
97575 +#define FM_FRAME_END_PARAMS_FOR_OP
97576 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97577 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97578 +
97579 +#define FM_NO_GUARANTEED_RESET_VALUES
97580 +
97581 +/* FM errata */
97582 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97583 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97584 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97585 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97586 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97587 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97588 +
97589 +#define FM_BCB_ERRATA_BMI_SW001
97590 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97591 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97592 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97593 +
97594 +/*****************************************************************************
97595 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97596 +******************************************************************************/
97597 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97598 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97599 +
97600 +/* RMan erratas */
97601 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97602 +
97603 +/*****************************************************************************
97604 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97605 +******************************************************************************/
97606 +#define NUM_OF_RX_SC 16
97607 +#define NUM_OF_TX_SC 16
97608 +
97609 +#define NUM_OF_SA_PER_RX_SC 2
97610 +#define NUM_OF_SA_PER_TX_SC 2
97611 +
97612 +#endif /* __DPAA_INTEGRATION_EXT_H */
97613 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97614 new file mode 100644
97615 index 00000000..0d62dd15
97616 --- /dev/null
97617 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97618 @@ -0,0 +1,71 @@
97619 +/*
97620 + * Copyright 2012 Freescale Semiconductor Inc.
97621 + *
97622 + * Redistribution and use in source and binary forms, with or without
97623 + * modification, are permitted provided that the following conditions are met:
97624 + * * Redistributions of source code must retain the above copyright
97625 + * notice, this list of conditions and the following disclaimer.
97626 + * * Redistributions in binary form must reproduce the above copyright
97627 + * notice, this list of conditions and the following disclaimer in the
97628 + * documentation and/or other materials provided with the distribution.
97629 + * * Neither the name of Freescale Semiconductor nor the
97630 + * names of its contributors may be used to endorse or promote products
97631 + * derived from this software without specific prior written permission.
97632 + *
97633 + *
97634 + * ALTERNATIVELY, this software may be distributed under the terms of the
97635 + * GNU General Public License ("GPL") as published by the Free Software
97636 + * Foundation, either version 2 of that License or (at your option) any
97637 + * later version.
97638 + *
97639 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97640 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97641 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97642 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97643 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97644 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97645 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97646 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97647 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97648 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97649 + */
97650 +
97651 +/**************************************************************************//**
97652 +
97653 + @File part_ext.h
97654 +
97655 + @Description Definitions for the part (integration) module.
97656 +*//***************************************************************************/
97657 +
97658 +#ifndef __PART_EXT_H
97659 +#define __PART_EXT_H
97660 +
97661 +#include "std_ext.h"
97662 +#include "part_integration_ext.h"
97663 +
97664 +#if !(defined(P1023) || \
97665 + defined(P2041) || \
97666 + defined(P3041) || \
97667 + defined(P4080) || \
97668 + defined(P5020) || \
97669 + defined(P5040) || \
97670 + defined(B4860) || \
97671 + defined(T4240))
97672 +#error "unable to proceed without chip-definition"
97673 +#endif
97674 +
97675 +
97676 +/**************************************************************************//*
97677 + @Description Part data structure - must be contained in any integration
97678 + data structure.
97679 +*//***************************************************************************/
97680 +typedef struct t_Part
97681 +{
97682 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97683 + /**< Returns the address of the module's memory map base. */
97684 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97685 + /**< Returns the module's ID according to its memory map base. */
97686 +} t_Part;
97687 +
97688 +
97689 +#endif /* __PART_EXT_H */
97690 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97691 new file mode 100644
97692 index 00000000..3254c766
97693 --- /dev/null
97694 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97695 @@ -0,0 +1,304 @@
97696 +/*
97697 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97698 + *
97699 + * Redistribution and use in source and binary forms, with or without
97700 + * modification, are permitted provided that the following conditions are met:
97701 + * * Redistributions of source code must retain the above copyright
97702 + * notice, this list of conditions and the following disclaimer.
97703 + * * Redistributions in binary form must reproduce the above copyright
97704 + * notice, this list of conditions and the following disclaimer in the
97705 + * documentation and/or other materials provided with the distribution.
97706 + * * Neither the name of Freescale Semiconductor nor the
97707 + * names of its contributors may be used to endorse or promote products
97708 + * derived from this software without specific prior written permission.
97709 + *
97710 + *
97711 + * ALTERNATIVELY, this software may be distributed under the terms of the
97712 + * GNU General Public License ("GPL") as published by the Free Software
97713 + * Foundation, either version 2 of that License or (at your option) any
97714 + * later version.
97715 + *
97716 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97717 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97718 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97719 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97720 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97721 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97722 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97723 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97724 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97725 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97726 + */
97727 +
97728 +/**
97729 +
97730 + @File part_integration_ext.h
97731 +
97732 + @Description T4240 external definitions and structures.
97733 +*//***************************************************************************/
97734 +#ifndef __PART_INTEGRATION_EXT_H
97735 +#define __PART_INTEGRATION_EXT_H
97736 +
97737 +#include "std_ext.h"
97738 +#include "ddr_std_ext.h"
97739 +#include "enet_ext.h"
97740 +#include "dpaa_integration_ext.h"
97741 +
97742 +
97743 +/**************************************************************************//**
97744 + @Group T4240_chip_id T4240 Application Programming Interface
97745 +
97746 + @Description T4240 Chip functions,definitions and enums.
97747 +
97748 + @{
97749 +*//***************************************************************************/
97750 +
97751 +#define CORE_E6500
97752 +
97753 +#define INTG_MAX_NUM_OF_CORES 24
97754 +
97755 +
97756 +/**************************************************************************//**
97757 + @Description Module types.
97758 +*//***************************************************************************/
97759 +typedef enum e_ModuleId
97760 +{
97761 + e_MODULE_ID_DUART_1 = 0,
97762 + e_MODULE_ID_DUART_2,
97763 + e_MODULE_ID_DUART_3,
97764 + e_MODULE_ID_DUART_4,
97765 + e_MODULE_ID_LAW,
97766 + e_MODULE_ID_IFC,
97767 + e_MODULE_ID_PAMU,
97768 + e_MODULE_ID_QM, /**< Queue manager module */
97769 + e_MODULE_ID_BM, /**< Buffer manager module */
97770 + e_MODULE_ID_QM_CE_PORTAL_0,
97771 + e_MODULE_ID_QM_CI_PORTAL_0,
97772 + e_MODULE_ID_QM_CE_PORTAL_1,
97773 + e_MODULE_ID_QM_CI_PORTAL_1,
97774 + e_MODULE_ID_QM_CE_PORTAL_2,
97775 + e_MODULE_ID_QM_CI_PORTAL_2,
97776 + e_MODULE_ID_QM_CE_PORTAL_3,
97777 + e_MODULE_ID_QM_CI_PORTAL_3,
97778 + e_MODULE_ID_QM_CE_PORTAL_4,
97779 + e_MODULE_ID_QM_CI_PORTAL_4,
97780 + e_MODULE_ID_QM_CE_PORTAL_5,
97781 + e_MODULE_ID_QM_CI_PORTAL_5,
97782 + e_MODULE_ID_QM_CE_PORTAL_6,
97783 + e_MODULE_ID_QM_CI_PORTAL_6,
97784 + e_MODULE_ID_QM_CE_PORTAL_7,
97785 + e_MODULE_ID_QM_CI_PORTAL_7,
97786 + e_MODULE_ID_QM_CE_PORTAL_8,
97787 + e_MODULE_ID_QM_CI_PORTAL_8,
97788 + e_MODULE_ID_QM_CE_PORTAL_9,
97789 + e_MODULE_ID_QM_CI_PORTAL_9,
97790 + e_MODULE_ID_BM_CE_PORTAL_0,
97791 + e_MODULE_ID_BM_CI_PORTAL_0,
97792 + e_MODULE_ID_BM_CE_PORTAL_1,
97793 + e_MODULE_ID_BM_CI_PORTAL_1,
97794 + e_MODULE_ID_BM_CE_PORTAL_2,
97795 + e_MODULE_ID_BM_CI_PORTAL_2,
97796 + e_MODULE_ID_BM_CE_PORTAL_3,
97797 + e_MODULE_ID_BM_CI_PORTAL_3,
97798 + e_MODULE_ID_BM_CE_PORTAL_4,
97799 + e_MODULE_ID_BM_CI_PORTAL_4,
97800 + e_MODULE_ID_BM_CE_PORTAL_5,
97801 + e_MODULE_ID_BM_CI_PORTAL_5,
97802 + e_MODULE_ID_BM_CE_PORTAL_6,
97803 + e_MODULE_ID_BM_CI_PORTAL_6,
97804 + e_MODULE_ID_BM_CE_PORTAL_7,
97805 + e_MODULE_ID_BM_CI_PORTAL_7,
97806 + e_MODULE_ID_BM_CE_PORTAL_8,
97807 + e_MODULE_ID_BM_CI_PORTAL_8,
97808 + e_MODULE_ID_BM_CE_PORTAL_9,
97809 + e_MODULE_ID_BM_CI_PORTAL_9,
97810 + e_MODULE_ID_FM, /**< Frame manager module */
97811 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97812 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97813 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97814 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97815 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97816 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97817 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97818 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97819 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97820 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97821 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97822 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97823 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97824 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97825 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97826 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97827 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97828 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97829 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97830 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97831 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97832 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97833 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97834 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97835 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97836 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97837 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97838 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97839 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
97840 + e_MODULE_ID_FM_KG, /**< FM Keygen */
97841 + e_MODULE_ID_FM_DMA, /**< FM DMA */
97842 + e_MODULE_ID_FM_FPM, /**< FM FPM */
97843 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
97844 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
97845 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
97846 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
97847 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
97848 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
97849 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
97850 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
97851 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
97852 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
97853 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
97854 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
97855 +
97856 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
97857 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
97858 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
97859 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
97860 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
97861 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
97862 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
97863 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
97864 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
97865 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
97866 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
97867 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
97868 +
97869 + e_MODULE_ID_PIC, /**< PIC */
97870 + e_MODULE_ID_GPIO, /**< GPIO */
97871 + e_MODULE_ID_SERDES, /**< SERDES */
97872 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
97873 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
97874 +
97875 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
97876 +
97877 + e_MODULE_ID_DUMMY_LAST
97878 +} e_ModuleId;
97879 +
97880 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
97881 +
97882 +#if 0 /* using unified values */
97883 +/*****************************************************************************
97884 + INTEGRATION-SPECIFIC MODULE CODES
97885 +******************************************************************************/
97886 +#define MODULE_UNKNOWN 0x00000000
97887 +#define MODULE_MEM 0x00010000
97888 +#define MODULE_MM 0x00020000
97889 +#define MODULE_CORE 0x00030000
97890 +#define MODULE_T4240 0x00040000
97891 +#define MODULE_T4240_PLATFORM 0x00050000
97892 +#define MODULE_PM 0x00060000
97893 +#define MODULE_MMU 0x00070000
97894 +#define MODULE_PIC 0x00080000
97895 +#define MODULE_CPC 0x00090000
97896 +#define MODULE_DUART 0x000a0000
97897 +#define MODULE_SERDES 0x000b0000
97898 +#define MODULE_PIO 0x000c0000
97899 +#define MODULE_QM 0x000d0000
97900 +#define MODULE_BM 0x000e0000
97901 +#define MODULE_SEC 0x000f0000
97902 +#define MODULE_LAW 0x00100000
97903 +#define MODULE_LBC 0x00110000
97904 +#define MODULE_PAMU 0x00120000
97905 +#define MODULE_FM 0x00130000
97906 +#define MODULE_FM_MURAM 0x00140000
97907 +#define MODULE_FM_PCD 0x00150000
97908 +#define MODULE_FM_RTC 0x00160000
97909 +#define MODULE_FM_MAC 0x00170000
97910 +#define MODULE_FM_PORT 0x00180000
97911 +#define MODULE_FM_SP 0x00190000
97912 +#define MODULE_DPA_PORT 0x001a0000
97913 +#define MODULE_MII 0x001b0000
97914 +#define MODULE_I2C 0x001c0000
97915 +#define MODULE_DMA 0x001d0000
97916 +#define MODULE_DDR 0x001e0000
97917 +#define MODULE_ESPI 0x001f0000
97918 +#define MODULE_DPAA_IPSEC 0x00200000
97919 +#endif /* using unified values */
97920 +
97921 +/*****************************************************************************
97922 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
97923 +******************************************************************************/
97924 +#define PAMU_NUM_OF_PARTITIONS 4
97925 +
97926 +/*****************************************************************************
97927 + LAW INTEGRATION-SPECIFIC DEFINITIONS
97928 +******************************************************************************/
97929 +#define LAW_NUM_OF_WINDOWS 32
97930 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
97931 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
97932 +
97933 +
97934 +/*****************************************************************************
97935 + LBC INTEGRATION-SPECIFIC DEFINITIONS
97936 +******************************************************************************/
97937 +/**************************************************************************//**
97938 + @Group lbc_exception_grp LBC Exception Unit
97939 +
97940 + @Description LBC Exception unit API functions, definitions and enums
97941 +
97942 + @{
97943 +*//***************************************************************************/
97944 +
97945 +/**************************************************************************//**
97946 + @Anchor lbc_exbm
97947 +
97948 + @Collection LBC Errors Bit Mask
97949 +
97950 + These errors are reported through the exceptions callback..
97951 + The values can be or'ed in any combination in the errors mask
97952 + parameter of the errors report structure.
97953 +
97954 + These errors can also be passed as a bit-mask to
97955 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
97956 + for enabling or disabling error checking.
97957 + @{
97958 +*//***************************************************************************/
97959 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
97960 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
97961 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
97962 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
97963 +
97964 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
97965 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
97966 + /**< All possible errors */
97967 +/* @} */
97968 +/** @} */ /* end of lbc_exception_grp group */
97969 +
97970 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
97971 +
97972 +#define LBC_NUM_OF_BANKS 8
97973 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
97974 +#define LBC_PARITY_SUPPORT
97975 +#define LBC_ADDRESS_HOLD_TIME_CTRL
97976 +#define LBC_HIGH_CLK_DIVIDERS
97977 +#define LBC_FCM_AVAILABLE
97978 +
97979 +/*****************************************************************************
97980 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
97981 +******************************************************************************/
97982 +#define GPIO_PORT_OFFSET_0x1000
97983 +
97984 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
97985 + Each port contains up to 32 I/O pins. */
97986 +
97987 +#define GPIO_VALID_PIN_MASKS \
97988 + { /* Port A */ 0xFFFFFFFF, \
97989 + /* Port B */ 0xFFFFFFFF, \
97990 + /* Port C */ 0xFFFFFFFF }
97991 +
97992 +#define GPIO_VALID_INTR_MASKS \
97993 + { /* Port A */ 0xFFFFFFFF, \
97994 + /* Port B */ 0xFFFFFFFF, \
97995 + /* Port C */ 0xFFFFFFFF }
97996 +
97997 +
97998 +
97999 +#endif /* __PART_INTEGRATION_EXT_H */
98000 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
98001 new file mode 100644
98002 index 00000000..f7f8eb07
98003 --- /dev/null
98004 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
98005 @@ -0,0 +1,293 @@
98006 +/*
98007 + * Copyright 2012 Freescale Semiconductor Inc.
98008 + *
98009 + * Redistribution and use in source and binary forms, with or without
98010 + * modification, are permitted provided that the following conditions are met:
98011 + * * Redistributions of source code must retain the above copyright
98012 + * notice, this list of conditions and the following disclaimer.
98013 + * * Redistributions in binary form must reproduce the above copyright
98014 + * notice, this list of conditions and the following disclaimer in the
98015 + * documentation and/or other materials provided with the distribution.
98016 + * * Neither the name of Freescale Semiconductor nor the
98017 + * names of its contributors may be used to endorse or promote products
98018 + * derived from this software without specific prior written permission.
98019 + *
98020 + *
98021 + * ALTERNATIVELY, this software may be distributed under the terms of the
98022 + * GNU General Public License ("GPL") as published by the Free Software
98023 + * Foundation, either version 2 of that License or (at your option) any
98024 + * later version.
98025 + *
98026 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98027 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98028 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98029 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98030 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98031 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98032 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98033 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98034 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98035 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98036 + */
98037 +
98038 +/**
98039 +
98040 + @File dpaa_integration_ext.h
98041 +
98042 + @Description T4240 FM external definitions and structures.
98043 +*//***************************************************************************/
98044 +#ifndef __DPAA_INTEGRATION_EXT_H
98045 +#define __DPAA_INTEGRATION_EXT_H
98046 +
98047 +#include "std_ext.h"
98048 +
98049 +
98050 +#define DPAA_VERSION 11
98051 +
98052 +/**************************************************************************//**
98053 + @Description DPAA SW Portals Enumeration.
98054 +*//***************************************************************************/
98055 +typedef enum
98056 +{
98057 + e_DPAA_SWPORTAL0 = 0,
98058 + e_DPAA_SWPORTAL1,
98059 + e_DPAA_SWPORTAL2,
98060 + e_DPAA_SWPORTAL3,
98061 + e_DPAA_SWPORTAL4,
98062 + e_DPAA_SWPORTAL5,
98063 + e_DPAA_SWPORTAL6,
98064 + e_DPAA_SWPORTAL7,
98065 + e_DPAA_SWPORTAL8,
98066 + e_DPAA_SWPORTAL9,
98067 + e_DPAA_SWPORTAL10,
98068 + e_DPAA_SWPORTAL11,
98069 + e_DPAA_SWPORTAL12,
98070 + e_DPAA_SWPORTAL13,
98071 + e_DPAA_SWPORTAL14,
98072 + e_DPAA_SWPORTAL15,
98073 + e_DPAA_SWPORTAL16,
98074 + e_DPAA_SWPORTAL17,
98075 + e_DPAA_SWPORTAL18,
98076 + e_DPAA_SWPORTAL19,
98077 + e_DPAA_SWPORTAL20,
98078 + e_DPAA_SWPORTAL21,
98079 + e_DPAA_SWPORTAL22,
98080 + e_DPAA_SWPORTAL23,
98081 + e_DPAA_SWPORTAL24,
98082 + e_DPAA_SWPORTAL_DUMMY_LAST
98083 +} e_DpaaSwPortal;
98084 +
98085 +/**************************************************************************//**
98086 + @Description DPAA Direct Connect Portals Enumeration.
98087 +*//***************************************************************************/
98088 +typedef enum
98089 +{
98090 + e_DPAA_DCPORTAL0 = 0,
98091 + e_DPAA_DCPORTAL1,
98092 + e_DPAA_DCPORTAL2,
98093 + e_DPAA_DCPORTAL_DUMMY_LAST
98094 +} e_DpaaDcPortal;
98095 +
98096 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98097 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98098 +
98099 +/*****************************************************************************
98100 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98101 +******************************************************************************/
98102 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98103 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98104 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98105 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98106 + /**< FQIDs range - 24 bits */
98107 +
98108 +/**************************************************************************//**
98109 + @Description Work Queue Channel assignments in QMan.
98110 +*//***************************************************************************/
98111 +typedef enum
98112 +{
98113 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98114 + e_QM_FQ_CHANNEL_SWPORTAL1,
98115 + e_QM_FQ_CHANNEL_SWPORTAL2,
98116 + e_QM_FQ_CHANNEL_SWPORTAL3,
98117 + e_QM_FQ_CHANNEL_SWPORTAL4,
98118 + e_QM_FQ_CHANNEL_SWPORTAL5,
98119 + e_QM_FQ_CHANNEL_SWPORTAL6,
98120 + e_QM_FQ_CHANNEL_SWPORTAL7,
98121 + e_QM_FQ_CHANNEL_SWPORTAL8,
98122 + e_QM_FQ_CHANNEL_SWPORTAL9,
98123 + e_QM_FQ_CHANNEL_SWPORTAL10,
98124 + e_QM_FQ_CHANNEL_SWPORTAL11,
98125 + e_QM_FQ_CHANNEL_SWPORTAL12,
98126 + e_QM_FQ_CHANNEL_SWPORTAL13,
98127 + e_QM_FQ_CHANNEL_SWPORTAL14,
98128 + e_QM_FQ_CHANNEL_SWPORTAL15,
98129 + e_QM_FQ_CHANNEL_SWPORTAL16,
98130 + e_QM_FQ_CHANNEL_SWPORTAL17,
98131 + e_QM_FQ_CHANNEL_SWPORTAL18,
98132 + e_QM_FQ_CHANNEL_SWPORTAL19,
98133 + e_QM_FQ_CHANNEL_SWPORTAL20,
98134 + e_QM_FQ_CHANNEL_SWPORTAL21,
98135 + e_QM_FQ_CHANNEL_SWPORTAL22,
98136 + e_QM_FQ_CHANNEL_SWPORTAL23,
98137 + e_QM_FQ_CHANNEL_SWPORTAL24,
98138 +
98139 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98140 + e_QM_FQ_CHANNEL_POOL2,
98141 + e_QM_FQ_CHANNEL_POOL3,
98142 + e_QM_FQ_CHANNEL_POOL4,
98143 + e_QM_FQ_CHANNEL_POOL5,
98144 + e_QM_FQ_CHANNEL_POOL6,
98145 + e_QM_FQ_CHANNEL_POOL7,
98146 + e_QM_FQ_CHANNEL_POOL8,
98147 + e_QM_FQ_CHANNEL_POOL9,
98148 + e_QM_FQ_CHANNEL_POOL10,
98149 + e_QM_FQ_CHANNEL_POOL11,
98150 + e_QM_FQ_CHANNEL_POOL12,
98151 + e_QM_FQ_CHANNEL_POOL13,
98152 + e_QM_FQ_CHANNEL_POOL14,
98153 + e_QM_FQ_CHANNEL_POOL15,
98154 +
98155 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98156 + connected to FMan 0; assigned in incrementing order to
98157 + each sub-portal (SP) in the portal */
98158 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98159 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98160 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98161 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98162 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98163 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98164 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98165 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98166 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98167 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98168 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98169 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98170 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98171 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98172 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98173 +
98174 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98175 + e_QM_FQ_CHANNEL_RMAN_SP1,
98176 +
98177 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98178 + connected to SEC */
98179 +} e_QmFQChannel;
98180 +
98181 +/*****************************************************************************
98182 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98183 +******************************************************************************/
98184 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98185 +
98186 +/*****************************************************************************
98187 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98188 +******************************************************************************/
98189 +#define SEC_NUM_OF_DECOS 3
98190 +#define SEC_ALL_DECOS_MASK 0x00000003
98191 +
98192 +
98193 +/*****************************************************************************
98194 + FM INTEGRATION-SPECIFIC DEFINITIONS
98195 +******************************************************************************/
98196 +#define INTG_MAX_NUM_OF_FM 1
98197 +/* Ports defines */
98198 +#define FM_MAX_NUM_OF_1G_MACS 5
98199 +#define FM_MAX_NUM_OF_10G_MACS 1
98200 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98201 +#define FM_MAX_NUM_OF_OH_PORTS 4
98202 +
98203 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98204 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98205 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98206 +
98207 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98208 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98209 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98210 +
98211 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
98212 +
98213 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98214 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98215 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98216 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98217 +
98218 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
98219 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98220 +
98221 +/* RAMs defines */
98222 +#define FM_MURAM_SIZE (192 * KILOBYTE)
98223 +#define FM_IRAM_SIZE(major, minor) \
98224 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
98225 +#define FM_NUM_OF_CTRL 2
98226 +
98227 +/* PCD defines */
98228 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98229 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98230 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98231 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98232 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98233 +
98234 +/* RTC defines */
98235 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98236 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98237 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98238 +
98239 +/* QMI defines */
98240 +#define QMI_MAX_NUM_OF_TNUMS 64
98241 +#define QMI_DEF_TNUMS_THRESH 32
98242 +/* FPM defines */
98243 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98244 +
98245 +/* DMA defines */
98246 +#define DMA_THRESH_MAX_COMMQ 83
98247 +#define DMA_THRESH_MAX_BUF 127
98248 +
98249 +/* BMI defines */
98250 +#define BMI_MAX_NUM_OF_TASKS 64
98251 +#define BMI_MAX_NUM_OF_DMAS 32
98252 +
98253 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98254 +#define PORT_MAX_WEIGHT 16
98255 +
98256 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98257 +
98258 +/* Unique T4240 */
98259 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98260 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98261 +#define FM_NO_OP_OBSERVED_POOLS
98262 +#define FM_FRAME_END_PARAMS_FOR_OP
98263 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98264 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98265 +
98266 +#define FM_NO_GUARANTEED_RESET_VALUES
98267 +
98268 +/* FM errata */
98269 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98270 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98271 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98272 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98273 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
98274 +
98275 +#define FM_BCB_ERRATA_BMI_SW001
98276 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98277 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98278 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98279 +
98280 +/*****************************************************************************
98281 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98282 +******************************************************************************/
98283 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98284 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98285 +
98286 +/* RMan erratas */
98287 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98288 +
98289 +/*****************************************************************************
98290 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98291 +******************************************************************************/
98292 +#define NUM_OF_RX_SC 16
98293 +#define NUM_OF_TX_SC 16
98294 +
98295 +#define NUM_OF_SA_PER_RX_SC 2
98296 +#define NUM_OF_SA_PER_TX_SC 2
98297 +
98298 +#endif /* __DPAA_INTEGRATION_EXT_H */
98299 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98300 new file mode 100644
98301 index 00000000..ba9732ee
98302 --- /dev/null
98303 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98304 @@ -0,0 +1,59 @@
98305 +/*
98306 + * Copyright 2012 Freescale Semiconductor Inc.
98307 + *
98308 + * Redistribution and use in source and binary forms, with or without
98309 + * modification, are permitted provided that the following conditions are met:
98310 + * * Redistributions of source code must retain the above copyright
98311 + * notice, this list of conditions and the following disclaimer.
98312 + * * Redistributions in binary form must reproduce the above copyright
98313 + * notice, this list of conditions and the following disclaimer in the
98314 + * documentation and/or other materials provided with the distribution.
98315 + * * Neither the name of Freescale Semiconductor nor the
98316 + * names of its contributors may be used to endorse or promote products
98317 + * derived from this software without specific prior written permission.
98318 + *
98319 + *
98320 + * ALTERNATIVELY, this software may be distributed under the terms of the
98321 + * GNU General Public License ("GPL") as published by the Free Software
98322 + * Foundation, either version 2 of that License or (at your option) any
98323 + * later version.
98324 + *
98325 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98326 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98327 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98328 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98329 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98330 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98331 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98332 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98333 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98334 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98335 + */
98336 +
98337 +/**************************************************************************//**
98338 +
98339 + @File part_ext.h
98340 +
98341 + @Description Definitions for the part (integration) module.
98342 +*//***************************************************************************/
98343 +
98344 +#ifndef __PART_EXT_H
98345 +#define __PART_EXT_H
98346 +
98347 +#include "std_ext.h"
98348 +#include "part_integration_ext.h"
98349 +
98350 +/**************************************************************************//*
98351 + @Description Part data structure - must be contained in any integration
98352 + data structure.
98353 +*//***************************************************************************/
98354 +typedef struct t_Part
98355 +{
98356 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98357 + /**< Returns the address of the module's memory map base. */
98358 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98359 + /**< Returns the module's ID according to its memory map base. */
98360 +} t_Part;
98361 +
98362 +
98363 +#endif /* __PART_EXT_H */
98364 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98365 new file mode 100644
98366 index 00000000..3254c766
98367 --- /dev/null
98368 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98369 @@ -0,0 +1,304 @@
98370 +/*
98371 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98372 + *
98373 + * Redistribution and use in source and binary forms, with or without
98374 + * modification, are permitted provided that the following conditions are met:
98375 + * * Redistributions of source code must retain the above copyright
98376 + * notice, this list of conditions and the following disclaimer.
98377 + * * Redistributions in binary form must reproduce the above copyright
98378 + * notice, this list of conditions and the following disclaimer in the
98379 + * documentation and/or other materials provided with the distribution.
98380 + * * Neither the name of Freescale Semiconductor nor the
98381 + * names of its contributors may be used to endorse or promote products
98382 + * derived from this software without specific prior written permission.
98383 + *
98384 + *
98385 + * ALTERNATIVELY, this software may be distributed under the terms of the
98386 + * GNU General Public License ("GPL") as published by the Free Software
98387 + * Foundation, either version 2 of that License or (at your option) any
98388 + * later version.
98389 + *
98390 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98391 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98392 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98393 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98394 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98395 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98396 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98397 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98398 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98399 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98400 + */
98401 +
98402 +/**
98403 +
98404 + @File part_integration_ext.h
98405 +
98406 + @Description T4240 external definitions and structures.
98407 +*//***************************************************************************/
98408 +#ifndef __PART_INTEGRATION_EXT_H
98409 +#define __PART_INTEGRATION_EXT_H
98410 +
98411 +#include "std_ext.h"
98412 +#include "ddr_std_ext.h"
98413 +#include "enet_ext.h"
98414 +#include "dpaa_integration_ext.h"
98415 +
98416 +
98417 +/**************************************************************************//**
98418 + @Group T4240_chip_id T4240 Application Programming Interface
98419 +
98420 + @Description T4240 Chip functions,definitions and enums.
98421 +
98422 + @{
98423 +*//***************************************************************************/
98424 +
98425 +#define CORE_E6500
98426 +
98427 +#define INTG_MAX_NUM_OF_CORES 24
98428 +
98429 +
98430 +/**************************************************************************//**
98431 + @Description Module types.
98432 +*//***************************************************************************/
98433 +typedef enum e_ModuleId
98434 +{
98435 + e_MODULE_ID_DUART_1 = 0,
98436 + e_MODULE_ID_DUART_2,
98437 + e_MODULE_ID_DUART_3,
98438 + e_MODULE_ID_DUART_4,
98439 + e_MODULE_ID_LAW,
98440 + e_MODULE_ID_IFC,
98441 + e_MODULE_ID_PAMU,
98442 + e_MODULE_ID_QM, /**< Queue manager module */
98443 + e_MODULE_ID_BM, /**< Buffer manager module */
98444 + e_MODULE_ID_QM_CE_PORTAL_0,
98445 + e_MODULE_ID_QM_CI_PORTAL_0,
98446 + e_MODULE_ID_QM_CE_PORTAL_1,
98447 + e_MODULE_ID_QM_CI_PORTAL_1,
98448 + e_MODULE_ID_QM_CE_PORTAL_2,
98449 + e_MODULE_ID_QM_CI_PORTAL_2,
98450 + e_MODULE_ID_QM_CE_PORTAL_3,
98451 + e_MODULE_ID_QM_CI_PORTAL_3,
98452 + e_MODULE_ID_QM_CE_PORTAL_4,
98453 + e_MODULE_ID_QM_CI_PORTAL_4,
98454 + e_MODULE_ID_QM_CE_PORTAL_5,
98455 + e_MODULE_ID_QM_CI_PORTAL_5,
98456 + e_MODULE_ID_QM_CE_PORTAL_6,
98457 + e_MODULE_ID_QM_CI_PORTAL_6,
98458 + e_MODULE_ID_QM_CE_PORTAL_7,
98459 + e_MODULE_ID_QM_CI_PORTAL_7,
98460 + e_MODULE_ID_QM_CE_PORTAL_8,
98461 + e_MODULE_ID_QM_CI_PORTAL_8,
98462 + e_MODULE_ID_QM_CE_PORTAL_9,
98463 + e_MODULE_ID_QM_CI_PORTAL_9,
98464 + e_MODULE_ID_BM_CE_PORTAL_0,
98465 + e_MODULE_ID_BM_CI_PORTAL_0,
98466 + e_MODULE_ID_BM_CE_PORTAL_1,
98467 + e_MODULE_ID_BM_CI_PORTAL_1,
98468 + e_MODULE_ID_BM_CE_PORTAL_2,
98469 + e_MODULE_ID_BM_CI_PORTAL_2,
98470 + e_MODULE_ID_BM_CE_PORTAL_3,
98471 + e_MODULE_ID_BM_CI_PORTAL_3,
98472 + e_MODULE_ID_BM_CE_PORTAL_4,
98473 + e_MODULE_ID_BM_CI_PORTAL_4,
98474 + e_MODULE_ID_BM_CE_PORTAL_5,
98475 + e_MODULE_ID_BM_CI_PORTAL_5,
98476 + e_MODULE_ID_BM_CE_PORTAL_6,
98477 + e_MODULE_ID_BM_CI_PORTAL_6,
98478 + e_MODULE_ID_BM_CE_PORTAL_7,
98479 + e_MODULE_ID_BM_CI_PORTAL_7,
98480 + e_MODULE_ID_BM_CE_PORTAL_8,
98481 + e_MODULE_ID_BM_CI_PORTAL_8,
98482 + e_MODULE_ID_BM_CE_PORTAL_9,
98483 + e_MODULE_ID_BM_CI_PORTAL_9,
98484 + e_MODULE_ID_FM, /**< Frame manager module */
98485 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98486 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98487 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98488 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98489 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98490 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98491 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98492 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98493 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98494 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98495 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98496 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98497 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98498 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98499 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98500 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98501 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98502 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98503 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98504 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98505 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98506 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98507 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98508 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98509 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98510 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98511 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98512 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98513 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98514 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98515 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98516 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98517 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98518 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98519 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98520 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98521 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98522 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98523 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98524 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98525 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98526 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98527 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98528 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98529 +
98530 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98531 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98532 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98533 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98534 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98535 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98536 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98537 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98538 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98539 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98540 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98541 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98542 +
98543 + e_MODULE_ID_PIC, /**< PIC */
98544 + e_MODULE_ID_GPIO, /**< GPIO */
98545 + e_MODULE_ID_SERDES, /**< SERDES */
98546 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98547 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98548 +
98549 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98550 +
98551 + e_MODULE_ID_DUMMY_LAST
98552 +} e_ModuleId;
98553 +
98554 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98555 +
98556 +#if 0 /* using unified values */
98557 +/*****************************************************************************
98558 + INTEGRATION-SPECIFIC MODULE CODES
98559 +******************************************************************************/
98560 +#define MODULE_UNKNOWN 0x00000000
98561 +#define MODULE_MEM 0x00010000
98562 +#define MODULE_MM 0x00020000
98563 +#define MODULE_CORE 0x00030000
98564 +#define MODULE_T4240 0x00040000
98565 +#define MODULE_T4240_PLATFORM 0x00050000
98566 +#define MODULE_PM 0x00060000
98567 +#define MODULE_MMU 0x00070000
98568 +#define MODULE_PIC 0x00080000
98569 +#define MODULE_CPC 0x00090000
98570 +#define MODULE_DUART 0x000a0000
98571 +#define MODULE_SERDES 0x000b0000
98572 +#define MODULE_PIO 0x000c0000
98573 +#define MODULE_QM 0x000d0000
98574 +#define MODULE_BM 0x000e0000
98575 +#define MODULE_SEC 0x000f0000
98576 +#define MODULE_LAW 0x00100000
98577 +#define MODULE_LBC 0x00110000
98578 +#define MODULE_PAMU 0x00120000
98579 +#define MODULE_FM 0x00130000
98580 +#define MODULE_FM_MURAM 0x00140000
98581 +#define MODULE_FM_PCD 0x00150000
98582 +#define MODULE_FM_RTC 0x00160000
98583 +#define MODULE_FM_MAC 0x00170000
98584 +#define MODULE_FM_PORT 0x00180000
98585 +#define MODULE_FM_SP 0x00190000
98586 +#define MODULE_DPA_PORT 0x001a0000
98587 +#define MODULE_MII 0x001b0000
98588 +#define MODULE_I2C 0x001c0000
98589 +#define MODULE_DMA 0x001d0000
98590 +#define MODULE_DDR 0x001e0000
98591 +#define MODULE_ESPI 0x001f0000
98592 +#define MODULE_DPAA_IPSEC 0x00200000
98593 +#endif /* using unified values */
98594 +
98595 +/*****************************************************************************
98596 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98597 +******************************************************************************/
98598 +#define PAMU_NUM_OF_PARTITIONS 4
98599 +
98600 +/*****************************************************************************
98601 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98602 +******************************************************************************/
98603 +#define LAW_NUM_OF_WINDOWS 32
98604 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98605 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98606 +
98607 +
98608 +/*****************************************************************************
98609 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98610 +******************************************************************************/
98611 +/**************************************************************************//**
98612 + @Group lbc_exception_grp LBC Exception Unit
98613 +
98614 + @Description LBC Exception unit API functions, definitions and enums
98615 +
98616 + @{
98617 +*//***************************************************************************/
98618 +
98619 +/**************************************************************************//**
98620 + @Anchor lbc_exbm
98621 +
98622 + @Collection LBC Errors Bit Mask
98623 +
98624 + These errors are reported through the exceptions callback..
98625 + The values can be or'ed in any combination in the errors mask
98626 + parameter of the errors report structure.
98627 +
98628 + These errors can also be passed as a bit-mask to
98629 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98630 + for enabling or disabling error checking.
98631 + @{
98632 +*//***************************************************************************/
98633 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98634 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98635 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98636 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98637 +
98638 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98639 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98640 + /**< All possible errors */
98641 +/* @} */
98642 +/** @} */ /* end of lbc_exception_grp group */
98643 +
98644 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98645 +
98646 +#define LBC_NUM_OF_BANKS 8
98647 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98648 +#define LBC_PARITY_SUPPORT
98649 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98650 +#define LBC_HIGH_CLK_DIVIDERS
98651 +#define LBC_FCM_AVAILABLE
98652 +
98653 +/*****************************************************************************
98654 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98655 +******************************************************************************/
98656 +#define GPIO_PORT_OFFSET_0x1000
98657 +
98658 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98659 + Each port contains up to 32 I/O pins. */
98660 +
98661 +#define GPIO_VALID_PIN_MASKS \
98662 + { /* Port A */ 0xFFFFFFFF, \
98663 + /* Port B */ 0xFFFFFFFF, \
98664 + /* Port C */ 0xFFFFFFFF }
98665 +
98666 +#define GPIO_VALID_INTR_MASKS \
98667 + { /* Port A */ 0xFFFFFFFF, \
98668 + /* Port B */ 0xFFFFFFFF, \
98669 + /* Port C */ 0xFFFFFFFF }
98670 +
98671 +
98672 +
98673 +#endif /* __PART_INTEGRATION_EXT_H */
98674 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98675 new file mode 100644
98676 index 00000000..5a8f3583
98677 --- /dev/null
98678 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98679 @@ -0,0 +1,291 @@
98680 +/*
98681 + * Copyright 2012 Freescale Semiconductor Inc.
98682 + *
98683 + * Redistribution and use in source and binary forms, with or without
98684 + * modification, are permitted provided that the following conditions are met:
98685 + * * Redistributions of source code must retain the above copyright
98686 + * notice, this list of conditions and the following disclaimer.
98687 + * * Redistributions in binary form must reproduce the above copyright
98688 + * notice, this list of conditions and the following disclaimer in the
98689 + * documentation and/or other materials provided with the distribution.
98690 + * * Neither the name of Freescale Semiconductor nor the
98691 + * names of its contributors may be used to endorse or promote products
98692 + * derived from this software without specific prior written permission.
98693 + *
98694 + *
98695 + * ALTERNATIVELY, this software may be distributed under the terms of the
98696 + * GNU General Public License ("GPL") as published by the Free Software
98697 + * Foundation, either version 2 of that License or (at your option) any
98698 + * later version.
98699 + *
98700 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98701 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98702 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98703 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98704 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98705 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98706 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98707 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98708 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98709 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98710 + */
98711 +
98712 +/**
98713 +
98714 + @File dpaa_integration_ext.h
98715 +
98716 + @Description T4240 FM external definitions and structures.
98717 +*//***************************************************************************/
98718 +#ifndef __DPAA_INTEGRATION_EXT_H
98719 +#define __DPAA_INTEGRATION_EXT_H
98720 +
98721 +#include "std_ext.h"
98722 +
98723 +
98724 +#define DPAA_VERSION 11
98725 +
98726 +/**************************************************************************//**
98727 + @Description DPAA SW Portals Enumeration.
98728 +*//***************************************************************************/
98729 +typedef enum
98730 +{
98731 + e_DPAA_SWPORTAL0 = 0,
98732 + e_DPAA_SWPORTAL1,
98733 + e_DPAA_SWPORTAL2,
98734 + e_DPAA_SWPORTAL3,
98735 + e_DPAA_SWPORTAL4,
98736 + e_DPAA_SWPORTAL5,
98737 + e_DPAA_SWPORTAL6,
98738 + e_DPAA_SWPORTAL7,
98739 + e_DPAA_SWPORTAL8,
98740 + e_DPAA_SWPORTAL9,
98741 + e_DPAA_SWPORTAL10,
98742 + e_DPAA_SWPORTAL11,
98743 + e_DPAA_SWPORTAL12,
98744 + e_DPAA_SWPORTAL13,
98745 + e_DPAA_SWPORTAL14,
98746 + e_DPAA_SWPORTAL15,
98747 + e_DPAA_SWPORTAL16,
98748 + e_DPAA_SWPORTAL17,
98749 + e_DPAA_SWPORTAL18,
98750 + e_DPAA_SWPORTAL19,
98751 + e_DPAA_SWPORTAL20,
98752 + e_DPAA_SWPORTAL21,
98753 + e_DPAA_SWPORTAL22,
98754 + e_DPAA_SWPORTAL23,
98755 + e_DPAA_SWPORTAL24,
98756 + e_DPAA_SWPORTAL_DUMMY_LAST
98757 +} e_DpaaSwPortal;
98758 +
98759 +/**************************************************************************//**
98760 + @Description DPAA Direct Connect Portals Enumeration.
98761 +*//***************************************************************************/
98762 +typedef enum
98763 +{
98764 + e_DPAA_DCPORTAL0 = 0,
98765 + e_DPAA_DCPORTAL1,
98766 + e_DPAA_DCPORTAL2,
98767 + e_DPAA_DCPORTAL_DUMMY_LAST
98768 +} e_DpaaDcPortal;
98769 +
98770 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98771 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98772 +
98773 +/*****************************************************************************
98774 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98775 +******************************************************************************/
98776 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98777 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98778 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98779 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98780 + /**< FQIDs range - 24 bits */
98781 +
98782 +/**************************************************************************//**
98783 + @Description Work Queue Channel assignments in QMan.
98784 +*//***************************************************************************/
98785 +typedef enum
98786 +{
98787 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98788 + e_QM_FQ_CHANNEL_SWPORTAL1,
98789 + e_QM_FQ_CHANNEL_SWPORTAL2,
98790 + e_QM_FQ_CHANNEL_SWPORTAL3,
98791 + e_QM_FQ_CHANNEL_SWPORTAL4,
98792 + e_QM_FQ_CHANNEL_SWPORTAL5,
98793 + e_QM_FQ_CHANNEL_SWPORTAL6,
98794 + e_QM_FQ_CHANNEL_SWPORTAL7,
98795 + e_QM_FQ_CHANNEL_SWPORTAL8,
98796 + e_QM_FQ_CHANNEL_SWPORTAL9,
98797 + e_QM_FQ_CHANNEL_SWPORTAL10,
98798 + e_QM_FQ_CHANNEL_SWPORTAL11,
98799 + e_QM_FQ_CHANNEL_SWPORTAL12,
98800 + e_QM_FQ_CHANNEL_SWPORTAL13,
98801 + e_QM_FQ_CHANNEL_SWPORTAL14,
98802 + e_QM_FQ_CHANNEL_SWPORTAL15,
98803 + e_QM_FQ_CHANNEL_SWPORTAL16,
98804 + e_QM_FQ_CHANNEL_SWPORTAL17,
98805 + e_QM_FQ_CHANNEL_SWPORTAL18,
98806 + e_QM_FQ_CHANNEL_SWPORTAL19,
98807 + e_QM_FQ_CHANNEL_SWPORTAL20,
98808 + e_QM_FQ_CHANNEL_SWPORTAL21,
98809 + e_QM_FQ_CHANNEL_SWPORTAL22,
98810 + e_QM_FQ_CHANNEL_SWPORTAL23,
98811 + e_QM_FQ_CHANNEL_SWPORTAL24,
98812 +
98813 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98814 + e_QM_FQ_CHANNEL_POOL2,
98815 + e_QM_FQ_CHANNEL_POOL3,
98816 + e_QM_FQ_CHANNEL_POOL4,
98817 + e_QM_FQ_CHANNEL_POOL5,
98818 + e_QM_FQ_CHANNEL_POOL6,
98819 + e_QM_FQ_CHANNEL_POOL7,
98820 + e_QM_FQ_CHANNEL_POOL8,
98821 + e_QM_FQ_CHANNEL_POOL9,
98822 + e_QM_FQ_CHANNEL_POOL10,
98823 + e_QM_FQ_CHANNEL_POOL11,
98824 + e_QM_FQ_CHANNEL_POOL12,
98825 + e_QM_FQ_CHANNEL_POOL13,
98826 + e_QM_FQ_CHANNEL_POOL14,
98827 + e_QM_FQ_CHANNEL_POOL15,
98828 +
98829 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98830 + connected to FMan 0; assigned in incrementing order to
98831 + each sub-portal (SP) in the portal */
98832 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98833 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98834 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98835 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98836 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98837 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98838 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98839 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98840 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98841 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98842 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98843 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98844 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98845 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98846 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98847 +
98848 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98849 + e_QM_FQ_CHANNEL_RMAN_SP1,
98850 +
98851 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98852 + connected to SEC */
98853 +} e_QmFQChannel;
98854 +
98855 +/*****************************************************************************
98856 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98857 +******************************************************************************/
98858 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98859 +
98860 +/*****************************************************************************
98861 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98862 +******************************************************************************/
98863 +#define SEC_NUM_OF_DECOS 3
98864 +#define SEC_ALL_DECOS_MASK 0x00000003
98865 +
98866 +
98867 +/*****************************************************************************
98868 + FM INTEGRATION-SPECIFIC DEFINITIONS
98869 +******************************************************************************/
98870 +#define INTG_MAX_NUM_OF_FM 2
98871 +
98872 +/* Ports defines */
98873 +#define FM_MAX_NUM_OF_1G_MACS 6
98874 +#define FM_MAX_NUM_OF_10G_MACS 2
98875 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98876 +#define FM_MAX_NUM_OF_OH_PORTS 6
98877 +
98878 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98879 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98880 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98881 +
98882 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98883 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98884 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98885 +
98886 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98887 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98888 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98889 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98890 +
98891 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98892 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98893 +
98894 +/* RAMs defines */
98895 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98896 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98897 +#define FM_NUM_OF_CTRL 4
98898 +
98899 +/* PCD defines */
98900 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98901 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98902 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98903 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98904 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98905 +
98906 +/* RTC defines */
98907 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98908 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98909 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98910 +
98911 +/* QMI defines */
98912 +#define QMI_MAX_NUM_OF_TNUMS 64
98913 +#define QMI_DEF_TNUMS_THRESH 32
98914 +/* FPM defines */
98915 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98916 +
98917 +/* DMA defines */
98918 +#define DMA_THRESH_MAX_COMMQ 83
98919 +#define DMA_THRESH_MAX_BUF 127
98920 +
98921 +/* BMI defines */
98922 +#define BMI_MAX_NUM_OF_TASKS 128
98923 +#define BMI_MAX_NUM_OF_DMAS 84
98924 +
98925 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98926 +#define PORT_MAX_WEIGHT 16
98927 +
98928 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98929 +
98930 +/* Unique T4240 */
98931 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98932 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98933 +#define FM_NO_OP_OBSERVED_POOLS
98934 +#define FM_FRAME_END_PARAMS_FOR_OP
98935 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98936 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98937 +
98938 +#define FM_NO_GUARANTEED_RESET_VALUES
98939 +
98940 +/* FM errata */
98941 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98942 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98943 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98944 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98945 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98946 +
98947 +#define FM_BCB_ERRATA_BMI_SW001
98948 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98949 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98950 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98951 +
98952 +/*****************************************************************************
98953 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98954 +******************************************************************************/
98955 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98956 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98957 +
98958 +/* RMan erratas */
98959 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98960 +
98961 +/*****************************************************************************
98962 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98963 +******************************************************************************/
98964 +#define NUM_OF_RX_SC 16
98965 +#define NUM_OF_TX_SC 16
98966 +
98967 +#define NUM_OF_SA_PER_RX_SC 2
98968 +#define NUM_OF_SA_PER_TX_SC 2
98969 +
98970 +#endif /* __DPAA_INTEGRATION_EXT_H */
98971 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98972 new file mode 100644
98973 index 00000000..4787e19c
98974 --- /dev/null
98975 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98976 @@ -0,0 +1,64 @@
98977 +/*
98978 + * Copyright 2012 Freescale Semiconductor Inc.
98979 + *
98980 + * Redistribution and use in source and binary forms, with or without
98981 + * modification, are permitted provided that the following conditions are met:
98982 + * * Redistributions of source code must retain the above copyright
98983 + * notice, this list of conditions and the following disclaimer.
98984 + * * Redistributions in binary form must reproduce the above copyright
98985 + * notice, this list of conditions and the following disclaimer in the
98986 + * documentation and/or other materials provided with the distribution.
98987 + * * Neither the name of Freescale Semiconductor nor the
98988 + * names of its contributors may be used to endorse or promote products
98989 + * derived from this software without specific prior written permission.
98990 + *
98991 + *
98992 + * ALTERNATIVELY, this software may be distributed under the terms of the
98993 + * GNU General Public License ("GPL") as published by the Free Software
98994 + * Foundation, either version 2 of that License or (at your option) any
98995 + * later version.
98996 + *
98997 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98998 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98999 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99000 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99001 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99002 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99003 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99004 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99005 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99006 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99007 + */
99008 +
99009 +/**************************************************************************//**
99010 +
99011 + @File part_ext.h
99012 +
99013 + @Description Definitions for the part (integration) module.
99014 +*//***************************************************************************/
99015 +
99016 +#ifndef __PART_EXT_H
99017 +#define __PART_EXT_H
99018 +
99019 +#include "std_ext.h"
99020 +#include "part_integration_ext.h"
99021 +
99022 +#if !(defined(LS1043))
99023 +#error "unable to proceed without chip-definition"
99024 +#endif
99025 +
99026 +
99027 +/**************************************************************************//*
99028 + @Description Part data structure - must be contained in any integration
99029 + data structure.
99030 +*//***************************************************************************/
99031 +typedef struct t_Part
99032 +{
99033 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99034 + /**< Returns the address of the module's memory map base. */
99035 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
99036 + /**< Returns the module's ID according to its memory map base. */
99037 +} t_Part;
99038 +
99039 +
99040 +#endif /* __PART_EXT_H */
99041 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
99042 new file mode 100644
99043 index 00000000..85ba2a47
99044 --- /dev/null
99045 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
99046 @@ -0,0 +1,185 @@
99047 +/*
99048 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99049 + *
99050 + * Redistribution and use in source and binary forms, with or without
99051 + * modification, are permitted provided that the following conditions are met:
99052 + * * Redistributions of source code must retain the above copyright
99053 + * notice, this list of conditions and the following disclaimer.
99054 + * * Redistributions in binary form must reproduce the above copyright
99055 + * notice, this list of conditions and the following disclaimer in the
99056 + * documentation and/or other materials provided with the distribution.
99057 + * * Neither the name of Freescale Semiconductor nor the
99058 + * names of its contributors may be used to endorse or promote products
99059 + * derived from this software without specific prior written permission.
99060 + *
99061 + *
99062 + * ALTERNATIVELY, this software may be distributed under the terms of the
99063 + * GNU General Public License ("GPL") as published by the Free Software
99064 + * Foundation, either version 2 of that License or (at your option) any
99065 + * later version.
99066 + *
99067 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99068 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99069 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99070 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99071 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99072 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99073 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99074 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99075 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99076 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99077 + */
99078 +
99079 +/**
99080 +
99081 + @File part_integration_ext.h
99082 +
99083 + @Description T4240 external definitions and structures.
99084 +*//***************************************************************************/
99085 +#ifndef __PART_INTEGRATION_EXT_H
99086 +#define __PART_INTEGRATION_EXT_H
99087 +
99088 +#include "std_ext.h"
99089 +#include "ddr_std_ext.h"
99090 +#include "enet_ext.h"
99091 +#include "dpaa_integration_ext.h"
99092 +
99093 +
99094 +/**************************************************************************//**
99095 + @Group T4240_chip_id T4240 Application Programming Interface
99096 +
99097 + @Description T4240 Chip functions,definitions and enums.
99098 +
99099 + @{
99100 +*//***************************************************************************/
99101 +
99102 +#define INTG_MAX_NUM_OF_CORES 4
99103 +
99104 +/**************************************************************************//**
99105 + @Description Module types.
99106 +*//***************************************************************************/
99107 +typedef enum e_ModuleId
99108 +{
99109 + e_MODULE_ID_DUART_1 = 0,
99110 + e_MODULE_ID_DUART_2,
99111 + e_MODULE_ID_DUART_3,
99112 + e_MODULE_ID_DUART_4,
99113 + e_MODULE_ID_LAW,
99114 + e_MODULE_ID_IFC,
99115 + e_MODULE_ID_PAMU,
99116 + e_MODULE_ID_QM, /**< Queue manager module */
99117 + e_MODULE_ID_BM, /**< Buffer manager module */
99118 + e_MODULE_ID_QM_CE_PORTAL_0,
99119 + e_MODULE_ID_QM_CI_PORTAL_0,
99120 + e_MODULE_ID_QM_CE_PORTAL_1,
99121 + e_MODULE_ID_QM_CI_PORTAL_1,
99122 + e_MODULE_ID_QM_CE_PORTAL_2,
99123 + e_MODULE_ID_QM_CI_PORTAL_2,
99124 + e_MODULE_ID_QM_CE_PORTAL_3,
99125 + e_MODULE_ID_QM_CI_PORTAL_3,
99126 + e_MODULE_ID_QM_CE_PORTAL_4,
99127 + e_MODULE_ID_QM_CI_PORTAL_4,
99128 + e_MODULE_ID_QM_CE_PORTAL_5,
99129 + e_MODULE_ID_QM_CI_PORTAL_5,
99130 + e_MODULE_ID_QM_CE_PORTAL_6,
99131 + e_MODULE_ID_QM_CI_PORTAL_6,
99132 + e_MODULE_ID_QM_CE_PORTAL_7,
99133 + e_MODULE_ID_QM_CI_PORTAL_7,
99134 + e_MODULE_ID_QM_CE_PORTAL_8,
99135 + e_MODULE_ID_QM_CI_PORTAL_8,
99136 + e_MODULE_ID_QM_CE_PORTAL_9,
99137 + e_MODULE_ID_QM_CI_PORTAL_9,
99138 + e_MODULE_ID_BM_CE_PORTAL_0,
99139 + e_MODULE_ID_BM_CI_PORTAL_0,
99140 + e_MODULE_ID_BM_CE_PORTAL_1,
99141 + e_MODULE_ID_BM_CI_PORTAL_1,
99142 + e_MODULE_ID_BM_CE_PORTAL_2,
99143 + e_MODULE_ID_BM_CI_PORTAL_2,
99144 + e_MODULE_ID_BM_CE_PORTAL_3,
99145 + e_MODULE_ID_BM_CI_PORTAL_3,
99146 + e_MODULE_ID_BM_CE_PORTAL_4,
99147 + e_MODULE_ID_BM_CI_PORTAL_4,
99148 + e_MODULE_ID_BM_CE_PORTAL_5,
99149 + e_MODULE_ID_BM_CI_PORTAL_5,
99150 + e_MODULE_ID_BM_CE_PORTAL_6,
99151 + e_MODULE_ID_BM_CI_PORTAL_6,
99152 + e_MODULE_ID_BM_CE_PORTAL_7,
99153 + e_MODULE_ID_BM_CI_PORTAL_7,
99154 + e_MODULE_ID_BM_CE_PORTAL_8,
99155 + e_MODULE_ID_BM_CI_PORTAL_8,
99156 + e_MODULE_ID_BM_CE_PORTAL_9,
99157 + e_MODULE_ID_BM_CI_PORTAL_9,
99158 + e_MODULE_ID_FM, /**< Frame manager module */
99159 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99160 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99161 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99162 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99163 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99164 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99165 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99166 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99167 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99168 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99169 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99170 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99171 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99172 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99173 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99174 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99175 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99176 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99177 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99178 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99179 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99180 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99181 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99182 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99183 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99184 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99185 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99186 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99187 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99188 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99189 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99190 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99191 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99192 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99193 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99194 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99195 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99196 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99197 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99198 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99199 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99200 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99201 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99202 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99203 +
99204 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99205 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99206 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99207 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99208 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99209 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99210 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99211 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99212 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99213 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99214 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99215 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99216 +
99217 + e_MODULE_ID_PIC, /**< PIC */
99218 + e_MODULE_ID_GPIO, /**< GPIO */
99219 + e_MODULE_ID_SERDES, /**< SERDES */
99220 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99221 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99222 +
99223 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99224 +
99225 + e_MODULE_ID_DUMMY_LAST
99226 +} e_ModuleId;
99227 +
99228 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99229 +
99230 +
99231 +#endif /* __PART_INTEGRATION_EXT_H */
99232 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
99233 new file mode 100644
99234 index 00000000..7b5390de
99235 --- /dev/null
99236 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
99237 @@ -0,0 +1,213 @@
99238 +/*
99239 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99240 + *
99241 + * Redistribution and use in source and binary forms, with or without
99242 + * modification, are permitted provided that the following conditions are met:
99243 + * * Redistributions of source code must retain the above copyright
99244 + * notice, this list of conditions and the following disclaimer.
99245 + * * Redistributions in binary form must reproduce the above copyright
99246 + * notice, this list of conditions and the following disclaimer in the
99247 + * documentation and/or other materials provided with the distribution.
99248 + * * Neither the name of Freescale Semiconductor nor the
99249 + * names of its contributors may be used to endorse or promote products
99250 + * derived from this software without specific prior written permission.
99251 + *
99252 + *
99253 + * ALTERNATIVELY, this software may be distributed under the terms of the
99254 + * GNU General Public License ("GPL") as published by the Free Software
99255 + * Foundation, either version 2 of that License or (at your option) any
99256 + * later version.
99257 + *
99258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99268 + */
99269 +
99270 +
99271 +/**
99272 +
99273 + @File dpaa_integration_ext.h
99274 +
99275 + @Description P1023 FM external definitions and structures.
99276 +*//***************************************************************************/
99277 +#ifndef __DPAA_INTEGRATION_EXT_H
99278 +#define __DPAA_INTEGRATION_EXT_H
99279 +
99280 +#include "std_ext.h"
99281 +
99282 +
99283 +#define DPAA_VERSION 10
99284 +
99285 +typedef enum e_DpaaSwPortal {
99286 + e_DPAA_SWPORTAL0 = 0,
99287 + e_DPAA_SWPORTAL1,
99288 + e_DPAA_SWPORTAL2,
99289 + e_DPAA_SWPORTAL_DUMMY_LAST
99290 +} e_DpaaSwPortal;
99291 +
99292 +typedef enum {
99293 + e_DPAA_DCPORTAL0 = 0,
99294 + e_DPAA_DCPORTAL2,
99295 + e_DPAA_DCPORTAL_DUMMY_LAST
99296 +} e_DpaaDcPortal;
99297 +
99298 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99299 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99300 +
99301 +/*****************************************************************************
99302 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
99303 +******************************************************************************/
99304 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
99305 +#define QM_MAX_NUM_OF_WQ 8
99306 +#define QM_MAX_NUM_OF_SWP_AS 2
99307 +#define QM_MAX_NUM_OF_CGS 64
99308 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
99309 +
99310 +typedef enum {
99311 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
99312 + e_QM_FQ_CHANNEL_SWPORTAL1,
99313 + e_QM_FQ_CHANNEL_SWPORTAL2,
99314 +
99315 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
99316 + e_QM_FQ_CHANNEL_POOL2,
99317 + e_QM_FQ_CHANNEL_POOL3,
99318 +
99319 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
99320 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99321 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99322 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99323 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99324 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99325 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99326 +
99327 +
99328 + e_QM_FQ_CHANNEL_CAAM = 0x80
99329 +} e_QmFQChannel;
99330 +
99331 +/*****************************************************************************
99332 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
99333 +******************************************************************************/
99334 +#define BM_MAX_NUM_OF_POOLS 8
99335 +
99336 +/*****************************************************************************
99337 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99338 +******************************************************************************/
99339 +#define SEC_NUM_OF_DECOS 2
99340 +#define SEC_ALL_DECOS_MASK 0x00000003
99341 +#define SEC_RNGB
99342 +#define SEC_NO_ESP_TRAILER_REMOVAL
99343 +
99344 +/*****************************************************************************
99345 + FM INTEGRATION-SPECIFIC DEFINITIONS
99346 +******************************************************************************/
99347 +#define INTG_MAX_NUM_OF_FM 1
99348 +
99349 +/* Ports defines */
99350 +#define FM_MAX_NUM_OF_1G_MACS 2
99351 +#define FM_MAX_NUM_OF_10G_MACS 0
99352 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99353 +#define FM_MAX_NUM_OF_OH_PORTS 5
99354 +
99355 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99356 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99357 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99358 +
99359 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99360 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99361 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99362 +
99363 +#define FM_MAX_NUM_OF_MACSECS 1
99364 +
99365 +#define FM_MACSEC_SUPPORT
99366 +
99367 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
99368 +
99369 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99370 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
99371 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
99372 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
99373 +
99374 +/* Rams defines */
99375 +#define FM_MURAM_SIZE (64*KILOBYTE)
99376 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
99377 +#define FM_NUM_OF_CTRL 2
99378 +
99379 +/* PCD defines */
99380 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
99381 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
99382 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
99383 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
99384 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99385 +
99386 +/* RTC defines */
99387 +#define FM_RTC_NUM_OF_ALARMS 2
99388 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
99389 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
99390 +
99391 +/* QMI defines */
99392 +#define QMI_MAX_NUM_OF_TNUMS 15
99393 +
99394 +/* FPM defines */
99395 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99396 +
99397 +/* DMA defines */
99398 +#define DMA_THRESH_MAX_COMMQ 15
99399 +#define DMA_THRESH_MAX_BUF 7
99400 +
99401 +/* BMI defines */
99402 +#define BMI_MAX_NUM_OF_TASKS 64
99403 +#define BMI_MAX_NUM_OF_DMAS 16
99404 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99405 +#define PORT_MAX_WEIGHT 4
99406 +
99407 +/*****************************************************************************
99408 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99409 +******************************************************************************/
99410 +#define NUM_OF_RX_SC 16
99411 +#define NUM_OF_TX_SC 16
99412 +
99413 +#define NUM_OF_SA_PER_RX_SC 2
99414 +#define NUM_OF_SA_PER_TX_SC 2
99415 +
99416 +/**************************************************************************//**
99417 + @Description Enum for inter-module interrupts registration
99418 +*//***************************************************************************/
99419 +
99420 +/* 1023 unique features */
99421 +#define FM_QMI_NO_ECC_EXCEPTIONS
99422 +#define FM_CSI_CFED_LIMIT
99423 +#define FM_PEDANTIC_DMA
99424 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
99425 +#define FM_FIFO_ALLOCATION_ALG
99426 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99427 +#define FM_HAS_TOTAL_DMAS
99428 +#define FM_KG_NO_IPPID_SUPPORT
99429 +#define FM_NO_GUARANTEED_RESET_VALUES
99430 +#define FM_MAC_RESET
99431 +
99432 +/* FM erratas */
99433 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99434 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99435 +
99436 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99437 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
99438 +
99439 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99440 +
99441 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
99442 +
99443 +/*
99444 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
99445 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
99446 +*/
99447 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
99448 +
99449 +
99450 +#endif /* __DPAA_INTEGRATION_EXT_H */
99451 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99452 new file mode 100644
99453 index 00000000..6814d5fb
99454 --- /dev/null
99455 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99456 @@ -0,0 +1,82 @@
99457 +/*
99458 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99459 + *
99460 + * Redistribution and use in source and binary forms, with or without
99461 + * modification, are permitted provided that the following conditions are met:
99462 + * * Redistributions of source code must retain the above copyright
99463 + * notice, this list of conditions and the following disclaimer.
99464 + * * Redistributions in binary form must reproduce the above copyright
99465 + * notice, this list of conditions and the following disclaimer in the
99466 + * documentation and/or other materials provided with the distribution.
99467 + * * Neither the name of Freescale Semiconductor nor the
99468 + * names of its contributors may be used to endorse or promote products
99469 + * derived from this software without specific prior written permission.
99470 + *
99471 + *
99472 + * ALTERNATIVELY, this software may be distributed under the terms of the
99473 + * GNU General Public License ("GPL") as published by the Free Software
99474 + * Foundation, either version 2 of that License or (at your option) any
99475 + * later version.
99476 + *
99477 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99478 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99479 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99480 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99481 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99482 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99483 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99484 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99485 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99486 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99487 + */
99488 +
99489 +
99490 +/**************************************************************************//**
99491 +
99492 + @File part_ext.h
99493 +
99494 + @Description Definitions for the part (integration) module.
99495 +*//***************************************************************************/
99496 +
99497 +#ifndef __PART_EXT_H
99498 +#define __PART_EXT_H
99499 +
99500 +#include "std_ext.h"
99501 +#include "part_integration_ext.h"
99502 +
99503 +
99504 +#if !(defined(MPC8306) || \
99505 + defined(MPC8309) || \
99506 + defined(MPC834x) || \
99507 + defined(MPC836x) || \
99508 + defined(MPC832x) || \
99509 + defined(MPC837x) || \
99510 + defined(MPC8568) || \
99511 + defined(MPC8569) || \
99512 + defined(P1020) || \
99513 + defined(P1021) || \
99514 + defined(P1022) || \
99515 + defined(P1023) || \
99516 + defined(P2020) || \
99517 + defined(P3041) || \
99518 + defined(P4080) || \
99519 + defined(P5020) || \
99520 + defined(MSC814x))
99521 +#error "unable to proceed without chip-definition"
99522 +#endif
99523 +
99524 +
99525 +/**************************************************************************//*
99526 + @Description Part data structure - must be contained in any integration
99527 + data structure.
99528 +*//***************************************************************************/
99529 +typedef struct t_Part
99530 +{
99531 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99532 + /**< Returns the address of the module's memory map base. */
99533 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99534 + /**< Returns the module's ID according to its memory map base. */
99535 +} t_Part;
99536 +
99537 +
99538 +#endif /* __PART_EXT_H */
99539 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99540 new file mode 100644
99541 index 00000000..e838283d
99542 --- /dev/null
99543 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99544 @@ -0,0 +1,635 @@
99545 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99546 + * All rights reserved.
99547 + *
99548 + * Redistribution and use in source and binary forms, with or without
99549 + * modification, are permitted provided that the following conditions are met:
99550 + * * Redistributions of source code must retain the above copyright
99551 + * notice, this list of conditions and the following disclaimer.
99552 + * * Redistributions in binary form must reproduce the above copyright
99553 + * notice, this list of conditions and the following disclaimer in the
99554 + * documentation and/or other materials provided with the distribution.
99555 + * * Neither the name of Freescale Semiconductor nor the
99556 + * names of its contributors may be used to endorse or promote products
99557 + * derived from this software without specific prior written permission.
99558 + *
99559 + *
99560 + * ALTERNATIVELY, this software may be distributed under the terms of the
99561 + * GNU General Public License ("GPL") as published by the Free Software
99562 + * Foundation, either version 2 of that License or (at your option) any
99563 + * later version.
99564 + *
99565 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99566 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99567 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99568 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99569 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99570 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99571 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99572 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99573 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99574 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99575 + */
99576 +
99577 +/**************************************************************************//**
99578 + @File part_integration_ext.h
99579 +
99580 + @Description P1023 external definitions and structures.
99581 +*//***************************************************************************/
99582 +#ifndef __PART_INTEGRATION_EXT_H
99583 +#define __PART_INTEGRATION_EXT_H
99584 +
99585 +#include "std_ext.h"
99586 +#include "dpaa_integration_ext.h"
99587 +
99588 +
99589 +/**************************************************************************//**
99590 + @Group 1023_chip_id P1023 Application Programming Interface
99591 +
99592 + @Description P1023 Chip functions,definitions and enums.
99593 +
99594 + @{
99595 +*//***************************************************************************/
99596 +
99597 +#define INTG_MAX_NUM_OF_CORES 2
99598 +
99599 +
99600 +/**************************************************************************//**
99601 + @Description Module types.
99602 +*//***************************************************************************/
99603 +typedef enum e_ModuleId
99604 +{
99605 + e_MODULE_ID_LAW, /**< Local Access module */
99606 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99607 + e_MODULE_ID_DDR, /**< DDR memory controller */
99608 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99609 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99610 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99611 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99612 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99613 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99614 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99615 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99616 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99617 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99618 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99619 + e_MODULE_ID_MSI, /**< MSI registers */
99620 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99621 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99622 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99623 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99624 + e_MODULE_ID_ESPI, /**< ESPI module */
99625 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99626 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99627 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99628 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99629 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99630 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99631 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99632 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99633 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99634 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99635 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99636 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99637 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99638 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99639 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99640 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99641 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99642 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99643 + e_MODULE_ID_GUTS, /**< Serial DMA */
99644 + e_MODULE_ID_PM, /**< Performance Monitor module */
99645 + e_MODULE_ID_QM, /**< Queue manager module */
99646 + e_MODULE_ID_BM, /**< Buffer manager module */
99647 + e_MODULE_ID_QM_CE_PORTAL,
99648 + e_MODULE_ID_QM_CI_PORTAL,
99649 + e_MODULE_ID_BM_CE_PORTAL,
99650 + e_MODULE_ID_BM_CI_PORTAL,
99651 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99652 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99653 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99654 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99655 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99656 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99657 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99658 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99659 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99660 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99661 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99662 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99663 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99664 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99665 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99666 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99667 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99668 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99669 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99670 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99671 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99672 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99673 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99674 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99675 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99676 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99677 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99678 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99679 +
99680 + e_MODULE_ID_DUMMY_LAST
99681 +} e_ModuleId;
99682 +
99683 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99684 +
99685 +
99686 +#define P1023_OFFSET_LAW 0x00000C08
99687 +#define P1023_OFFSET_ECM 0x00001000
99688 +#define P1023_OFFSET_DDR 0x00002000
99689 +#define P1023_OFFSET_I2C1 0x00003000
99690 +#define P1023_OFFSET_I2C2 0x00003100
99691 +#define P1023_OFFSET_DUART1 0x00004500
99692 +#define P1023_OFFSET_DUART2 0x00004600
99693 +#define P1023_OFFSET_LBC 0x00005000
99694 +#define P1023_OFFSET_ESPI 0x00007000
99695 +#define P1023_OFFSET_PCIE2 0x00009000
99696 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99697 +#define P1023_OFFSET_PCIE1 0x0000A000
99698 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99699 +#define P1023_OFFSET_PCIE3 0x0000B000
99700 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99701 +#define P1023_OFFSET_DMA2 0x0000C100
99702 +#define P1023_OFFSET_GPIO 0x0000F000
99703 +#define P1023_OFFSET_L2_SRAM 0x00020000
99704 +#define P1023_OFFSET_DMA1 0x00021100
99705 +#define P1023_OFFSET_USB1 0x00022000
99706 +#define P1023_OFFSET_SEC_GEN 0x00030000
99707 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99708 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99709 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99710 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99711 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99712 +#define P1023_OFFSET_SEC_QI 0x00037000
99713 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99714 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99715 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99716 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99717 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99718 +#define P1023_OFFSET_PIC 0x00040000
99719 +#define P1023_OFFSET_MSI 0x00041600
99720 +#define P1023_OFFSET_AXI 0x00081000
99721 +#define P1023_OFFSET_QM 0x00088000
99722 +#define P1023_OFFSET_BM 0x0008A000
99723 +#define P1022_OFFSET_PM 0x000E1000
99724 +
99725 +#define P1023_OFFSET_GUTIL 0x000E0000
99726 +#define P1023_OFFSET_PM 0x000E1000
99727 +#define P1023_OFFSET_DEBUG 0x000E2000
99728 +#define P1023_OFFSET_SERDES 0x000E3000
99729 +#define P1023_OFFSET_ROM 0x000F0000
99730 +#define P1023_OFFSET_FM 0x00100000
99731 +
99732 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99733 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99734 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99735 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99736 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99737 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99738 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99739 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99740 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99741 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99742 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99743 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99744 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99745 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99746 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99747 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99748 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99749 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99750 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99751 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99752 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99753 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99754 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99755 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99756 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99757 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99758 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99759 +
99760 +/* Offsets relative to QM or BM portals base */
99761 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99762 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99763 +
99764 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99765 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99766 +
99767 +/**************************************************************************//**
99768 + @Description Transaction source ID (for memory controllers error reporting).
99769 +*//***************************************************************************/
99770 +typedef enum e_TransSrc
99771 +{
99772 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99773 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99774 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99775 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99776 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99777 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99778 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99779 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99780 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99781 +} e_TransSrc;
99782 +
99783 +/**************************************************************************//**
99784 + @Description Local Access Window Target interface ID
99785 +*//***************************************************************************/
99786 +typedef enum e_P1023LawTargetId
99787 +{
99788 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99789 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99790 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99791 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99792 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99793 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99794 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99795 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99796 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99797 +} e_P1023LawTargetId;
99798 +
99799 +
99800 +/**************************************************************************//**
99801 + @Group 1023_init_grp P1023 Initialization Unit
99802 +
99803 + @Description P1023 initialization unit API functions, definitions and enums
99804 +
99805 + @{
99806 +*//***************************************************************************/
99807 +
99808 +/**************************************************************************//**
99809 + @Description Part ID and revision number
99810 +*//***************************************************************************/
99811 +typedef enum e_P1023DeviceName
99812 +{
99813 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99814 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99815 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99816 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99817 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99818 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99819 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99820 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99821 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99822 +} e_P1023DeviceName;
99823 +
99824 +/**************************************************************************//**
99825 + @Description structure representing P1023 initialization parameters
99826 +*//***************************************************************************/
99827 +typedef struct t_P1023Params
99828 +{
99829 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99830 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99831 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99832 +} t_P1023Params;
99833 +
99834 +/**************************************************************************//**
99835 + @Function P1023_ConfigAndInit
99836 +
99837 + @Description General initiation of the chip registers.
99838 +
99839 + @Param[in] p_P1023Params - A pointer to data structure of parameters
99840 +
99841 + @Return A handle to the P1023 data structure.
99842 +*//***************************************************************************/
99843 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
99844 +
99845 +/**************************************************************************//**
99846 + @Function P1023_Free
99847 +
99848 + @Description Free all resources.
99849 +
99850 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
99851 +
99852 + @Return E_OK on success; Other value otherwise.
99853 +*//***************************************************************************/
99854 +t_Error P1023_Free(t_Handle h_P1023);
99855 +
99856 +/**************************************************************************//**
99857 + @Function P1023_GetRevInfo
99858 +
99859 + @Description This routine enables access to chip and revision information.
99860 +
99861 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99862 +
99863 + @Return Part ID and revision.
99864 +*//***************************************************************************/
99865 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
99866 +
99867 +/**************************************************************************//**
99868 + @Function P1023_GetE500Factor
99869 +
99870 + @Description Returns E500 core clock multiplication factor.
99871 +
99872 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99873 + @Param[in] coreId - Id of the requested core.
99874 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
99875 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
99876 +
99877 + @Return E_OK on success; Other value otherwise.
99878 +*
99879 +*//***************************************************************************/
99880 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
99881 + uint32_t coreId,
99882 + uint32_t *p_E500MulFactor,
99883 + uint32_t *p_E500DivFactor);
99884 +
99885 +/**************************************************************************//**
99886 + @Function P1023_GetFmFactor
99887 +
99888 + @Description returns FM multiplication factors. (This value is returned using
99889 + two parameters to avoid using float parameter).
99890 +
99891 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99892 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
99893 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
99894 +
99895 + @Return E_OK on success; Other value otherwise.
99896 +*//***************************************************************************/
99897 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
99898 +
99899 +/**************************************************************************//**
99900 + @Function P1023_GetCcbFactor
99901 +
99902 + @Description returns system multiplication factor.
99903 +
99904 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99905 +
99906 + @Return System multiplication factor.
99907 +*//***************************************************************************/
99908 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
99909 +
99910 +#if 0
99911 +/**************************************************************************//**
99912 + @Function P1023_GetDdrFactor
99913 +
99914 + @Description returns the multiplication factor of the clock in for the DDR clock .
99915 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
99916 +
99917 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99918 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
99919 + @Param p_DdrDivFactor - returns DDR division factor.
99920 +
99921 + @Return E_OK on success; Other value otherwise..
99922 +*//***************************************************************************/
99923 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
99924 + uint32_t *p_DdrMulFactor,
99925 + uint32_t *p_DdrDivFactor);
99926 +
99927 +/**************************************************************************//**
99928 + @Function P1023_GetDdrType
99929 +
99930 + @Description returns the multiplication factor of the clock in for the DDR clock .
99931 +
99932 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99933 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
99934 +
99935 + @Return E_OK on success; Other value otherwise.
99936 +*//***************************************************************************/
99937 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
99938 +#endif
99939 +
99940 +/** @} */ /* end of 1023_init_grp group */
99941 +/** @} */ /* end of 1023_grp group */
99942 +
99943 +#define CORE_E500V2
99944 +
99945 +#if 0 /* using unified values */
99946 +/*****************************************************************************
99947 + INTEGRATION-SPECIFIC MODULE CODES
99948 +******************************************************************************/
99949 +#define MODULE_UNKNOWN 0x00000000
99950 +#define MODULE_MEM 0x00010000
99951 +#define MODULE_MM 0x00020000
99952 +#define MODULE_CORE 0x00030000
99953 +#define MODULE_P1023 0x00040000
99954 +#define MODULE_MII 0x00050000
99955 +#define MODULE_PM 0x00060000
99956 +#define MODULE_MMU 0x00070000
99957 +#define MODULE_PIC 0x00080000
99958 +#define MODULE_L2_CACHE 0x00090000
99959 +#define MODULE_DUART 0x000a0000
99960 +#define MODULE_SERDES 0x000b0000
99961 +#define MODULE_PIO 0x000c0000
99962 +#define MODULE_QM 0x000d0000
99963 +#define MODULE_BM 0x000e0000
99964 +#define MODULE_SEC 0x000f0000
99965 +#define MODULE_FM 0x00100000
99966 +#define MODULE_FM_MURAM 0x00110000
99967 +#define MODULE_FM_PCD 0x00120000
99968 +#define MODULE_FM_RTC 0x00130000
99969 +#define MODULE_FM_MAC 0x00140000
99970 +#define MODULE_FM_PORT 0x00150000
99971 +#define MODULE_FM_MACSEC 0x00160000
99972 +#define MODULE_FM_MACSEC_SECY 0x00170000
99973 +#define MODULE_FM_SP 0x00280000
99974 +#define MODULE_ECM 0x00190000
99975 +#define MODULE_DMA 0x001a0000
99976 +#define MODULE_DDR 0x001b0000
99977 +#define MODULE_LAW 0x001c0000
99978 +#define MODULE_LBC 0x001d0000
99979 +#define MODULE_I2C 0x001e0000
99980 +#define MODULE_ESPI 0x001f0000
99981 +#define MODULE_PCI 0x00200000
99982 +#define MODULE_DPA_PORT 0x00210000
99983 +#define MODULE_USB 0x00220000
99984 +#endif /* using unified values */
99985 +
99986 +/*****************************************************************************
99987 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99988 +******************************************************************************/
99989 +/**************************************************************************//**
99990 + @Group lbc_exception_grp LBC Exception Unit
99991 +
99992 + @Description LBC Exception unit API functions, definitions and enums
99993 +
99994 + @{
99995 +*//***************************************************************************/
99996 +
99997 +/**************************************************************************//**
99998 + @Anchor lbc_exbm
99999 +
100000 + @Collection LBC Errors Bit Mask
100001 +
100002 + These errors are reported through the exceptions callback..
100003 + The values can be or'ed in any combination in the errors mask
100004 + parameter of the errors report structure.
100005 +
100006 + These errors can also be passed as a bit-mask to
100007 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100008 + for enabling or disabling error checking.
100009 + @{
100010 +*//***************************************************************************/
100011 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100012 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100013 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100014 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100015 +
100016 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100017 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
100018 + /**< All possible errors */
100019 +/* @} */
100020 +/** @} */ /* end of lbc_exception_grp group */
100021 +
100022 +#define LBC_NUM_OF_BANKS 2
100023 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100024 +#define LBC_ATOMIC_OPERATION_SUPPORT
100025 +#define LBC_PARITY_SUPPORT
100026 +#define LBC_ADDRESS_SHIFT_SUPPORT
100027 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100028 +#define LBC_HIGH_CLK_DIVIDERS
100029 +#define LBC_FCM_AVAILABLE
100030 +
100031 +
100032 +/*****************************************************************************
100033 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100034 +******************************************************************************/
100035 +#define LAW_ARCH_CCB
100036 +#define LAW_NUM_OF_WINDOWS 12
100037 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100038 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
100039 +
100040 +
100041 +/*****************************************************************************
100042 + SPI INTEGRATION-SPECIFIC DEFINITIONS
100043 +******************************************************************************/
100044 +#define SPI_NUM_OF_CONTROLLERS 1
100045 +
100046 +/*****************************************************************************
100047 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
100048 +******************************************************************************/
100049 +
100050 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
100051 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
100052 +
100053 +/**************************************************************************//**
100054 + @Description Target interface of an inbound window
100055 +*//***************************************************************************/
100056 +typedef enum e_PciTargetInterface
100057 +{
100058 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
100059 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
100060 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
100061 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
100062 +
100063 +} e_PciTargetInterface;
100064 +
100065 +/*****************************************************************************
100066 + DDR INTEGRATION-SPECIFIC DEFINITIONS
100067 +******************************************************************************/
100068 +#define DDR_NUM_OF_VALID_CS 2
100069 +
100070 +/*****************************************************************************
100071 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100072 +******************************************************************************/
100073 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
100074 +
100075 +/*****************************************************************************
100076 + DMA INTEGRATION-SPECIFIC DEFINITIONS
100077 +******************************************************************************/
100078 +#define DMA_NUM_OF_CONTROLLERS 2
100079 +
100080 +
100081 +
100082 +
100083 +/*****************************************************************************
100084 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
100085 +******************************************************************************/
100086 +#define PTP_V2
100087 +
100088 +/**************************************************************************//**
100089 + @Function P1023_GetMuxControlReg
100090 +
100091 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
100092 + Control Register)
100093 +
100094 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100095 +
100096 + @Return Value of PMUXCR
100097 +*//***************************************************************************/
100098 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
100099 +
100100 +/**************************************************************************//**
100101 + @Function P1023_SetMuxControlReg
100102 +
100103 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
100104 + Control Register)
100105 +
100106 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100107 + @Param[in] val - the new value for PMUXCR.
100108 +
100109 + @Return None
100110 +*//***************************************************************************/
100111 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
100112 +
100113 +/**************************************************************************//**
100114 + @Function P1023_GetDeviceDisableStatusRegister
100115 +
100116 + @Description Returns the value of DEVDISR (Device Disable Register)
100117 +
100118 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100119 +
100120 + @Return Value of DEVDISR
100121 +*//***************************************************************************/
100122 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
100123 +
100124 +/**************************************************************************//**
100125 + @Function P1023_GetPorDeviceStatusRegister
100126 +
100127 + @Description Returns the value of POR Device Status Register
100128 +
100129 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100130 +
100131 + @Return POR Device Status Register
100132 +*//***************************************************************************/
100133 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
100134 +
100135 +/**************************************************************************//**
100136 + @Function P1023_GetPorBootModeStatusRegister
100137 +
100138 + @Description Returns the value of POR Boot Mode Status Register
100139 +
100140 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100141 +
100142 + @Return POR Boot Mode Status Register value
100143 +*//***************************************************************************/
100144 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
100145 +
100146 +
100147 +#define PORDEVSR_SGMII1_DIS 0x10000000
100148 +#define PORDEVSR_SGMII2_DIS 0x08000000
100149 +#define PORDEVSR_ECP1 0x02000000
100150 +#define PORDEVSR_IO_SEL 0x00780000
100151 +#define PORDEVSR_IO_SEL_SHIFT 19
100152 +#define PORBMSR_HA 0x00070000
100153 +#define PORBMSR_HA_SHIFT 16
100154 +
100155 +#define DEVDISR_QM_BM 0x80000000
100156 +#define DEVDISR_FM 0x40000000
100157 +#define DEVDISR_PCIE1 0x20000000
100158 +#define DEVDISR_MAC_SEC 0x10000000
100159 +#define DEVDISR_ELBC 0x08000000
100160 +#define DEVDISR_PCIE2 0x04000000
100161 +#define DEVDISR_PCIE3 0x02000000
100162 +#define DEVDISR_CAAM 0x01000000
100163 +#define DEVDISR_USB0 0x00800000
100164 +#define DEVDISR_1588 0x00020000
100165 +#define DEVDISR_CORE0 0x00008000
100166 +#define DEVDISR_TB0 0x00004000
100167 +#define DEVDISR_CORE1 0x00002000
100168 +#define DEVDISR_TB1 0x00001000
100169 +#define DEVDISR_DMA1 0x00000400
100170 +#define DEVDISR_DMA2 0x00000200
100171 +#define DEVDISR_DDR 0x00000010
100172 +#define DEVDISR_TSEC1 0x00000080
100173 +#define DEVDISR_TSEC2 0x00000040
100174 +#define DEVDISR_SPI 0x00000008
100175 +#define DEVDISR_I2C 0x00000004
100176 +#define DEVDISR_DUART 0x00000002
100177 +
100178 +
100179 +#endif /* __PART_INTEGRATION_EXT_H */
100180 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
100181 new file mode 100644
100182 index 00000000..6e2b925f
100183 --- /dev/null
100184 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
100185 @@ -0,0 +1,276 @@
100186 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
100187 + * All rights reserved.
100188 + *
100189 + * Redistribution and use in source and binary forms, with or without
100190 + * modification, are permitted provided that the following conditions are met:
100191 + * * Redistributions of source code must retain the above copyright
100192 + * notice, this list of conditions and the following disclaimer.
100193 + * * Redistributions in binary form must reproduce the above copyright
100194 + * notice, this list of conditions and the following disclaimer in the
100195 + * documentation and/or other materials provided with the distribution.
100196 + * * Neither the name of Freescale Semiconductor nor the
100197 + * names of its contributors may be used to endorse or promote products
100198 + * derived from this software without specific prior written permission.
100199 + *
100200 + *
100201 + * ALTERNATIVELY, this software may be distributed under the terms of the
100202 + * GNU General Public License ("GPL") as published by the Free Software
100203 + * Foundation, either version 2 of that License or (at your option) any
100204 + * later version.
100205 + *
100206 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100207 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100208 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100209 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100210 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100211 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100212 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100213 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100214 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100215 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100216 + */
100217 +
100218 +/**************************************************************************//**
100219 + @File dpaa_integration_ext.h
100220 +
100221 + @Description P3040/P4080/P5020 FM external definitions and structures.
100222 +*//***************************************************************************/
100223 +#ifndef __DPAA_INTEGRATION_EXT_H
100224 +#define __DPAA_INTEGRATION_EXT_H
100225 +
100226 +#include "std_ext.h"
100227 +
100228 +
100229 +#define DPAA_VERSION 10
100230 +
100231 +typedef enum {
100232 + e_DPAA_SWPORTAL0 = 0,
100233 + e_DPAA_SWPORTAL1,
100234 + e_DPAA_SWPORTAL2,
100235 + e_DPAA_SWPORTAL3,
100236 + e_DPAA_SWPORTAL4,
100237 + e_DPAA_SWPORTAL5,
100238 + e_DPAA_SWPORTAL6,
100239 + e_DPAA_SWPORTAL7,
100240 + e_DPAA_SWPORTAL8,
100241 + e_DPAA_SWPORTAL9,
100242 + e_DPAA_SWPORTAL_DUMMY_LAST
100243 +} e_DpaaSwPortal;
100244 +
100245 +typedef enum {
100246 + e_DPAA_DCPORTAL0 = 0,
100247 + e_DPAA_DCPORTAL1,
100248 + e_DPAA_DCPORTAL2,
100249 + e_DPAA_DCPORTAL3,
100250 + e_DPAA_DCPORTAL4,
100251 + e_DPAA_DCPORTAL_DUMMY_LAST
100252 +} e_DpaaDcPortal;
100253 +
100254 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100255 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100256 +
100257 +/*****************************************************************************
100258 + QMan INTEGRATION-SPECIFIC DEFINITIONS
100259 +******************************************************************************/
100260 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
100261 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
100262 +#define QM_MAX_NUM_OF_SWP_AS 4
100263 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
100264 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
100265 +
100266 +/**************************************************************************//**
100267 + @Description Work Queue Channel assignments in QMan.
100268 +*//***************************************************************************/
100269 +typedef enum
100270 +{
100271 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
100272 + e_QM_FQ_CHANNEL_SWPORTAL1,
100273 + e_QM_FQ_CHANNEL_SWPORTAL2,
100274 + e_QM_FQ_CHANNEL_SWPORTAL3,
100275 + e_QM_FQ_CHANNEL_SWPORTAL4,
100276 + e_QM_FQ_CHANNEL_SWPORTAL5,
100277 + e_QM_FQ_CHANNEL_SWPORTAL6,
100278 + e_QM_FQ_CHANNEL_SWPORTAL7,
100279 + e_QM_FQ_CHANNEL_SWPORTAL8,
100280 + e_QM_FQ_CHANNEL_SWPORTAL9,
100281 +
100282 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
100283 + e_QM_FQ_CHANNEL_POOL2,
100284 + e_QM_FQ_CHANNEL_POOL3,
100285 + e_QM_FQ_CHANNEL_POOL4,
100286 + e_QM_FQ_CHANNEL_POOL5,
100287 + e_QM_FQ_CHANNEL_POOL6,
100288 + e_QM_FQ_CHANNEL_POOL7,
100289 + e_QM_FQ_CHANNEL_POOL8,
100290 + e_QM_FQ_CHANNEL_POOL9,
100291 + e_QM_FQ_CHANNEL_POOL10,
100292 + e_QM_FQ_CHANNEL_POOL11,
100293 + e_QM_FQ_CHANNEL_POOL12,
100294 + e_QM_FQ_CHANNEL_POOL13,
100295 + e_QM_FQ_CHANNEL_POOL14,
100296 + e_QM_FQ_CHANNEL_POOL15,
100297 +
100298 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
100299 + connected to FMan 0; assigned in incrementing order to
100300 + each sub-portal (SP) in the portal */
100301 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100302 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100303 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100304 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100305 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100306 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100307 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100308 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100309 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100310 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100311 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100312 +/* difference between 5020 and 4080 :) */
100313 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
100314 + e_QM_FQ_CHANNEL_FMAN1_SP1,
100315 + e_QM_FQ_CHANNEL_FMAN1_SP2,
100316 + e_QM_FQ_CHANNEL_FMAN1_SP3,
100317 + e_QM_FQ_CHANNEL_FMAN1_SP4,
100318 + e_QM_FQ_CHANNEL_FMAN1_SP5,
100319 + e_QM_FQ_CHANNEL_FMAN1_SP6,
100320 + e_QM_FQ_CHANNEL_FMAN1_SP7,
100321 + e_QM_FQ_CHANNEL_FMAN1_SP8,
100322 + e_QM_FQ_CHANNEL_FMAN1_SP9,
100323 + e_QM_FQ_CHANNEL_FMAN1_SP10,
100324 + e_QM_FQ_CHANNEL_FMAN1_SP11,
100325 +
100326 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
100327 + connected to SEC 4.x */
100328 +
100329 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
100330 + connected to PME */
100331 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
100332 + connected to RAID */
100333 +} e_QmFQChannel;
100334 +
100335 +/*****************************************************************************
100336 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100337 +******************************************************************************/
100338 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100339 +
100340 +
100341 +/*****************************************************************************
100342 + FM INTEGRATION-SPECIFIC DEFINITIONS
100343 +******************************************************************************/
100344 +#define INTG_MAX_NUM_OF_FM 2
100345 +
100346 +/* Ports defines */
100347 +#define FM_MAX_NUM_OF_1G_MACS 5
100348 +#define FM_MAX_NUM_OF_10G_MACS 1
100349 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100350 +#define FM_MAX_NUM_OF_OH_PORTS 7
100351 +
100352 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100353 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100354 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100355 +
100356 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100357 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100358 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100359 +
100360 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
100361 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100362 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
100363 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100364 +
100365 +/* Rams defines */
100366 +#define FM_MURAM_SIZE (160*KILOBYTE)
100367 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100368 +#define FM_NUM_OF_CTRL 2
100369 +
100370 +/* PCD defines */
100371 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100372 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100373 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100374 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
100375 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100376 +
100377 +/* RTC defines */
100378 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100379 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
100380 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100381 +
100382 +/* QMI defines */
100383 +#define QMI_MAX_NUM_OF_TNUMS 64
100384 +#define QMI_DEF_TNUMS_THRESH 48
100385 +
100386 +/* FPM defines */
100387 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100388 +
100389 +/* DMA defines */
100390 +#define DMA_THRESH_MAX_COMMQ 31
100391 +#define DMA_THRESH_MAX_BUF 127
100392 +
100393 +/* BMI defines */
100394 +#define BMI_MAX_NUM_OF_TASKS 128
100395 +#define BMI_MAX_NUM_OF_DMAS 32
100396 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100397 +#define PORT_MAX_WEIGHT 16
100398 +
100399 +
100400 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100401 +
100402 +/* p4080-rev1 unique features */
100403 +#define QM_CGS_NO_FRAME_MODE
100404 +
100405 +/* p4080 unique features */
100406 +#define FM_NO_DISPATCH_RAM_ECC
100407 +#define FM_NO_WATCHDOG
100408 +#define FM_NO_TNUM_AGING
100409 +#define FM_KG_NO_BYPASS_FQID_GEN
100410 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
100411 +#define FM_NO_BACKUP_POOLS
100412 +#define FM_NO_OP_OBSERVED_POOLS
100413 +#define FM_NO_ADVANCED_RATE_LIMITER
100414 +#define FM_NO_OP_OBSERVED_CGS
100415 +#define FM_HAS_TOTAL_DMAS
100416 +#define FM_KG_NO_IPPID_SUPPORT
100417 +#define FM_NO_GUARANTEED_RESET_VALUES
100418 +#define FM_MAC_RESET
100419 +
100420 +/* FM erratas */
100421 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
100422 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
100423 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
100424 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
100425 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
100426 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
100427 +
100428 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100429 +#define FM_GRS_ERRATA_DTSEC_A002
100430 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
100431 +#define FM_GTS_ERRATA_DTSEC_A004
100432 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
100433 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
100434 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100435 +
100436 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100437 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
100438 +
100439 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
100440 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100441 +
100442 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
100443 +
100444 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
100445 +
100446 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100447 +
100448 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
100449 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
100450 +
100451 +/*****************************************************************************
100452 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100453 +******************************************************************************/
100454 +#define NUM_OF_RX_SC 16
100455 +#define NUM_OF_TX_SC 16
100456 +
100457 +#define NUM_OF_SA_PER_RX_SC 2
100458 +#define NUM_OF_SA_PER_TX_SC 2
100459 +
100460 +
100461 +#endif /* __DPAA_INTEGRATION_EXT_H */
100462 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100463 new file mode 100644
100464 index 00000000..512f0baf
100465 --- /dev/null
100466 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100467 @@ -0,0 +1,83 @@
100468 +/*
100469 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100470 + *
100471 + * Redistribution and use in source and binary forms, with or without
100472 + * modification, are permitted provided that the following conditions are met:
100473 + * * Redistributions of source code must retain the above copyright
100474 + * notice, this list of conditions and the following disclaimer.
100475 + * * Redistributions in binary form must reproduce the above copyright
100476 + * notice, this list of conditions and the following disclaimer in the
100477 + * documentation and/or other materials provided with the distribution.
100478 + * * Neither the name of Freescale Semiconductor nor the
100479 + * names of its contributors may be used to endorse or promote products
100480 + * derived from this software without specific prior written permission.
100481 + *
100482 + *
100483 + * ALTERNATIVELY, this software may be distributed under the terms of the
100484 + * GNU General Public License ("GPL") as published by the Free Software
100485 + * Foundation, either version 2 of that License or (at your option) any
100486 + * later version.
100487 + *
100488 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100489 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100490 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100491 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100492 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100493 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100494 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100495 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100496 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100497 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100498 + */
100499 +
100500 +/**************************************************************************//**
100501 +
100502 + @File part_ext.h
100503 +
100504 + @Description Definitions for the part (integration) module.
100505 +*//***************************************************************************/
100506 +
100507 +#ifndef __PART_EXT_H
100508 +#define __PART_EXT_H
100509 +
100510 +#include "std_ext.h"
100511 +#include "part_integration_ext.h"
100512 +
100513 +
100514 +#if !(defined(MPC8306) || \
100515 + defined(MPC8309) || \
100516 + defined(MPC834x) || \
100517 + defined(MPC836x) || \
100518 + defined(MPC832x) || \
100519 + defined(MPC837x) || \
100520 + defined(MPC8568) || \
100521 + defined(MPC8569) || \
100522 + defined(P1020) || \
100523 + defined(P1021) || \
100524 + defined(P1022) || \
100525 + defined(P1023) || \
100526 + defined(P2020) || \
100527 + defined(P2040) || \
100528 + defined(P3041) || \
100529 + defined(P4080) || \
100530 + defined(SC4080) || \
100531 + defined(P5020) || \
100532 + defined(MSC814x))
100533 +#error "unable to proceed without chip-definition"
100534 +#endif /* !(defined(MPC834x) || ... */
100535 +
100536 +
100537 +/**************************************************************************//*
100538 + @Description Part data structure - must be contained in any integration
100539 + data structure.
100540 +*//***************************************************************************/
100541 +typedef struct t_Part
100542 +{
100543 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100544 + /**< Returns the address of the module's memory map base. */
100545 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100546 + /**< Returns the module's ID according to its memory map base. */
100547 +} t_Part;
100548 +
100549 +
100550 +#endif /* __PART_EXT_H */
100551 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100552 new file mode 100644
100553 index 00000000..03c59b8b
100554 --- /dev/null
100555 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100556 @@ -0,0 +1,336 @@
100557 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100558 + * All rights reserved.
100559 + *
100560 + * Redistribution and use in source and binary forms, with or without
100561 + * modification, are permitted provided that the following conditions are met:
100562 + * * Redistributions of source code must retain the above copyright
100563 + * notice, this list of conditions and the following disclaimer.
100564 + * * Redistributions in binary form must reproduce the above copyright
100565 + * notice, this list of conditions and the following disclaimer in the
100566 + * documentation and/or other materials provided with the distribution.
100567 + * * Neither the name of Freescale Semiconductor nor the
100568 + * names of its contributors may be used to endorse or promote products
100569 + * derived from this software without specific prior written permission.
100570 + *
100571 + *
100572 + * ALTERNATIVELY, this software may be distributed under the terms of the
100573 + * GNU General Public License ("GPL") as published by the Free Software
100574 + * Foundation, either version 2 of that License or (at your option) any
100575 + * later version.
100576 + *
100577 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100578 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100579 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100580 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100581 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100582 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100583 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100584 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100585 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100586 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100587 + */
100588 +
100589 +/**************************************************************************//**
100590 + @File part_integration_ext.h
100591 +
100592 + @Description P3040/P4080/P5020 external definitions and structures.
100593 +*//***************************************************************************/
100594 +#ifndef __PART_INTEGRATION_EXT_H
100595 +#define __PART_INTEGRATION_EXT_H
100596 +
100597 +#include "std_ext.h"
100598 +#include "dpaa_integration_ext.h"
100599 +
100600 +
100601 +/**************************************************************************//**
100602 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100603 +
100604 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100605 +
100606 + @{
100607 +*//***************************************************************************/
100608 +
100609 +#define CORE_E500MC
100610 +
100611 +#define INTG_MAX_NUM_OF_CORES 1
100612 +
100613 +
100614 +/**************************************************************************//**
100615 + @Description Module types.
100616 +*//***************************************************************************/
100617 +typedef enum e_ModuleId
100618 +{
100619 + e_MODULE_ID_DUART_1 = 0,
100620 + e_MODULE_ID_DUART_2,
100621 + e_MODULE_ID_DUART_3,
100622 + e_MODULE_ID_DUART_4,
100623 + e_MODULE_ID_LAW,
100624 + e_MODULE_ID_LBC,
100625 + e_MODULE_ID_PAMU,
100626 + e_MODULE_ID_QM, /**< Queue manager module */
100627 + e_MODULE_ID_BM, /**< Buffer manager module */
100628 + e_MODULE_ID_QM_CE_PORTAL_0,
100629 + e_MODULE_ID_QM_CI_PORTAL_0,
100630 + e_MODULE_ID_QM_CE_PORTAL_1,
100631 + e_MODULE_ID_QM_CI_PORTAL_1,
100632 + e_MODULE_ID_QM_CE_PORTAL_2,
100633 + e_MODULE_ID_QM_CI_PORTAL_2,
100634 + e_MODULE_ID_QM_CE_PORTAL_3,
100635 + e_MODULE_ID_QM_CI_PORTAL_3,
100636 + e_MODULE_ID_QM_CE_PORTAL_4,
100637 + e_MODULE_ID_QM_CI_PORTAL_4,
100638 + e_MODULE_ID_QM_CE_PORTAL_5,
100639 + e_MODULE_ID_QM_CI_PORTAL_5,
100640 + e_MODULE_ID_QM_CE_PORTAL_6,
100641 + e_MODULE_ID_QM_CI_PORTAL_6,
100642 + e_MODULE_ID_QM_CE_PORTAL_7,
100643 + e_MODULE_ID_QM_CI_PORTAL_7,
100644 + e_MODULE_ID_QM_CE_PORTAL_8,
100645 + e_MODULE_ID_QM_CI_PORTAL_8,
100646 + e_MODULE_ID_QM_CE_PORTAL_9,
100647 + e_MODULE_ID_QM_CI_PORTAL_9,
100648 + e_MODULE_ID_BM_CE_PORTAL_0,
100649 + e_MODULE_ID_BM_CI_PORTAL_0,
100650 + e_MODULE_ID_BM_CE_PORTAL_1,
100651 + e_MODULE_ID_BM_CI_PORTAL_1,
100652 + e_MODULE_ID_BM_CE_PORTAL_2,
100653 + e_MODULE_ID_BM_CI_PORTAL_2,
100654 + e_MODULE_ID_BM_CE_PORTAL_3,
100655 + e_MODULE_ID_BM_CI_PORTAL_3,
100656 + e_MODULE_ID_BM_CE_PORTAL_4,
100657 + e_MODULE_ID_BM_CI_PORTAL_4,
100658 + e_MODULE_ID_BM_CE_PORTAL_5,
100659 + e_MODULE_ID_BM_CI_PORTAL_5,
100660 + e_MODULE_ID_BM_CE_PORTAL_6,
100661 + e_MODULE_ID_BM_CI_PORTAL_6,
100662 + e_MODULE_ID_BM_CE_PORTAL_7,
100663 + e_MODULE_ID_BM_CI_PORTAL_7,
100664 + e_MODULE_ID_BM_CE_PORTAL_8,
100665 + e_MODULE_ID_BM_CI_PORTAL_8,
100666 + e_MODULE_ID_BM_CE_PORTAL_9,
100667 + e_MODULE_ID_BM_CI_PORTAL_9,
100668 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100669 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100670 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100671 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100672 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100673 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100674 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100675 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100676 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100677 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100678 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100679 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100680 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100681 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100682 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100683 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100684 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100685 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100686 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100687 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100688 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100689 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100690 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100691 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100692 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100693 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100694 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100695 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100696 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100697 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100698 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100699 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100700 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100701 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100702 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100703 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100704 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100705 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100706 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100707 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100708 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100709 +
100710 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100711 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100712 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100713 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100714 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100715 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100716 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100717 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100718 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100719 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100720 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100721 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100722 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100723 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100724 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100725 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100726 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100727 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100728 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100729 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100730 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100731 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100732 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100733 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100734 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100735 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100736 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100737 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100738 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100739 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100740 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100741 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100742 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100743 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100744 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100745 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100746 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100747 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100748 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100749 +
100750 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100751 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100752 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100753 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100754 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100755 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100756 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100757 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100758 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100759 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100760 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100761 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100762 +
100763 + e_MODULE_ID_MPIC, /**< MPIC */
100764 + e_MODULE_ID_GPIO, /**< GPIO */
100765 + e_MODULE_ID_SERDES, /**< SERDES */
100766 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100767 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100768 +
100769 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100770 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100771 +
100772 + e_MODULE_ID_DUMMY_LAST
100773 +} e_ModuleId;
100774 +
100775 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100776 +
100777 +#if 0 /* using unified values */
100778 +/*****************************************************************************
100779 + INTEGRATION-SPECIFIC MODULE CODES
100780 +******************************************************************************/
100781 +#define MODULE_UNKNOWN 0x00000000
100782 +#define MODULE_MEM 0x00010000
100783 +#define MODULE_MM 0x00020000
100784 +#define MODULE_CORE 0x00030000
100785 +#define MODULE_CHIP 0x00040000
100786 +#define MODULE_PLTFRM 0x00050000
100787 +#define MODULE_PM 0x00060000
100788 +#define MODULE_MMU 0x00070000
100789 +#define MODULE_PIC 0x00080000
100790 +#define MODULE_CPC 0x00090000
100791 +#define MODULE_DUART 0x000a0000
100792 +#define MODULE_SERDES 0x000b0000
100793 +#define MODULE_PIO 0x000c0000
100794 +#define MODULE_QM 0x000d0000
100795 +#define MODULE_BM 0x000e0000
100796 +#define MODULE_SEC 0x000f0000
100797 +#define MODULE_LAW 0x00100000
100798 +#define MODULE_LBC 0x00110000
100799 +#define MODULE_PAMU 0x00120000
100800 +#define MODULE_FM 0x00130000
100801 +#define MODULE_FM_MURAM 0x00140000
100802 +#define MODULE_FM_PCD 0x00150000
100803 +#define MODULE_FM_RTC 0x00160000
100804 +#define MODULE_FM_MAC 0x00170000
100805 +#define MODULE_FM_PORT 0x00180000
100806 +#define MODULE_FM_SP 0x00190000
100807 +#define MODULE_DPA_PORT 0x001a0000
100808 +#define MODULE_MII 0x001b0000
100809 +#define MODULE_I2C 0x001c0000
100810 +#define MODULE_DMA 0x001d0000
100811 +#define MODULE_DDR 0x001e0000
100812 +#define MODULE_ESPI 0x001f0000
100813 +#define MODULE_DPAA_IPSEC 0x00200000
100814 +#endif /* using unified values */
100815 +
100816 +/*****************************************************************************
100817 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100818 +******************************************************************************/
100819 +#define PAMU_NUM_OF_PARTITIONS 5
100820 +
100821 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100822 +
100823 +/*****************************************************************************
100824 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100825 +******************************************************************************/
100826 +#define LAW_NUM_OF_WINDOWS 32
100827 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100828 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100829 +
100830 +
100831 +/*****************************************************************************
100832 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100833 +******************************************************************************/
100834 +/**************************************************************************//**
100835 + @Group lbc_exception_grp LBC Exception Unit
100836 +
100837 + @Description LBC Exception unit API functions, definitions and enums
100838 +
100839 + @{
100840 +*//***************************************************************************/
100841 +
100842 +/**************************************************************************//**
100843 + @Anchor lbc_exbm
100844 +
100845 + @Collection LBC Errors Bit Mask
100846 +
100847 + These errors are reported through the exceptions callback..
100848 + The values can be or'ed in any combination in the errors mask
100849 + parameter of the errors report structure.
100850 +
100851 + These errors can also be passed as a bit-mask to
100852 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100853 + for enabling or disabling error checking.
100854 + @{
100855 +*//***************************************************************************/
100856 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100857 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100858 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100859 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
100860 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
100861 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100862 +
100863 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100864 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
100865 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
100866 + /**< All possible errors */
100867 +/* @} */
100868 +/** @} */ /* end of lbc_exception_grp group */
100869 +
100870 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100871 +
100872 +#define LBC_NUM_OF_BANKS 8
100873 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100874 +#define LBC_ATOMIC_OPERATION_SUPPORT
100875 +#define LBC_PARITY_SUPPORT
100876 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100877 +#define LBC_HIGH_CLK_DIVIDERS
100878 +#define LBC_FCM_AVAILABLE
100879 +
100880 +/*****************************************************************************
100881 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100882 +******************************************************************************/
100883 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
100884 + Each port contains up to 32 i/O pins. */
100885 +
100886 +#define GPIO_VALID_PIN_MASKS \
100887 + { /* Port A */ 0xFFFFFFFF }
100888 +
100889 +#define GPIO_VALID_INTR_MASKS \
100890 + { /* Port A */ 0xFFFFFFFF }
100891 +
100892 +#endif /* __PART_INTEGRATION_EXT_H */
100893 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100894 new file mode 100644
100895 index 00000000..4ecfc6ed
100896 --- /dev/null
100897 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100898 @@ -0,0 +1,100 @@
100899 +/*
100900 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100901 + *
100902 + * Redistribution and use in source and binary forms, with or without
100903 + * modification, are permitted provided that the following conditions are met:
100904 + * * Redistributions of source code must retain the above copyright
100905 + * notice, this list of conditions and the following disclaimer.
100906 + * * Redistributions in binary form must reproduce the above copyright
100907 + * notice, this list of conditions and the following disclaimer in the
100908 + * documentation and/or other materials provided with the distribution.
100909 + * * Neither the name of Freescale Semiconductor nor the
100910 + * names of its contributors may be used to endorse or promote products
100911 + * derived from this software without specific prior written permission.
100912 + *
100913 + *
100914 + * ALTERNATIVELY, this software may be distributed under the terms of the
100915 + * GNU General Public License ("GPL") as published by the Free Software
100916 + * Foundation, either version 2 of that License or (at your option) any
100917 + * later version.
100918 + *
100919 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100920 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100921 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100922 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100923 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100924 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100925 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100926 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100927 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100928 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100929 + */
100930 +
100931 +
100932 +#ifndef __MATH_EXT_H
100933 +#define __MATH_EXT_H
100934 +
100935 +
100936 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
100937 +#include <linux/math.h>
100938 +#include <linux/math64.h>
100939 +
100940 +#elif defined(__MWERKS__)
100941 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
100942 +#define HIGH(x) (*(int32_t*)&x)
100943 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
100944 +#define UHIGH(x) (*(uint32_t*)&x)
100945 +
100946 +static const double big = 1.0e300;
100947 +
100948 +/* Macro for checking if a number is a power of 2 */
100949 +static __inline__ double ceil(double x)
100950 +{
100951 + int32_t i0,i1,j0; /*- cc 020130 -*/
100952 + uint32_t i,j; /*- cc 020130 -*/
100953 + i0 = HIGH(x);
100954 + i1 = LOW(x);
100955 + j0 = ((i0>>20)&0x7ff)-0x3ff;
100956 + if(j0<20) {
100957 + if(j0<0) { /* raise inexact if x != 0 */
100958 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
100959 + if(i0<0) {i0=0x80000000;i1=0;}
100960 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
100961 + }
100962 + } else {
100963 + i = (uint32_t)(0x000fffff)>>j0;
100964 + if(((i0&i)|i1)==0) return x; /* x is integral */
100965 + if(big+x>0.0) { /* raise inexact flag */
100966 + if(i0>0) i0 += (0x00100000)>>j0;
100967 + i0 &= (~i); i1=0;
100968 + }
100969 + }
100970 + } else if (j0>51) {
100971 + if(j0==0x400) return x+x; /* inf or NaN */
100972 + else return x; /* x is integral */
100973 + } else {
100974 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
100975 + if((i1&i)==0) return x; /* x is integral */
100976 + if(big+x>0.0) { /* raise inexact flag */
100977 + if(i0>0) {
100978 + if(j0==20) i0+=1;
100979 + else {
100980 + j = (uint32_t)(i1 + (1<<(52-j0)));
100981 + if(j<i1) i0+=1; /* got a carry */
100982 + i1 = (int32_t)j;
100983 + }
100984 + }
100985 + i1 &= (~i);
100986 + }
100987 + }
100988 + HIGH(x) = i0;
100989 + LOW(x) = i1;
100990 + return x;
100991 +}
100992 +
100993 +#else
100994 +#include <math.h>
100995 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
100996 +
100997 +
100998 +#endif /* __MATH_EXT_H */
100999 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
101000 new file mode 100644
101001 index 00000000..dc32e249
101002 --- /dev/null
101003 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
101004 @@ -0,0 +1,435 @@
101005 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101006 + * All rights reserved.
101007 + *
101008 + * Redistribution and use in source and binary forms, with or without
101009 + * modification, are permitted provided that the following conditions are met:
101010 + * * Redistributions of source code must retain the above copyright
101011 + * notice, this list of conditions and the following disclaimer.
101012 + * * Redistributions in binary form must reproduce the above copyright
101013 + * notice, this list of conditions and the following disclaimer in the
101014 + * documentation and/or other materials provided with the distribution.
101015 + * * Neither the name of Freescale Semiconductor nor the
101016 + * names of its contributors may be used to endorse or promote products
101017 + * derived from this software without specific prior written permission.
101018 + *
101019 + *
101020 + * ALTERNATIVELY, this software may be distributed under the terms of the
101021 + * GNU General Public License ("GPL") as published by the Free Software
101022 + * Foundation, either version 2 of that License or (at your option) any
101023 + * later version.
101024 + *
101025 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101026 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101027 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101028 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101029 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101030 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101031 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101032 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101033 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101034 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101035 + */
101036 +
101037 +
101038 +/**************************************************************************//**
101039 + @File ncsw_ext.h
101040 +
101041 + @Description General NetCommSw Standard Definitions
101042 +*//***************************************************************************/
101043 +
101044 +#ifndef __NCSW_EXT_H
101045 +#define __NCSW_EXT_H
101046 +
101047 +
101048 +#include "memcpy_ext.h"
101049 +
101050 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
101051 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
101052 +
101053 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
101054 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
101055 +
101056 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
101057 +
101058 +
101059 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
101060 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
101061 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
101062 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
101063 +
101064 +/* Little-Endian access macros */
101065 +
101066 +#define WRITE_UINT16_LE(arg, data) \
101067 + WRITE_UINT16((arg), SwapUint16(data))
101068 +
101069 +#define WRITE_UINT32_LE(arg, data) \
101070 + WRITE_UINT32((arg), SwapUint32(data))
101071 +
101072 +#define WRITE_UINT64_LE(arg, data) \
101073 + WRITE_UINT64((arg), SwapUint64(data))
101074 +
101075 +#define GET_UINT16_LE(arg) \
101076 + SwapUint16(GET_UINT16(arg))
101077 +
101078 +#define GET_UINT32_LE(arg) \
101079 + SwapUint32(GET_UINT32(arg))
101080 +
101081 +#define GET_UINT64_LE(arg) \
101082 + SwapUint64(GET_UINT64(arg))
101083 +
101084 +/* Write and Read again macros */
101085 +#define WRITE_UINT_SYNC(size, arg, data) \
101086 + do { \
101087 + WRITE_UINT##size((arg), (data)); \
101088 + CORE_MemoryBarrier(); \
101089 + } while (0)
101090 +
101091 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
101092 +
101093 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
101094 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
101095 +
101096 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
101097 +
101098 +
101099 +/*----------------------*/
101100 +/* Miscellaneous macros */
101101 +/*----------------------*/
101102 +
101103 +#define UNUSED(_x) ((void)(_x))
101104 +
101105 +#define KILOBYTE 0x400UL /* 1024 */
101106 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
101107 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
101108 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
101109 +
101110 +#ifndef NO_IRQ
101111 +#define NO_IRQ (0)
101112 +#endif
101113 +#define NCSW_MASTER_ID (0)
101114 +
101115 +/* Macro for checking if a number is a power of 2 */
101116 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
101117 +
101118 +/* Macro for calculating log of base 2 */
101119 +#define LOG2(num, log2Num) \
101120 + do \
101121 + { \
101122 + uint64_t tmp = (num); \
101123 + log2Num = 0; \
101124 + while (tmp > 1) \
101125 + { \
101126 + log2Num++; \
101127 + tmp >>= 1; \
101128 + } \
101129 + } while (0)
101130 +
101131 +#define NEXT_POWER_OF_2(_num, _nextPow) \
101132 +do \
101133 +{ \
101134 + if (POWER_OF_2(_num)) \
101135 + _nextPow = (_num); \
101136 + else \
101137 + { \
101138 + uint64_t tmp = (_num); \
101139 + _nextPow = 1; \
101140 + while (tmp) \
101141 + { \
101142 + _nextPow <<= 1; \
101143 + tmp >>= 1; \
101144 + } \
101145 + } \
101146 +} while (0)
101147 +
101148 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
101149 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
101150 +
101151 +/* Round up a number to be a multiple of a second number */
101152 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
101153 +
101154 +/* Timing macro for converting usec units to number of ticks. */
101155 +/* (number of usec * clock_Hz) / 1,000,000) - since */
101156 +/* clk is in MHz units, no division needed. */
101157 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
101158 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
101159 +
101160 +/* Timing macros for converting between nsec units and number of clocks. */
101161 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
101162 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
101163 +
101164 +/* Timing macros for converting between psec units and number of clocks. */
101165 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
101166 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
101167 +
101168 +/* Min, Max macros */
101169 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
101170 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
101171 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
101172 +
101173 +#define ABS(a) ((a<0)?(a*-1):a)
101174 +
101175 +#if !(defined(ARRAY_SIZE))
101176 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
101177 +#endif /* !defined(ARRAY_SIZE) */
101178 +
101179 +
101180 +/* possible alignments */
101181 +#define HALF_WORD_ALIGNMENT 2
101182 +#define WORD_ALIGNMENT 4
101183 +#define DOUBLE_WORD_ALIGNMENT 8
101184 +#define BURST_ALIGNMENT 32
101185 +
101186 +#define HALF_WORD_ALIGNED 0x00000001
101187 +#define WORD_ALIGNED 0x00000003
101188 +#define DOUBLE_WORD_ALIGNED 0x00000007
101189 +#define BURST_ALIGNED 0x0000001f
101190 +#ifndef IS_ALIGNED
101191 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
101192 +#endif /* IS_ALIGNED */
101193 +
101194 +
101195 +#define LAST_BUF 1
101196 +#define FIRST_BUF 2
101197 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
101198 +#define MIDDLE_BUF 4
101199 +
101200 +#define ARRAY_END -1
101201 +
101202 +#define ILLEGAL_BASE (~0)
101203 +
101204 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
101205 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
101206 +
101207 +
101208 +/**************************************************************************//**
101209 + @Description Timers operation mode
101210 +*//***************************************************************************/
101211 +typedef enum e_TimerMode
101212 +{
101213 + e_TIMER_MODE_INVALID = 0,
101214 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
101215 + after reaching the reference value. */
101216 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
101217 + after reaching the reference value. */
101218 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
101219 + after reaching the reference value. */
101220 +} e_TimerMode;
101221 +
101222 +
101223 +/**************************************************************************//**
101224 + @Description Enumeration (bit flags) of communication modes (Transmit,
101225 + receive or both).
101226 +*//***************************************************************************/
101227 +typedef enum e_CommMode
101228 +{
101229 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
101230 + e_COMM_MODE_RX = 1, /**< Only receive communication */
101231 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
101232 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
101233 +} e_CommMode;
101234 +
101235 +/**************************************************************************//**
101236 + @Description General Diagnostic Mode
101237 +*//***************************************************************************/
101238 +typedef enum e_DiagMode
101239 +{
101240 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
101241 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
101242 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
101243 + controller; e.g. IO-pins, SerDes, etc. */
101244 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
101245 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
101246 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
101247 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
101248 +} e_DiagMode;
101249 +
101250 +/**************************************************************************//**
101251 + @Description Possible RxStore callback responses.
101252 +*//***************************************************************************/
101253 +typedef enum e_RxStoreResponse
101254 +{
101255 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
101256 + in polling mode, start again invoking callback
101257 + only next time user invokes the receive routine;
101258 + in interrupt mode, start again invoking callback
101259 + only next time a receive event triggers an interrupt;
101260 + in all cases, received data that are pending are not
101261 + lost, rather, their processing is temporarily deferred;
101262 + in all cases, received data are processed in the order
101263 + in which they were received. */
101264 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
101265 +} e_RxStoreResponse;
101266 +
101267 +
101268 +/**************************************************************************//**
101269 + @Description General Handle
101270 +*//***************************************************************************/
101271 +typedef void * t_Handle; /**< handle, used as object's descriptor */
101272 +
101273 +/**************************************************************************//**
101274 + @Description MUTEX type
101275 +*//***************************************************************************/
101276 +typedef uint32_t t_Mutex;
101277 +
101278 +/**************************************************************************//**
101279 + @Description Error Code.
101280 +
101281 + The high word of the error code is the code of the software
101282 + module (driver). The low word is the error type (e_ErrorType).
101283 + To get the values from the error code, use GET_ERROR_TYPE()
101284 + and GET_ERROR_MODULE().
101285 +*//***************************************************************************/
101286 +typedef uint32_t t_Error;
101287 +
101288 +/**************************************************************************//**
101289 + @Description General prototype of interrupt service routine (ISR).
101290 +
101291 + @Param[in] handle - Optional handle of the module handling the interrupt.
101292 +
101293 + @Return None
101294 + *//***************************************************************************/
101295 +typedef void (t_Isr)(t_Handle handle);
101296 +
101297 +/**************************************************************************//**
101298 + @Anchor mem_attr
101299 +
101300 + @Collection Memory Attributes
101301 +
101302 + Various attributes of memory partitions. These values may be
101303 + or'ed together to create a mask of all memory attributes.
101304 + @{
101305 +*//***************************************************************************/
101306 +#define MEMORY_ATTR_CACHEABLE 0x00000001
101307 + /**< Memory is cacheable */
101308 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
101309 + /**< Memory can be accessed by QUICC Engine
101310 + through its secondary bus interface */
101311 +
101312 +/* @} */
101313 +
101314 +
101315 +/**************************************************************************//**
101316 + @Function t_GetBufFunction
101317 +
101318 + @Description User callback function called by driver to get data buffer.
101319 +
101320 + User provides this function. Driver invokes it.
101321 +
101322 + @Param[in] h_BufferPool - A handle to buffer pool manager
101323 + @Param[out] p_BufContextHandle - Returns the user's private context that
101324 + should be associated with the buffer
101325 +
101326 + @Return Pointer to data buffer, NULL if error
101327 + *//***************************************************************************/
101328 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
101329 + t_Handle *p_BufContextHandle);
101330 +
101331 +/**************************************************************************//**
101332 + @Function t_PutBufFunction
101333 +
101334 + @Description User callback function called by driver to return data buffer.
101335 +
101336 + User provides this function. Driver invokes it.
101337 +
101338 + @Param[in] h_BufferPool - A handle to buffer pool manager
101339 + @Param[in] p_Buffer - A pointer to buffer to return
101340 + @Param[in] h_BufContext - The user's private context associated with
101341 + the returned buffer
101342 +
101343 + @Return E_OK on success; Error code otherwise
101344 + *//***************************************************************************/
101345 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
101346 + uint8_t *p_Buffer,
101347 + t_Handle h_BufContext);
101348 +
101349 +/**************************************************************************//**
101350 + @Function t_PhysToVirt
101351 +
101352 + @Description Translates a physical address to the matching virtual address.
101353 +
101354 + @Param[in] addr - The physical address to translate.
101355 +
101356 + @Return Virtual address.
101357 +*//***************************************************************************/
101358 +typedef void * t_PhysToVirt(physAddress_t addr);
101359 +
101360 +/**************************************************************************//**
101361 + @Function t_VirtToPhys
101362 +
101363 + @Description Translates a virtual address to the matching physical address.
101364 +
101365 + @Param[in] addr - The virtual address to translate.
101366 +
101367 + @Return Physical address.
101368 +*//***************************************************************************/
101369 +typedef physAddress_t t_VirtToPhys(void *addr);
101370 +
101371 +/**************************************************************************//**
101372 + @Description Buffer Pool Information Structure.
101373 +*//***************************************************************************/
101374 +typedef struct t_BufferPoolInfo
101375 +{
101376 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
101377 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
101378 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
101379 + uint16_t bufferSize; /**< Buffer size (in bytes) */
101380 +
101381 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
101382 + physical addresses to virtual addresses */
101383 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
101384 + virtual addresses to physical addresses */
101385 +} t_BufferPoolInfo;
101386 +
101387 +
101388 +/**************************************************************************//**
101389 + @Description User callback function called by driver when transmit completed.
101390 +
101391 + User provides this function. Driver invokes it.
101392 +
101393 + @Param[in] h_App - Application's handle, as was provided to the
101394 + driver by the user
101395 + @Param[in] queueId - Transmit queue ID
101396 + @Param[in] p_Data - Pointer to the data buffer
101397 + @Param[in] h_BufContext - The user's private context associated with
101398 + the given data buffer
101399 + @Param[in] status - Transmit status and errors
101400 + @Param[in] flags - Driver-dependent information
101401 + *//***************************************************************************/
101402 +typedef void (t_TxConfFunction)(t_Handle h_App,
101403 + uint32_t queueId,
101404 + uint8_t *p_Data,
101405 + t_Handle h_BufContext,
101406 + uint16_t status,
101407 + uint32_t flags);
101408 +
101409 +/**************************************************************************//**
101410 + @Description User callback function called by driver with receive data.
101411 +
101412 + User provides this function. Driver invokes it.
101413 +
101414 + @Param[in] h_App - Application's handle, as was provided to the
101415 + driver by the user
101416 + @Param[in] queueId - Receive queue ID
101417 + @Param[in] p_Data - Pointer to the buffer with received data
101418 + @Param[in] h_BufContext - The user's private context associated with
101419 + the given data buffer
101420 + @Param[in] length - Length of received data
101421 + @Param[in] status - Receive status and errors
101422 + @Param[in] position - Position of buffer in frame
101423 + @Param[in] flags - Driver-dependent information
101424 +
101425 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
101426 + operation for all ready data.
101427 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
101428 + *//***************************************************************************/
101429 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
101430 + uint32_t queueId,
101431 + uint8_t *p_Data,
101432 + t_Handle h_BufContext,
101433 + uint32_t length,
101434 + uint16_t status,
101435 + uint8_t position,
101436 + uint32_t flags);
101437 +
101438 +
101439 +#endif /* __NCSW_EXT_H */
101440 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101441 new file mode 100644
101442 index 00000000..8f3bc369
101443 --- /dev/null
101444 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101445 @@ -0,0 +1,430 @@
101446 +/*
101447 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101448 + *
101449 + * Redistribution and use in source and binary forms, with or without
101450 + * modification, are permitted provided that the following conditions are met:
101451 + * * Redistributions of source code must retain the above copyright
101452 + * notice, this list of conditions and the following disclaimer.
101453 + * * Redistributions in binary form must reproduce the above copyright
101454 + * notice, this list of conditions and the following disclaimer in the
101455 + * documentation and/or other materials provided with the distribution.
101456 + * * Neither the name of Freescale Semiconductor nor the
101457 + * names of its contributors may be used to endorse or promote products
101458 + * derived from this software without specific prior written permission.
101459 + *
101460 + *
101461 + * ALTERNATIVELY, this software may be distributed under the terms of the
101462 + * GNU General Public License ("GPL") as published by the Free Software
101463 + * Foundation, either version 2 of that License or (at your option) any
101464 + * later version.
101465 + *
101466 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101467 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101468 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101469 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101470 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101471 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101472 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101473 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101474 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101475 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101476 + */
101477 +
101478 +
101479 +/**************************************************************************//**
101480 + @File net_ext.h
101481 +
101482 + @Description This file contains common and general netcomm headers definitions.
101483 +*//***************************************************************************/
101484 +#ifndef __NET_EXT_H
101485 +#define __NET_EXT_H
101486 +
101487 +#include "std_ext.h"
101488 +
101489 +
101490 +typedef uint8_t headerFieldPpp_t;
101491 +
101492 +#define NET_HEADER_FIELD_PPP_PID (1)
101493 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
101494 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
101495 +
101496 +
101497 +typedef uint8_t headerFieldPppoe_t;
101498 +
101499 +#define NET_HEADER_FIELD_PPPoE_VER (1)
101500 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
101501 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
101502 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
101503 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101504 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101505 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101506 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101507 +
101508 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101509 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101510 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101511 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101512 +
101513 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101514 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101515 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101516 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101517 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101518 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101519 +
101520 +
101521 +typedef uint8_t headerFieldEth_t;
101522 +
101523 +#define NET_HEADER_FIELD_ETH_DA (1)
101524 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101525 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101526 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101527 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101528 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101529 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101530 +
101531 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101532 +
101533 +typedef uint16_t headerFieldIp_t;
101534 +
101535 +#define NET_HEADER_FIELD_IP_VER (1)
101536 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101537 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101538 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101539 +
101540 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101541 +
101542 +typedef uint16_t headerFieldIpv4_t;
101543 +
101544 +#define NET_HEADER_FIELD_IPv4_VER (1)
101545 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101546 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101547 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101548 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101549 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101550 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101551 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101552 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101553 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101554 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101555 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101556 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101557 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101558 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101559 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101560 +
101561 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101562 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101563 +
101564 +
101565 +typedef uint8_t headerFieldIpv6_t;
101566 +
101567 +#define NET_HEADER_FIELD_IPv6_VER (1)
101568 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101569 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101570 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101571 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101572 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101573 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101574 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101575 +
101576 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101577 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101578 +
101579 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101580 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101581 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101582 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101583 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101584 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101585 +
101586 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101587 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101588 +
101589 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101590 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101591 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101592 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101593 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101594 +
101595 +
101596 +typedef uint16_t headerFieldTcp_t;
101597 +
101598 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101599 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101600 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101601 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101602 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101603 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101604 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101605 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101606 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101607 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101608 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101609 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101610 +
101611 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101612 +
101613 +
101614 +typedef uint8_t headerFieldSctp_t;
101615 +
101616 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101617 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101618 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101619 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101620 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101621 +
101622 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101623 +
101624 +typedef uint8_t headerFieldDccp_t;
101625 +
101626 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101627 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101628 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101629 +
101630 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101631 +
101632 +
101633 +typedef uint8_t headerFieldUdp_t;
101634 +
101635 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101636 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101637 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101638 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101639 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101640 +
101641 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101642 +
101643 +typedef uint8_t headerFieldUdpLite_t;
101644 +
101645 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101646 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101647 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101648 +
101649 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101650 +
101651 +typedef uint8_t headerFieldUdpEncapEsp_t;
101652 +
101653 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101654 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101655 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101656 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101657 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101658 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101659 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101660 +
101661 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101662 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101663 +
101664 +#define NET_HEADER_FIELD_IPHC_CID (1)
101665 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101666 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101667 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101668 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101669 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101670 +
101671 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101672 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101673 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101674 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101675 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101676 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101677 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101678 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101679 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101680 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101681 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101682 +
101683 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101684 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101685 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101686 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101687 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101688 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101689 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101690 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101691 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101692 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101693 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101694 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101695 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101696 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101697 +
101698 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101699 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101700 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101701 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101702 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101703 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101704 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101705 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101706 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101707 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101708 +
101709 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101710 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101711 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101712 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101713 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101714 +
101715 +
101716 +typedef uint8_t headerFieldVlan_t;
101717 +
101718 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101719 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101720 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101721 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101722 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101723 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101724 +
101725 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101726 + NET_HEADER_FIELD_VLAN_CFI | \
101727 + NET_HEADER_FIELD_VLAN_VID)
101728 +
101729 +
101730 +typedef uint8_t headerFieldLlc_t;
101731 +
101732 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101733 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101734 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101735 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101736 +
101737 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101738 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101739 +
101740 +
101741 +typedef uint8_t headerFieldSnap_t;
101742 +
101743 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101744 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101745 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101746 +
101747 +
101748 +typedef uint8_t headerFieldLlcSnap_t;
101749 +
101750 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101751 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101752 +
101753 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101754 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101755 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101756 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101757 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101758 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101759 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101760 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101761 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101762 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101763 +
101764 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101765 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101766 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101767 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101768 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101769 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101770 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101771 +
101772 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101773 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101774 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101775 +
101776 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101777 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101778 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101779 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101780 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101781 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101782 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101783 +
101784 +
101785 +typedef uint8_t headerFieldGre_t;
101786 +
101787 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101788 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101789 +
101790 +
101791 +typedef uint8_t headerFieldMinencap_t;
101792 +
101793 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101794 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101795 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101796 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101797 +
101798 +
101799 +typedef uint8_t headerFieldIpsecAh_t;
101800 +
101801 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101802 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101803 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101804 +
101805 +
101806 +typedef uint8_t headerFieldIpsecEsp_t;
101807 +
101808 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101809 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101810 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101811 +
101812 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101813 +
101814 +
101815 +typedef uint8_t headerFieldMpls_t;
101816 +
101817 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101818 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101819 +
101820 +
101821 +typedef uint8_t headerFieldMacsec_t;
101822 +
101823 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101824 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101825 +
101826 +
101827 +typedef enum {
101828 + HEADER_TYPE_NONE = 0,
101829 + HEADER_TYPE_PAYLOAD,
101830 + HEADER_TYPE_ETH,
101831 + HEADER_TYPE_VLAN,
101832 + HEADER_TYPE_IPv4,
101833 + HEADER_TYPE_IPv6,
101834 + HEADER_TYPE_IP,
101835 + HEADER_TYPE_TCP,
101836 + HEADER_TYPE_UDP,
101837 + HEADER_TYPE_UDP_LITE,
101838 + HEADER_TYPE_IPHC,
101839 + HEADER_TYPE_SCTP,
101840 + HEADER_TYPE_SCTP_CHUNK_DATA,
101841 + HEADER_TYPE_PPPoE,
101842 + HEADER_TYPE_PPP,
101843 + HEADER_TYPE_PPPMUX,
101844 + HEADER_TYPE_PPPMUX_SUBFRAME,
101845 + HEADER_TYPE_L2TPv2,
101846 + HEADER_TYPE_L2TPv3_CTRL,
101847 + HEADER_TYPE_L2TPv3_SESS,
101848 + HEADER_TYPE_LLC,
101849 + HEADER_TYPE_LLC_SNAP,
101850 + HEADER_TYPE_NLPID,
101851 + HEADER_TYPE_SNAP,
101852 + HEADER_TYPE_MPLS,
101853 + HEADER_TYPE_IPSEC_AH,
101854 + HEADER_TYPE_IPSEC_ESP,
101855 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
101856 + HEADER_TYPE_MACSEC,
101857 + HEADER_TYPE_GRE,
101858 + HEADER_TYPE_MINENCAP,
101859 + HEADER_TYPE_DCCP,
101860 + HEADER_TYPE_ICMP,
101861 + HEADER_TYPE_IGMP,
101862 + HEADER_TYPE_ARP,
101863 + HEADER_TYPE_CAPWAP,
101864 + HEADER_TYPE_CAPWAP_DTLS,
101865 + HEADER_TYPE_RFC2684,
101866 + HEADER_TYPE_USER_DEFINED_L2,
101867 + HEADER_TYPE_USER_DEFINED_L3,
101868 + HEADER_TYPE_USER_DEFINED_L4,
101869 + HEADER_TYPE_USER_DEFINED_SHIM1,
101870 + HEADER_TYPE_USER_DEFINED_SHIM2,
101871 + MAX_HEADER_TYPE_COUNT
101872 +} e_NetHeaderType;
101873 +
101874 +
101875 +#endif /* __NET_EXT_H */
101876 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101877 new file mode 100644
101878 index 00000000..d91e6fdd
101879 --- /dev/null
101880 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101881 @@ -0,0 +1,48 @@
101882 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101883 + * All rights reserved.
101884 + *
101885 + * Redistribution and use in source and binary forms, with or without
101886 + * modification, are permitted provided that the following conditions are met:
101887 + * * Redistributions of source code must retain the above copyright
101888 + * notice, this list of conditions and the following disclaimer.
101889 + * * Redistributions in binary form must reproduce the above copyright
101890 + * notice, this list of conditions and the following disclaimer in the
101891 + * documentation and/or other materials provided with the distribution.
101892 + * * Neither the name of Freescale Semiconductor nor the
101893 + * names of its contributors may be used to endorse or promote products
101894 + * derived from this software without specific prior written permission.
101895 + *
101896 + *
101897 + * ALTERNATIVELY, this software may be distributed under the terms of the
101898 + * GNU General Public License ("GPL") as published by the Free Software
101899 + * Foundation, either version 2 of that License or (at your option) any
101900 + * later version.
101901 + *
101902 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101903 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101904 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101905 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101906 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101907 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101908 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101909 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101910 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101911 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101912 + */
101913 +
101914 +
101915 +/**************************************************************************//**
101916 + @File std_ext.h
101917 +
101918 + @Description General Standard Definitions
101919 +*//***************************************************************************/
101920 +
101921 +#ifndef __STD_EXT_H
101922 +#define __STD_EXT_H
101923 +
101924 +
101925 +#include "types_ext.h"
101926 +#include "ncsw_ext.h"
101927 +
101928 +
101929 +#endif /* __STD_EXT_H */
101930 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101931 new file mode 100644
101932 index 00000000..3c8bb0a0
101933 --- /dev/null
101934 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101935 @@ -0,0 +1,49 @@
101936 +/*
101937 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101938 + *
101939 + * Redistribution and use in source and binary forms, with or without
101940 + * modification, are permitted provided that the following conditions are met:
101941 + * * Redistributions of source code must retain the above copyright
101942 + * notice, this list of conditions and the following disclaimer.
101943 + * * Redistributions in binary form must reproduce the above copyright
101944 + * notice, this list of conditions and the following disclaimer in the
101945 + * documentation and/or other materials provided with the distribution.
101946 + * * Neither the name of Freescale Semiconductor nor the
101947 + * names of its contributors may be used to endorse or promote products
101948 + * derived from this software without specific prior written permission.
101949 + *
101950 + *
101951 + * ALTERNATIVELY, this software may be distributed under the terms of the
101952 + * GNU General Public License ("GPL") as published by the Free Software
101953 + * Foundation, either version 2 of that License or (at your option) any
101954 + * later version.
101955 + *
101956 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101957 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101958 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101959 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101960 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101961 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101962 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101963 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101964 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101965 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101966 + */
101967 +
101968 +
101969 +#ifndef __STDARG_EXT_H
101970 +#define __STDARG_EXT_H
101971 +
101972 +
101973 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101974 +#include <stdarg.h>
101975 +
101976 +#else
101977 +#include <stdarg.h>
101978 +
101979 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101980 +
101981 +#include "std_ext.h"
101982 +
101983 +
101984 +#endif /* __STDARG_EXT_H */
101985 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101986 new file mode 100644
101987 index 00000000..a47860cf
101988 --- /dev/null
101989 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101990 @@ -0,0 +1,162 @@
101991 +/*
101992 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101993 + *
101994 + * Redistribution and use in source and binary forms, with or without
101995 + * modification, are permitted provided that the following conditions are met:
101996 + * * Redistributions of source code must retain the above copyright
101997 + * notice, this list of conditions and the following disclaimer.
101998 + * * Redistributions in binary form must reproduce the above copyright
101999 + * notice, this list of conditions and the following disclaimer in the
102000 + * documentation and/or other materials provided with the distribution.
102001 + * * Neither the name of Freescale Semiconductor nor the
102002 + * names of its contributors may be used to endorse or promote products
102003 + * derived from this software without specific prior written permission.
102004 + *
102005 + *
102006 + * ALTERNATIVELY, this software may be distributed under the terms of the
102007 + * GNU General Public License ("GPL") as published by the Free Software
102008 + * Foundation, either version 2 of that License or (at your option) any
102009 + * later version.
102010 + *
102011 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102012 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102013 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102014 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102015 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102016 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102017 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102018 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102019 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102020 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102021 + */
102022 +
102023 +
102024 +
102025 +#ifndef __STDLIB_EXT_H
102026 +#define __STDLIB_EXT_H
102027 +
102028 +
102029 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
102030 +#include "stdarg_ext.h"
102031 +#include "std_ext.h"
102032 +
102033 +
102034 +/**
102035 + * strtoul - convert a string to an uint32_t
102036 + * @cp: The start of the string
102037 + * @endp: A pointer to the end of the parsed string will be placed here
102038 + * @base: The number base to use
102039 + */
102040 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
102041 +
102042 +/**
102043 + * strtol - convert a string to a int32_t
102044 + * @cp: The start of the string
102045 + * @endp: A pointer to the end of the parsed string will be placed here
102046 + * @base: The number base to use
102047 + */
102048 +long strtol(const char *cp,char **endp,uint32_t base);
102049 +
102050 +/**
102051 + * strtoull - convert a string to an uint64_t
102052 + * @cp: The start of the string
102053 + * @endp: A pointer to the end of the parsed string will be placed here
102054 + * @base: The number base to use
102055 + */
102056 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
102057 +
102058 +/**
102059 + * strtoll - convert a string to a int64 long
102060 + * @cp: The start of the string
102061 + * @endp: A pointer to the end of the parsed string will be placed here
102062 + * @base: The number base to use
102063 + */
102064 +long long strtoll(const char *cp,char **endp,uint32_t base);
102065 +
102066 +/**
102067 + * atoi - convert a character to a int
102068 + * @s: The start of the string
102069 + */
102070 +int atoi(const char *s);
102071 +
102072 +/**
102073 + * strnlen - Find the length of a length-limited string
102074 + * @s: The string to be sized
102075 + * @count: The maximum number of bytes to search
102076 + */
102077 +size_t strnlen(const char * s, size_t count);
102078 +
102079 +/**
102080 + * strlen - Find the length of a string
102081 + * @s: The string to be sized
102082 + */
102083 +size_t strlen(const char * s);
102084 +
102085 +/**
102086 + * strtok - Split a string into tokens
102087 + * @s: The string to be searched
102088 + * @ct: The characters to search for
102089 + *
102090 + * WARNING: strtok is deprecated, use strsep instead.
102091 + */
102092 +char * strtok(char * s,const char * ct);
102093 +
102094 +/**
102095 + * strncpy - Copy a length-limited, %NUL-terminated string
102096 + * @dest: Where to copy the string to
102097 + * @src: Where to copy the string from
102098 + * @count: The maximum number of bytes to copy
102099 + *
102100 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
102101 + * However, the result is not %NUL-terminated if the source exceeds
102102 + * @count bytes.
102103 + */
102104 +char * strncpy(char * dest,const char *src,size_t count);
102105 +
102106 +/**
102107 + * strcpy - Copy a %NUL terminated string
102108 + * @dest: Where to copy the string to
102109 + * @src: Where to copy the string from
102110 + */
102111 +char * strcpy(char * dest,const char *src);
102112 +
102113 +/**
102114 + * vsscanf - Unformat a buffer into a list of arguments
102115 + * @buf: input buffer
102116 + * @fmt: format of buffer
102117 + * @args: arguments
102118 + */
102119 +int vsscanf(const char * buf, const char * fmt, va_list args);
102120 +
102121 +/**
102122 + * vsnprintf - Format a string and place it in a buffer
102123 + * @buf: The buffer to place the result into
102124 + * @size: The size of the buffer, including the trailing null space
102125 + * @fmt: The format string to use
102126 + * @args: Arguments for the format string
102127 + *
102128 + * Call this function if you are already dealing with a va_list.
102129 + * You probably want snprintf instead.
102130 + */
102131 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
102132 +
102133 +/**
102134 + * vsprintf - Format a string and place it in a buffer
102135 + * @buf: The buffer to place the result into
102136 + * @fmt: The format string to use
102137 + * @args: Arguments for the format string
102138 + *
102139 + * Call this function if you are already dealing with a va_list.
102140 + * You probably want sprintf instead.
102141 + */
102142 +int vsprintf(char *buf, const char *fmt, va_list args);
102143 +
102144 +#else
102145 +#include <stdlib.h>
102146 +#include <stdio.h>
102147 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102148 +
102149 +#include "std_ext.h"
102150 +
102151 +
102152 +#endif /* __STDLIB_EXT_H */
102153 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
102154 new file mode 100644
102155 index 00000000..a5c6c7e0
102156 --- /dev/null
102157 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
102158 @@ -0,0 +1,56 @@
102159 +/*
102160 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102161 + *
102162 + * Redistribution and use in source and binary forms, with or without
102163 + * modification, are permitted provided that the following conditions are met:
102164 + * * Redistributions of source code must retain the above copyright
102165 + * notice, this list of conditions and the following disclaimer.
102166 + * * Redistributions in binary form must reproduce the above copyright
102167 + * notice, this list of conditions and the following disclaimer in the
102168 + * documentation and/or other materials provided with the distribution.
102169 + * * Neither the name of Freescale Semiconductor nor the
102170 + * names of its contributors may be used to endorse or promote products
102171 + * derived from this software without specific prior written permission.
102172 + *
102173 + *
102174 + * ALTERNATIVELY, this software may be distributed under the terms of the
102175 + * GNU General Public License ("GPL") as published by the Free Software
102176 + * Foundation, either version 2 of that License or (at your option) any
102177 + * later version.
102178 + *
102179 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102180 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102181 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102182 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102183 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102184 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102185 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102186 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102187 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102188 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102189 + */
102190 +
102191 +
102192 +#ifndef __STRING_EXT_H
102193 +#define __STRING_EXT_H
102194 +
102195 +
102196 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102197 +#include <linux/kernel.h>
102198 +#include <linux/string.h>
102199 +extern char * strtok ( char * str, const char * delimiters );
102200 +
102201 +#elif defined(__KERNEL__)
102202 +#include "linux/types.h"
102203 +#include "linux/posix_types.h"
102204 +#include "linux/string.h"
102205 +
102206 +#else
102207 +#include <string.h>
102208 +
102209 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102210 +
102211 +#include "std_ext.h"
102212 +
102213 +
102214 +#endif /* __STRING_EXT_H */
102215 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
102216 new file mode 100644
102217 index 00000000..8c87edb7
102218 --- /dev/null
102219 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
102220 @@ -0,0 +1,62 @@
102221 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102222 + * All rights reserved.
102223 + *
102224 + * Redistribution and use in source and binary forms, with or without
102225 + * modification, are permitted provided that the following conditions are met:
102226 + * * Redistributions of source code must retain the above copyright
102227 + * notice, this list of conditions and the following disclaimer.
102228 + * * Redistributions in binary form must reproduce the above copyright
102229 + * notice, this list of conditions and the following disclaimer in the
102230 + * documentation and/or other materials provided with the distribution.
102231 + * * Neither the name of Freescale Semiconductor nor the
102232 + * names of its contributors may be used to endorse or promote products
102233 + * derived from this software without specific prior written permission.
102234 + *
102235 + *
102236 + * ALTERNATIVELY, this software may be distributed under the terms of the
102237 + * GNU General Public License ("GPL") as published by the Free Software
102238 + * Foundation, either version 2 of that License or (at your option) any
102239 + * later version.
102240 + *
102241 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102242 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102243 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102244 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102245 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102246 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102247 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102248 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102249 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102250 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102251 + */
102252 +
102253 +
102254 +/**************************************************************************//**
102255 + @File types_ext.h
102256 +
102257 + @Description General types Standard Definitions
102258 +*//***************************************************************************/
102259 +
102260 +#ifndef __TYPES_EXT_H
102261 +#define __TYPES_EXT_H
102262 +
102263 +#if defined(NCSW_LINUX)
102264 +#include "types_linux.h"
102265 +
102266 +#elif defined(NCSW_VXWORKS)
102267 +#include "types_vxworks.h"
102268 +
102269 +#elif defined(__GNUC__) && defined(__cplusplus)
102270 +#include "types_bb_gpp.h"
102271 +
102272 +#elif defined(__GNUC__)
102273 +#include "types_bb_gcc.h"
102274 +
102275 +#elif defined(__ghs__)
102276 +#include "types_ghs.h"
102277 +
102278 +#else
102279 +#include "types_dflt.h"
102280 +#endif /* defined (__ROCOO__) */
102281 +
102282 +#endif /* __TYPES_EXT_H */
102283 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
102284 new file mode 100644
102285 index 00000000..8e81094b
102286 --- /dev/null
102287 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
102288 @@ -0,0 +1,56 @@
102289 +/*
102290 + * Copyright 2012 Freescale Semiconductor Inc.
102291 + *
102292 + * Redistribution and use in source and binary forms, with or without
102293 + * modification, are permitted provided that the following conditions are met:
102294 + * * Redistributions of source code must retain the above copyright
102295 + * notice, this list of conditions and the following disclaimer.
102296 + * * Redistributions in binary form must reproduce the above copyright
102297 + * notice, this list of conditions and the following disclaimer in the
102298 + * documentation and/or other materials provided with the distribution.
102299 + * * Neither the name of Freescale Semiconductor nor the
102300 + * names of its contributors may be used to endorse or promote products
102301 + * derived from this software without specific prior written permission.
102302 + *
102303 + *
102304 + * ALTERNATIVELY, this software may be distributed under the terms of the
102305 + * GNU General Public License ("GPL") as published by the Free Software
102306 + * Foundation, either version 2 of that License or (at your option) any
102307 + * later version.
102308 + *
102309 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102310 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102311 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102312 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102313 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102314 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102315 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102316 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102317 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102318 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102319 + */
102320 +
102321 +
102322 +/**************************************************************************//**
102323 + @File debug_ext.h
102324 +
102325 + @Description Debug mode definitions.
102326 +*//***************************************************************************/
102327 +
102328 +#ifndef __XX_COMMON_H
102329 +#define __XX_COMMON_H
102330 +
102331 +/*****************************************************************************
102332 + * UNIFIED MODULE CODES
102333 + *****************************************************************************/
102334 +#define MODULE_UNKNOWN 0x00000000
102335 +#define MODULE_FM 0x00010000
102336 +#define MODULE_FM_MURAM 0x00020000
102337 +#define MODULE_FM_PCD 0x00030000
102338 +#define MODULE_FM_RTC 0x00040000
102339 +#define MODULE_FM_MAC 0x00050000
102340 +#define MODULE_FM_PORT 0x00060000
102341 +#define MODULE_MM 0x00070000
102342 +#define MODULE_FM_SP 0x00080000
102343 +#define MODULE_FM_MACSEC 0x00090000
102344 +#endif /* __XX_COMMON_H */
102345 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102346 new file mode 100644
102347 index 00000000..21b62d0a
102348 --- /dev/null
102349 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102350 @@ -0,0 +1,791 @@
102351 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102352 + * All rights reserved.
102353 + *
102354 + * Redistribution and use in source and binary forms, with or without
102355 + * modification, are permitted provided that the following conditions are met:
102356 + * * Redistributions of source code must retain the above copyright
102357 + * notice, this list of conditions and the following disclaimer.
102358 + * * Redistributions in binary form must reproduce the above copyright
102359 + * notice, this list of conditions and the following disclaimer in the
102360 + * documentation and/or other materials provided with the distribution.
102361 + * * Neither the name of Freescale Semiconductor nor the
102362 + * names of its contributors may be used to endorse or promote products
102363 + * derived from this software without specific prior written permission.
102364 + *
102365 + *
102366 + * ALTERNATIVELY, this software may be distributed under the terms of the
102367 + * GNU General Public License ("GPL") as published by the Free Software
102368 + * Foundation, either version 2 of that License or (at your option) any
102369 + * later version.
102370 + *
102371 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102372 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102373 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102374 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102375 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102376 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102377 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102378 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102379 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102380 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102381 + */
102382 +
102383 +
102384 +/**************************************************************************//**
102385 + @File xx_ext.h
102386 +
102387 + @Description Prototypes, externals and typedefs for system-supplied
102388 + (external) routines
102389 +*//***************************************************************************/
102390 +
102391 +#ifndef __XX_EXT_H
102392 +#define __XX_EXT_H
102393 +
102394 +#include "std_ext.h"
102395 +#include "xx_common.h"
102396 +#include "part_ext.h"
102397 +
102398 +
102399 +
102400 +/**************************************************************************//**
102401 + @Group xx_id XX Interface (System call hooks)
102402 +
102403 + @Description Prototypes, externals and typedefs for system-supplied
102404 + (external) routines
102405 +
102406 + @{
102407 +*//***************************************************************************/
102408 +
102409 +#ifdef DEBUG_XX_MALLOC
102410 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
102411 +
102412 +void * XX_MallocSmartDebug(uint32_t size,
102413 + int memPartitionId,
102414 + uint32_t alignment,
102415 + char *fname,
102416 + int line);
102417 +
102418 +#define XX_Malloc(sz) \
102419 + XX_MallocDebug((sz), __FILE__, __LINE__)
102420 +
102421 +#define XX_MallocSmart(sz, memt, al) \
102422 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
102423 +
102424 +#else /* not DEBUG_XX_MALLOC */
102425 +/**************************************************************************//**
102426 + @Function XX_Malloc
102427 +
102428 + @Description allocates contiguous block of memory.
102429 +
102430 + @Param[in] size - Number of bytes to allocate.
102431 +
102432 + @Return The address of the newly allocated block on success, NULL on failure.
102433 +*//***************************************************************************/
102434 +void * XX_Malloc(uint32_t size);
102435 +
102436 +/**************************************************************************//**
102437 + @Function XX_MallocSmart
102438 +
102439 + @Description Allocates contiguous block of memory in a specified
102440 + alignment and from the specified segment.
102441 +
102442 + @Param[in] size - Number of bytes to allocate.
102443 + @Param[in] memPartitionId - Memory partition ID; The value zero must
102444 + be mapped to the default heap partition.
102445 + @Param[in] alignment - Required memory alignment (in bytes).
102446 +
102447 + @Return The address of the newly allocated block on success, NULL on failure.
102448 +*//***************************************************************************/
102449 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
102450 +#endif /* not DEBUG_XX_MALLOC */
102451 +
102452 +/**************************************************************************//**
102453 + @Function XX_FreeSmart
102454 +
102455 + @Description Frees the memory block pointed to by "p".
102456 + Only for memory allocated by XX_MallocSmart
102457 +
102458 + @Param[in] p_Memory - pointer to the memory block.
102459 +
102460 + @Return None.
102461 +*//***************************************************************************/
102462 +void XX_FreeSmart(void *p_Memory);
102463 +
102464 +/**************************************************************************//**
102465 + @Function XX_Free
102466 +
102467 + @Description frees the memory block pointed to by "p".
102468 +
102469 + @Param[in] p_Memory - pointer to the memory block.
102470 +
102471 + @Return None.
102472 +*//***************************************************************************/
102473 +void XX_Free(void *p_Memory);
102474 +
102475 +/**************************************************************************//**
102476 + @Function XX_Print
102477 +
102478 + @Description print a string.
102479 +
102480 + @Param[in] str - string to print.
102481 +
102482 + @Return None.
102483 +*//***************************************************************************/
102484 +void XX_Print(char *str, ...);
102485 +
102486 +/**************************************************************************//**
102487 + @Function XX_SetIntr
102488 +
102489 + @Description Set an interrupt service routine for a specific interrupt source.
102490 +
102491 + @Param[in] irq - Interrupt ID (system-specific number).
102492 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
102493 + @Param[in] handle - The argument for the user callback routine.
102494 +
102495 + @Return E_OK on success; error code otherwise..
102496 +*//***************************************************************************/
102497 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
102498 +
102499 +/**************************************************************************//**
102500 + @Function XX_FreeIntr
102501 +
102502 + @Description Free a specific interrupt and a specific callback routine.
102503 +
102504 + @Param[in] irq - Interrupt ID (system-specific number).
102505 +
102506 + @Return E_OK on success; error code otherwise..
102507 +*//***************************************************************************/
102508 +t_Error XX_FreeIntr(int irq);
102509 +
102510 +/**************************************************************************//**
102511 + @Function XX_EnableIntr
102512 +
102513 + @Description Enable a specific interrupt.
102514 +
102515 + @Param[in] irq - Interrupt ID (system-specific number).
102516 +
102517 + @Return E_OK on success; error code otherwise..
102518 +*//***************************************************************************/
102519 +t_Error XX_EnableIntr(int irq);
102520 +
102521 +/**************************************************************************//**
102522 + @Function XX_DisableIntr
102523 +
102524 + @Description Disable a specific interrupt.
102525 +
102526 + @Param[in] irq - Interrupt ID (system-specific number).
102527 +
102528 + @Return E_OK on success; error code otherwise..
102529 +*//***************************************************************************/
102530 +t_Error XX_DisableIntr(int irq);
102531 +
102532 +/**************************************************************************//**
102533 + @Function XX_DisableAllIntr
102534 +
102535 + @Description Disable all interrupts by masking them at the CPU.
102536 +
102537 + @Return A value that represents the interrupts state before the
102538 + operation, and should be passed to the matching
102539 + XX_RestoreAllIntr() call.
102540 +*//***************************************************************************/
102541 +uint32_t XX_DisableAllIntr(void);
102542 +
102543 +/**************************************************************************//**
102544 + @Function XX_RestoreAllIntr
102545 +
102546 + @Description Restore previous state of interrupts level at the CPU.
102547 +
102548 + @Param[in] flags - A value that represents the interrupts state to restore,
102549 + as returned by the matching call for XX_DisableAllIntr().
102550 +
102551 + @Return None.
102552 +*//***************************************************************************/
102553 +void XX_RestoreAllIntr(uint32_t flags);
102554 +
102555 +
102556 +/**************************************************************************//**
102557 + @Function XX_Exit
102558 +
102559 + @Description Stop execution and report status (where it is applicable)
102560 +
102561 + @Param[in] status - exit status
102562 +*//***************************************************************************/
102563 +void XX_Exit(int status);
102564 +
102565 +
102566 +/*****************************************************************************/
102567 +/* Tasklet Service Routines */
102568 +/*****************************************************************************/
102569 +typedef t_Handle t_TaskletHandle;
102570 +
102571 +/**************************************************************************//**
102572 + @Function XX_InitTasklet
102573 +
102574 + @Description Create and initialize a tasklet object.
102575 +
102576 + @Param[in] routine - A routine to be ran as a tasklet.
102577 + @Param[in] data - An argument to pass to the tasklet.
102578 +
102579 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102580 +*//***************************************************************************/
102581 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102582 +
102583 +/**************************************************************************//**
102584 + @Function XX_FreeTasklet
102585 +
102586 + @Description Free a tasklet object.
102587 +
102588 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102589 +
102590 + @Return None.
102591 +*//***************************************************************************/
102592 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102593 +
102594 +/**************************************************************************//**
102595 + @Function XX_ScheduleTask
102596 +
102597 + @Description Schedule a tasklet object.
102598 +
102599 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102600 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102601 + the immediate queue or on the delayed one.
102602 +
102603 + @Return 0 - on success. Error code - otherwise.
102604 +*//***************************************************************************/
102605 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102606 +
102607 +/**************************************************************************//**
102608 + @Function XX_FlushScheduledTasks
102609 +
102610 + @Description Flush all tasks there are in the scheduled tasks queue.
102611 +
102612 + @Return None.
102613 +*//***************************************************************************/
102614 +void XX_FlushScheduledTasks(void);
102615 +
102616 +/**************************************************************************//**
102617 + @Function XX_TaskletIsQueued
102618 +
102619 + @Description Check if task is queued.
102620 +
102621 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102622 +
102623 + @Return 1 - task is queued. 0 - otherwise.
102624 +*//***************************************************************************/
102625 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102626 +
102627 +/**************************************************************************//**
102628 + @Function XX_SetTaskletData
102629 +
102630 + @Description Set data to a scheduled task. Used to change data of already
102631 + scheduled task.
102632 +
102633 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102634 + @Param[in] data - Data to be set.
102635 +*//***************************************************************************/
102636 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102637 +
102638 +/**************************************************************************//**
102639 + @Function XX_GetTaskletData
102640 +
102641 + @Description Get the data of scheduled task.
102642 +
102643 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102644 +
102645 + @Return handle to the data of the task.
102646 +*//***************************************************************************/
102647 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102648 +
102649 +/**************************************************************************//**
102650 + @Function XX_BottomHalf
102651 +
102652 + @Description Bottom half implementation, invoked by the interrupt handler.
102653 +
102654 + This routine handles all bottom-half tasklets with interrupts
102655 + enabled.
102656 +
102657 + @Return None.
102658 +*//***************************************************************************/
102659 +void XX_BottomHalf(void);
102660 +
102661 +
102662 +/*****************************************************************************/
102663 +/* Spinlock Service Routines */
102664 +/*****************************************************************************/
102665 +
102666 +/**************************************************************************//**
102667 + @Function XX_InitSpinlock
102668 +
102669 + @Description Creates a spinlock.
102670 +
102671 + @Return Spinlock handle is returned on success; NULL otherwise.
102672 +*//***************************************************************************/
102673 +t_Handle XX_InitSpinlock(void);
102674 +
102675 +/**************************************************************************//**
102676 + @Function XX_FreeSpinlock
102677 +
102678 + @Description Frees the memory allocated for the spinlock creation.
102679 +
102680 + @Param[in] h_Spinlock - A handle to a spinlock.
102681 +
102682 + @Return None.
102683 +*//***************************************************************************/
102684 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102685 +
102686 +/**************************************************************************//**
102687 + @Function XX_LockSpinlock
102688 +
102689 + @Description Locks a spinlock.
102690 +
102691 + @Param[in] h_Spinlock - A handle to a spinlock.
102692 +
102693 + @Return None.
102694 +*//***************************************************************************/
102695 +void XX_LockSpinlock(t_Handle h_Spinlock);
102696 +
102697 +/**************************************************************************//**
102698 + @Function XX_UnlockSpinlock
102699 +
102700 + @Description Unlocks a spinlock.
102701 +
102702 + @Param[in] h_Spinlock - A handle to a spinlock.
102703 +
102704 + @Return None.
102705 +*//***************************************************************************/
102706 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102707 +
102708 +/**************************************************************************//**
102709 + @Function XX_LockIntrSpinlock
102710 +
102711 + @Description Locks a spinlock (interrupt safe).
102712 +
102713 + @Param[in] h_Spinlock - A handle to a spinlock.
102714 +
102715 + @Return A value that represents the interrupts state before the
102716 + operation, and should be passed to the matching
102717 + XX_UnlockIntrSpinlock() call.
102718 +*//***************************************************************************/
102719 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102720 +
102721 +/**************************************************************************//**
102722 + @Function XX_UnlockIntrSpinlock
102723 +
102724 + @Description Unlocks a spinlock (interrupt safe).
102725 +
102726 + @Param[in] h_Spinlock - A handle to a spinlock.
102727 + @Param[in] intrFlags - A value that represents the interrupts state to
102728 + restore, as returned by the matching call for
102729 + XX_LockIntrSpinlock().
102730 +
102731 + @Return None.
102732 +*//***************************************************************************/
102733 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102734 +
102735 +
102736 +/*****************************************************************************/
102737 +/* Timers Service Routines */
102738 +/*****************************************************************************/
102739 +
102740 +/**************************************************************************//**
102741 + @Function XX_CurrentTime
102742 +
102743 + @Description Returns current system time.
102744 +
102745 + @Return Current system time (in milliseconds).
102746 +*//***************************************************************************/
102747 +uint32_t XX_CurrentTime(void);
102748 +
102749 +/**************************************************************************//**
102750 + @Function XX_CreateTimer
102751 +
102752 + @Description Creates a timer.
102753 +
102754 + @Return Timer handle is returned on success; NULL otherwise.
102755 +*//***************************************************************************/
102756 +t_Handle XX_CreateTimer(void);
102757 +
102758 +/**************************************************************************//**
102759 + @Function XX_FreeTimer
102760 +
102761 + @Description Frees the memory allocated for the timer creation.
102762 +
102763 + @Param[in] h_Timer - A handle to a timer.
102764 +
102765 + @Return None.
102766 +*//***************************************************************************/
102767 +void XX_FreeTimer(t_Handle h_Timer);
102768 +
102769 +/**************************************************************************//**
102770 + @Function XX_StartTimer
102771 +
102772 + @Description Starts a timer.
102773 +
102774 + The user can select to start the timer as periodic timer or as
102775 + one-shot timer. The user should provide a callback routine that
102776 + will be called when the timer expires.
102777 +
102778 + @Param[in] h_Timer - A handle to a timer.
102779 + @Param[in] msecs - Timer expiration period (in milliseconds).
102780 + @Param[in] periodic - TRUE for a periodic timer;
102781 + FALSE for a one-shot timer..
102782 + @Param[in] f_TimerExpired - A callback routine to be called when the
102783 + timer expires.
102784 + @Param[in] h_Arg - The argument to pass in the timer-expired
102785 + callback routine.
102786 +
102787 + @Return None.
102788 +*//***************************************************************************/
102789 +void XX_StartTimer(t_Handle h_Timer,
102790 + uint32_t msecs,
102791 + bool periodic,
102792 + void (*f_TimerExpired)(t_Handle h_Arg),
102793 + t_Handle h_Arg);
102794 +
102795 +/**************************************************************************//**
102796 + @Function XX_StopTimer
102797 +
102798 + @Description Frees the memory allocated for the timer creation.
102799 +
102800 + @Param[in] h_Timer - A handle to a timer.
102801 +
102802 + @Return None.
102803 +*//***************************************************************************/
102804 +void XX_StopTimer(t_Handle h_Timer);
102805 +
102806 +/**************************************************************************//**
102807 + @Function XX_ModTimer
102808 +
102809 + @Description Updates the expiration time of a timer.
102810 +
102811 + This routine adds the given time to the current system time,
102812 + and sets this value as the new expiration time of the timer.
102813 +
102814 + @Param[in] h_Timer - A handle to a timer.
102815 + @Param[in] msecs - The new interval until timer expiration
102816 + (in milliseconds).
102817 +
102818 + @Return None.
102819 +*//***************************************************************************/
102820 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102821 +
102822 +/**************************************************************************//**
102823 + @Function XX_Sleep
102824 +
102825 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102826 +
102827 + @Param[in] msecs - The requested sleep time (in milliseconds).
102828 +
102829 + @Return Zero if the requested time has elapsed; Otherwise, the value
102830 + returned will be the unslept amount) in milliseconds.
102831 +
102832 + @Cautions This routine enables interrupts during its wait time.
102833 +*//***************************************************************************/
102834 +uint32_t XX_Sleep(uint32_t msecs);
102835 +
102836 +/**************************************************************************//**
102837 + @Function XX_UDelay
102838 +
102839 + @Description Busy-wait until the desired time (in microseconds) has passed.
102840 +
102841 + @Param[in] usecs - The requested delay time (in microseconds).
102842 +
102843 + @Return None.
102844 +
102845 + @Cautions It is highly unrecommended to call this routine during interrupt
102846 + time, because the system time may not be updated properly during
102847 + the delay loop. The behavior of this routine during interrupt
102848 + time is unexpected.
102849 +*//***************************************************************************/
102850 +void XX_UDelay(uint32_t usecs);
102851 +
102852 +
102853 +/*****************************************************************************/
102854 +/* Other Service Routines */
102855 +/*****************************************************************************/
102856 +
102857 +/**************************************************************************//**
102858 + @Function XX_PhysToVirt
102859 +
102860 + @Description Translates a physical address to the matching virtual address.
102861 +
102862 + @Param[in] addr - The physical address to translate.
102863 +
102864 + @Return Virtual address.
102865 +*//***************************************************************************/
102866 +void * XX_PhysToVirt(physAddress_t addr);
102867 +
102868 +/**************************************************************************//**
102869 + @Function XX_VirtToPhys
102870 +
102871 + @Description Translates a virtual address to the matching physical address.
102872 +
102873 + @Param[in] addr - The virtual address to translate.
102874 +
102875 + @Return Physical address.
102876 +*//***************************************************************************/
102877 +physAddress_t XX_VirtToPhys(void *addr);
102878 +
102879 +
102880 +/**************************************************************************//**
102881 + @Group xx_ipc XX Inter-Partition-Communication API
102882 +
102883 + @Description The following API is to be used when working with multiple
102884 + partitions configuration.
102885 +
102886 + @{
102887 +*//***************************************************************************/
102888 +
102889 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
102890 + The IPC service can use this constant to limit
102891 + the storage space for IPC endpoint names. */
102892 +
102893 +
102894 +/**************************************************************************//**
102895 + @Function t_IpcMsgCompletion
102896 +
102897 + @Description Callback function used upon IPC non-blocking transaction completion
102898 + to return message buffer to the caller and to forward reply if available.
102899 +
102900 + This callback function may be attached by the source endpoint to any outgoing
102901 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
102902 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
102903 + the IPC service invokes this callback routine to return the message buffer to the sender
102904 + and to provide the received reply, if requested.
102905 +
102906 + User provides this function. Driver invokes it.
102907 +
102908 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
102909 + in the XX_IpcSendMessage() function; This handle is typically used to point
102910 + to the internal data structure of the source endpoint.
102911 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
102912 + The source endpoint can free (or reuse) this buffer when message
102913 + completion callback is called.
102914 + @Param[in] p_Reply - Pointer to (received) reply buffer;
102915 + This pointer is the same as was provided by the source endpoint in
102916 + XX_IpcSendMessage().
102917 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
102918 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
102919 + timeout.
102920 +
102921 + @Return None
102922 + *//***************************************************************************/
102923 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
102924 + uint8_t *p_Msg,
102925 + uint8_t *p_Reply,
102926 + uint32_t replyLength,
102927 + t_Error status);
102928 +
102929 +/**************************************************************************//**
102930 + @Function t_IpcMsgHandler
102931 +
102932 + @Description Callback function used as IPC message handler.
102933 +
102934 + The IPC service invokes message handlers for each IPC message received.
102935 + The actual function pointer should be registered by each destination endpoint
102936 + via the XX_IpcRegisterMsgHandler() routine.
102937 +
102938 + User provides this function. Driver invokes it.
102939 +
102940 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
102941 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
102942 + typically used to point to the internal data structure of the destination
102943 + endpoint.
102944 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
102945 + @Param[in] msgLength - Length (in bytes) of message data.
102946 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
102947 + by the IPC service;
102948 + The reply buffer is allocated by the IPC service with size equals to the
102949 + replyLength parameter provided in message handler registration (see
102950 + XX_IpcRegisterMsgHandler() function);
102951 + If replyLength was initially specified as zero during message handler registration,
102952 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
102953 + The IPC service is also responsible for freeing the reply buffer after the
102954 + reply has been sent or dismissed.
102955 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102956 + [In] equals the replyLength parameter provided in message handler
102957 + registration (see XX_IpcRegisterMsgHandler() function), and
102958 + [Out] should be updated by message handler to the actual reply length; if
102959 + this value is set to zero, the IPC service must assume that a reply should
102960 + not be sent;
102961 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
102962 +
102963 + @Return E_OK on success; Error code otherwise.
102964 + *//***************************************************************************/
102965 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
102966 + uint8_t *p_Msg,
102967 + uint32_t msgLength,
102968 + uint8_t *p_Reply,
102969 + uint32_t *p_ReplyLength);
102970 +
102971 +/**************************************************************************//**
102972 + @Function XX_IpcRegisterMsgHandler
102973 +
102974 + @Description IPC mailbox registration.
102975 +
102976 + This function is used for registering an IPC message handler in the IPC service.
102977 + This function is called by each destination endpoint to indicate that it is ready
102978 + to handle incoming messages. The IPC service invokes the message handler upon receiving
102979 + a message addressed to the specified destination endpoint.
102980 +
102981 + @Param[in] addr - The address name string associated with the destination endpoint;
102982 + This address must be unique across the IPC service domain to ensure
102983 + correct message routing.
102984 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
102985 + message; invoked by the IPC service upon receiving a message
102986 + addressed to the destination endpoint specified by the addr
102987 + parameter.
102988 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
102989 + to f_MsgHandler callback function.
102990 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
102991 + may generate; the IPC service provides the message handler with buffer
102992 + for reply according to the length specified here (refer also to the description
102993 + of #t_IpcMsgHandler callback function type);
102994 + This size shall be zero if the message handler never generates replies.
102995 +
102996 + @Return E_OK on success; Error code otherwise.
102997 +*//***************************************************************************/
102998 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102999 + t_IpcMsgHandler *f_MsgHandler,
103000 + t_Handle h_Module,
103001 + uint32_t replyLength);
103002 +
103003 +/**************************************************************************//**
103004 + @Function XX_IpcUnregisterMsgHandler
103005 +
103006 + @Description Release IPC mailbox routine.
103007 +
103008 + This function is used for unregistering an IPC message handler from the IPC service.
103009 + This function is called by each destination endpoint to indicate that it is no longer
103010 + capable of handling incoming messages.
103011 +
103012 + @Param[in] addr - The address name string associated with the destination endpoint;
103013 + This address is the same as was used when the message handler was
103014 + registered via XX_IpcRegisterMsgHandler().
103015 +
103016 + @Return E_OK on success; Error code otherwise.
103017 +*//***************************************************************************/
103018 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
103019 +
103020 +/**************************************************************************//**
103021 + @Function XX_IpcInitSession
103022 +
103023 + @Description This function is used for creating an IPC session between the source endpoint
103024 + and the destination endpoint.
103025 +
103026 + The actual implementation and representation of a session is left for the IPC service.
103027 + The function returns an abstract handle to the created session. This handle shall be used
103028 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
103029 + The IPC service assumes that before this function is called, no messages are sent from
103030 + the specified source endpoint to the specified destination endpoint.
103031 +
103032 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
103033 + as described below.
103034 +
103035 + @par Connection-Oriented Approach
103036 +
103037 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
103038 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
103039 + and a destination-to-source channel for replies. The returned handle should represent the internal
103040 + representation of these channels.
103041 +
103042 + @par Connectionless Approach
103043 +
103044 + The IPC service may implement a session in a connectionless approach - when this function is called, the
103045 + IPC service should not perform any particular steps, but it must store the pair of source and destination
103046 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
103047 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
103048 + through the connectionless medium.
103049 +
103050 + @Param[in] destAddr - The address name string associated with the destination endpoint.
103051 + @Param[in] srcAddr - The address name string associated with the source endpoint.
103052 +
103053 + @Return Abstract handle to the initialized session, or NULL on error.
103054 +*//***************************************************************************/
103055 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
103056 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
103057 +
103058 +/**************************************************************************//**
103059 + @Function XX_IpcFreeSession
103060 +
103061 + @Description This function is used for terminating an existing IPC session between a source endpoint
103062 + and a destination endpoint.
103063 +
103064 + The IPC service assumes that after this function is called, no messages shall be sent from
103065 + the associated source endpoint to the associated destination endpoint.
103066 +
103067 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
103068 + returned by the XX_IpcInitSession() function.
103069 +
103070 + @Return E_OK on success; Error code otherwise.
103071 +*//***************************************************************************/
103072 +t_Error XX_IpcFreeSession(t_Handle h_Session);
103073 +
103074 +/**************************************************************************//**
103075 + @Function XX_IpcSendMessage
103076 +
103077 + @Description IPC message send routine.
103078 +
103079 + This function may be used by a source endpoint to send an IPC message to a destination
103080 + endpoint. The source endpoint cannot send a message to the destination endpoint without
103081 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
103082 +
103083 + The source endpoint must provide the buffer pointer and length of the outgoing message.
103084 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
103085 + transaction is not considered complete by the IPC service until the reply has been received.
103086 + If the source endpoint does not provide a reply buffer, the transaction is considered
103087 + complete after the message has been sent. The source endpoint must keep the message (and
103088 + optional reply) buffers valid until the transaction is complete.
103089 +
103090 + @par Non-blocking mode
103091 +
103092 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
103093 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
103094 + message and an optional reply), the IPC service invokes this callback routine to return the message
103095 + buffer to the sender and to provide the received reply, if requested.
103096 +
103097 + @par Blocking mode
103098 +
103099 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
103100 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
103101 + was requested) the message has been sent.
103102 +
103103 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
103104 + returned by the XX_IpcInitSession() function.
103105 + @Param[in] p_Msg - Pointer to message buffer to send.
103106 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
103107 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
103108 + fills this buffer with the received reply data;
103109 + In blocking mode, the reply data must be valid when the function returns;
103110 + In non-blocking mode, the reply data is valid when f_Completion is called;
103111 + If this pointer is NULL, no reply is expected.
103112 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
103113 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
103114 + p_Reply, and
103115 + [Out] in non-blocking mode this value is updated by the IPC service to the
103116 + actual reply length (in bytes).
103117 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
103118 + The completion callback is invoked by the IPC service upon
103119 + completion of the IPC transaction (consisting of a message and an optional
103120 + reply);
103121 + If this pointer is NULL, the function is expected to block until the IPC
103122 + transaction is complete.
103123 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
103124 + callback function as the first argument.
103125 +
103126 + @Return E_OK on success; Error code otherwise.
103127 +*//***************************************************************************/
103128 +t_Error XX_IpcSendMessage(t_Handle h_Session,
103129 + uint8_t *p_Msg,
103130 + uint32_t msgLength,
103131 + uint8_t *p_Reply,
103132 + uint32_t *p_ReplyLength,
103133 + t_IpcMsgCompletion *f_Completion,
103134 + t_Handle h_Arg);
103135 +
103136 +
103137 +/** @} */ /* end of xx_ipc group */
103138 +/** @} */ /* end of xx_id group */
103139 +
103140 +
103141 +#endif /* __XX_EXT_H */
103142 diff --git a/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
103143 new file mode 100644
103144 index 00000000..c3a5a623
103145 --- /dev/null
103146 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
103147 @@ -0,0 +1,56 @@
103148 +/*
103149 + * Copyright 2012 Freescale Semiconductor Inc.
103150 + *
103151 + * Redistribution and use in source and binary forms, with or without
103152 + * modification, are permitted provided that the following conditions are met:
103153 + * * Redistributions of source code must retain the above copyright
103154 + * notice, this list of conditions and the following disclaimer.
103155 + * * Redistributions in binary form must reproduce the above copyright
103156 + * notice, this list of conditions and the following disclaimer in the
103157 + * documentation and/or other materials provided with the distribution.
103158 + * * Neither the name of Freescale Semiconductor nor the
103159 + * names of its contributors may be used to endorse or promote products
103160 + * derived from this software without specific prior written permission.
103161 + *
103162 + *
103163 + * ALTERNATIVELY, this software may be distributed under the terms of the
103164 + * GNU General Public License ("GPL") as published by the Free Software
103165 + * Foundation, either version 2 of that License or (at your option) any
103166 + * later version.
103167 + *
103168 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103169 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103170 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103171 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103172 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103173 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103174 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103175 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103176 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103177 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103178 + */
103179 +
103180 +#ifndef __dflags_h
103181 +#define __dflags_h
103182 +
103183 +
103184 +#define NCSW_LINUX
103185 +
103186 +#define LS1043
103187 +
103188 +#define DEBUG_ERRORS 1
103189 +
103190 +#if defined(DEBUG)
103191 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103192 +
103193 +#define DEBUG_XX_MALLOC
103194 +#define DEBUG_MEM_LEAKS
103195 +
103196 +#else
103197 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103198 +#endif /* (DEBUG) */
103199 +
103200 +#define REPORT_EVENTS 1
103201 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103202 +
103203 +#endif /* __dflags_h */
103204 diff --git a/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103205 new file mode 100644
103206 index 00000000..586f9c79
103207 --- /dev/null
103208 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103209 @@ -0,0 +1,53 @@
103210 +#
103211 +# Makefile config for the Freescale NetcommSW
103212 +#
103213 +NET_DPA = $(srctree)/drivers/net
103214 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
103215 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
103216 +
103217 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103218 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
103219 +endif
103220 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103221 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
103222 +endif
103223 +ifdef CONFIG_FMAN_V3H
103224 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
103225 +endif
103226 +ifdef CONFIG_FMAN_V3L
103227 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
103228 +endif
103229 +ifdef CONFIG_FMAN_ARM
103230 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
103231 +endif
103232 +
103233 +ccflags-y += -I$(DRV_DPA)/
103234 +ccflags-y += -I$(FMAN)/inc
103235 +ccflags-y += -I$(FMAN)/inc/cores
103236 +ccflags-y += -I$(FMAN)/inc/etc
103237 +ccflags-y += -I$(FMAN)/inc/Peripherals
103238 +ccflags-y += -I$(FMAN)/inc/flib
103239 +
103240 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103241 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
103242 +endif
103243 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103244 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
103245 +endif
103246 +ifdef CONFIG_FMAN_V3H
103247 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
103248 +endif
103249 +ifdef CONFIG_FMAN_V3L
103250 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
103251 +endif
103252 +ifdef CONFIG_FMAN_ARM
103253 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
103254 +endif
103255 +
103256 +ccflags-y += -I$(FMAN)/src/inc
103257 +ccflags-y += -I$(FMAN)/src/inc/system
103258 +ccflags-y += -I$(FMAN)/src/inc/wrapper
103259 +ccflags-y += -I$(FMAN)/src/inc/xx
103260 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
103261 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
103262 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
103263 diff --git a/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
103264 new file mode 100644
103265 index 00000000..b48819d7
103266 --- /dev/null
103267 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
103268 @@ -0,0 +1,65 @@
103269 +/*
103270 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103271 + *
103272 + * Redistribution and use in source and binary forms, with or without
103273 + * modification, are permitted provided that the following conditions are met:
103274 + * * Redistributions of source code must retain the above copyright
103275 + * notice, this list of conditions and the following disclaimer.
103276 + * * Redistributions in binary form must reproduce the above copyright
103277 + * notice, this list of conditions and the following disclaimer in the
103278 + * documentation and/or other materials provided with the distribution.
103279 + * * Neither the name of Freescale Semiconductor nor the
103280 + * names of its contributors may be used to endorse or promote products
103281 + * derived from this software without specific prior written permission.
103282 + *
103283 + *
103284 + * ALTERNATIVELY, this software may be distributed under the terms of the
103285 + * GNU General Public License ("GPL") as published by the Free Software
103286 + * Foundation, either version 2 of that License or (at your option) any
103287 + * later version.
103288 + *
103289 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103290 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103291 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103292 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103293 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103294 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103295 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103296 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103297 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103298 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103299 + */
103300 +
103301 +#ifndef __dflags_h
103302 +#define __dflags_h
103303 +
103304 +
103305 +#define NCSW_LINUX
103306 +#if 0
103307 +#define DEBUG
103308 +#endif
103309 +
103310 +#define P1023
103311 +#define NCSW_PPC_CORE
103312 +
103313 +#define DEBUG_ERRORS 1
103314 +
103315 +#if defined(DEBUG)
103316 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103317 +
103318 +#define DEBUG_XX_MALLOC
103319 +#define DEBUG_MEM_LEAKS
103320 +
103321 +#else
103322 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103323 +#endif /* (DEBUG) */
103324 +
103325 +#define REPORT_EVENTS 1
103326 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103327 +
103328 +#ifdef CONFIG_P4080_SIM
103329 +#error "Do not define CONFIG_P4080_SIM..."
103330 +#endif
103331 +
103332 +
103333 +#endif /* __dflags_h */
103334 diff --git a/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103335 new file mode 100644
103336 index 00000000..74389742
103337 --- /dev/null
103338 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103339 @@ -0,0 +1,62 @@
103340 +/*
103341 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103342 + *
103343 + * Redistribution and use in source and binary forms, with or without
103344 + * modification, are permitted provided that the following conditions are met:
103345 + * * Redistributions of source code must retain the above copyright
103346 + * notice, this list of conditions and the following disclaimer.
103347 + * * Redistributions in binary form must reproduce the above copyright
103348 + * notice, this list of conditions and the following disclaimer in the
103349 + * documentation and/or other materials provided with the distribution.
103350 + * * Neither the name of Freescale Semiconductor nor the
103351 + * names of its contributors may be used to endorse or promote products
103352 + * derived from this software without specific prior written permission.
103353 + *
103354 + *
103355 + * ALTERNATIVELY, this software may be distributed under the terms of the
103356 + * GNU General Public License ("GPL") as published by the Free Software
103357 + * Foundation, either version 2 of that License or (at your option) any
103358 + * later version.
103359 + *
103360 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103361 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103362 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103363 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103364 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103365 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103366 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103367 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103368 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103369 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103370 + */
103371 +
103372 +#ifndef __dflags_h
103373 +#define __dflags_h
103374 +
103375 +
103376 +#define NCSW_LINUX
103377 +
103378 +#define P4080
103379 +#define NCSW_PPC_CORE
103380 +
103381 +#define DEBUG_ERRORS 1
103382 +
103383 +#if defined(DEBUG)
103384 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103385 +
103386 +#define DEBUG_XX_MALLOC
103387 +#define DEBUG_MEM_LEAKS
103388 +
103389 +#else
103390 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103391 +#endif /* (DEBUG) */
103392 +
103393 +#define REPORT_EVENTS 1
103394 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103395 +
103396 +#ifdef CONFIG_P4080_SIM
103397 +#define SIMULATOR
103398 +#endif /* CONFIG_P4080_SIM */
103399 +
103400 +
103401 +#endif /* __dflags_h */
103402 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103403 new file mode 100644
103404 index 00000000..49405d0e
103405 --- /dev/null
103406 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103407 @@ -0,0 +1,11 @@
103408 +#
103409 +# Makefile for the Freescale Ethernet controllers
103410 +#
103411 +ccflags-y += -DVERSION=\"\"
103412 +#
103413 +#Include netcomm SW specific definitions
103414 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103415 +#
103416 +obj-y += system/
103417 +obj-y += wrapper/
103418 +obj-y += xx/
103419 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103420 new file mode 100644
103421 index 00000000..20f27d29
103422 --- /dev/null
103423 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103424 @@ -0,0 +1,118 @@
103425 +/*
103426 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103427 + *
103428 + * Redistribution and use in source and binary forms, with or without
103429 + * modification, are permitted provided that the following conditions are met:
103430 + * * Redistributions of source code must retain the above copyright
103431 + * notice, this list of conditions and the following disclaimer.
103432 + * * Redistributions in binary form must reproduce the above copyright
103433 + * notice, this list of conditions and the following disclaimer in the
103434 + * documentation and/or other materials provided with the distribution.
103435 + * * Neither the name of Freescale Semiconductor nor the
103436 + * names of its contributors may be used to endorse or promote products
103437 + * derived from this software without specific prior written permission.
103438 + *
103439 + *
103440 + * ALTERNATIVELY, this software may be distributed under the terms of the
103441 + * GNU General Public License ("GPL") as published by the Free Software
103442 + * Foundation, either version 2 of that License or (at your option) any
103443 + * later version.
103444 + *
103445 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103446 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103447 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103448 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103449 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103450 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103451 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103452 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103453 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103454 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103455 + */
103456 +
103457 +#ifndef __SYS_EXT_H
103458 +#define __SYS_EXT_H
103459 +
103460 +#include "std_ext.h"
103461 +
103462 +
103463 +/**************************************************************************//**
103464 + @Group sys_grp System Interfaces
103465 +
103466 + @Description Linux system programming interfaces.
103467 +
103468 + @{
103469 +*//***************************************************************************/
103470 +
103471 +/**************************************************************************//**
103472 + @Group sys_gen_grp System General Interface
103473 +
103474 + @Description General definitions, structures and routines of the linux
103475 + system programming interface.
103476 +
103477 + @{
103478 +*//***************************************************************************/
103479 +
103480 +/**************************************************************************//**
103481 + @Collection Macros for Advanced Configuration Requests
103482 + @{
103483 +*//***************************************************************************/
103484 +#define SYS_MAX_ADV_CONFIG_ARGS 4
103485 + /**< Maximum number of arguments in
103486 + an advanced configuration entry */
103487 +/* @} */
103488 +
103489 +/**************************************************************************//**
103490 + @Description System Object Advanced Configuration Entry
103491 +
103492 + This structure represents a single request for an advanced
103493 + configuration call on the initialized object. An array of such
103494 + requests may be contained in the settings structure of the
103495 + corresponding object.
103496 +
103497 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
103498 +*//***************************************************************************/
103499 +typedef struct t_SysObjectAdvConfigEntry
103500 +{
103501 + void *p_Function; /**< Pointer to advanced configuration routine */
103502 +
103503 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
103504 + /**< Array of arguments for the specified routine;
103505 + All arguments should be casted to uint32_t. */
103506 +} t_SysObjectAdvConfigEntry;
103507 +
103508 +
103509 +/** @} */ /* end of sys_gen_grp */
103510 +/** @} */ /* end of sys_grp */
103511 +
103512 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
103513 +
103514 +#define ADV_CONFIG_PARAMS_1(_type) \
103515 + , (_type)p_Entry->args[0]
103516 +
103517 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
103518 + p_Entry->args[0] = (uintptr_t )(_arg0); \
103519 +
103520 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
103521 +
103522 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
103523 + { \
103524 + t_SysObjectAdvConfigEntry *p_Entry; \
103525 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
103526 + int i=0, max = (_maxEntries); \
103527 +
103528 +#define ADD_ADV_CONFIG_END \
103529 + }
103530 +
103531 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
103532 + { \
103533 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
103534 + t_Error errCode; \
103535 +
103536 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
103537 + if (p_Entry->p_Function == _func) \
103538 + { \
103539 + errCode = _func(_handle _params); \
103540 + } else
103541 +
103542 +#endif /* __SYS_EXT_H */
103543 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103544 new file mode 100644
103545 index 00000000..d6aa9d41
103546 --- /dev/null
103547 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103548 @@ -0,0 +1,46 @@
103549 +/*
103550 + * Copyright 2008-2012 Freescale Semiconductor Inc.
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 +#ifndef __SYS_IO_EXT_H
103582 +#define __SYS_IO_EXT_H
103583 +
103584 +#include "std_ext.h"
103585 +#include "error_ext.h"
103586 +
103587 +
103588 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103589 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103590 +uint64_t SYS_PhysToVirt (uint64_t addr);
103591 +uint64_t SYS_VirtToPhys (uint64_t addr);
103592 +
103593 +
103594 +#endif /* __SYS_IO_EXT_H */
103595 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103596 new file mode 100644
103597 index 00000000..201ad699
103598 --- /dev/null
103599 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103600 @@ -0,0 +1,208 @@
103601 +/*
103602 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103603 + *
103604 + * Redistribution and use in source and binary forms, with or without
103605 + * modification, are permitted provided that the following conditions are met:
103606 + * * Redistributions of source code must retain the above copyright
103607 + * notice, this list of conditions and the following disclaimer.
103608 + * * Redistributions in binary form must reproduce the above copyright
103609 + * notice, this list of conditions and the following disclaimer in the
103610 + * documentation and/or other materials provided with the distribution.
103611 + * * Neither the name of Freescale Semiconductor nor the
103612 + * names of its contributors may be used to endorse or promote products
103613 + * derived from this software without specific prior written permission.
103614 + *
103615 + *
103616 + * ALTERNATIVELY, this software may be distributed under the terms of the
103617 + * GNU General Public License ("GPL") as published by the Free Software
103618 + * Foundation, either version 2 of that License or (at your option) any
103619 + * later version.
103620 + *
103621 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103622 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103623 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103624 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103625 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103626 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103627 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103628 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103629 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103630 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103631 + */
103632 +
103633 +#ifndef __TYPES_LINUX_H__
103634 +#define __TYPES_LINUX_H__
103635 +
103636 +#include <linux/version.h>
103637 +
103638 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103639 +#define MODVERSIONS
103640 +#endif
103641 +#ifdef MODVERSIONS
103642 +#include <config/modversions.h>
103643 +#endif /* MODVERSIONS */
103644 +
103645 +#include <linux/kernel.h>
103646 +#include <linux/types.h>
103647 +#include <asm/io.h>
103648 +#include <linux/delay.h>
103649 +
103650 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103651 + #error "This kernel is probably not supported!!!"
103652 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103653 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103654 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103655 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103656 +#endif /* LINUX_VERSION_CODE */
103657 +
103658 +
103659 +typedef float float_t; /* Single precision floating point */
103660 +typedef double double_t; /* Double precision floating point */
103661 +
103662 +
103663 +#define _Packed
103664 +#define _PackedType __attribute__ ((packed))
103665 +
103666 +typedef phys_addr_t physAddress_t;
103667 +
103668 +#define UINT8_MAX 0xFF
103669 +#define UINT8_MIN 0
103670 +#define UINT16_MAX 0xFFFF
103671 +#define UINT16_MIN 0
103672 +#define UINT32_MAX 0xFFFFFFFF
103673 +#define UINT32_MIN 0
103674 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103675 +#define UINT64_MIN 0
103676 +#define INT8_MAX 0x7F
103677 +#define INT8_MIN 0x80
103678 +#define INT16_MAX 0x7FFF
103679 +#define INT16_MIN 0x8000
103680 +#define INT32_MAX 0x7FFFFFFF
103681 +#define INT32_MIN 0x80000000
103682 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103683 +#define INT64_MIN 0x8000000000000000LL
103684 +
103685 +#define ON 1
103686 +#define OFF 0
103687 +
103688 +#define FALSE false
103689 +#define TRUE true
103690 +
103691 +
103692 +/************************/
103693 +/* memory access macros */
103694 +/************************/
103695 +#ifdef CONFIG_FMAN_ARM
103696 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103697 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103698 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103699 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103700 +#endif
103701 +
103702 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103703 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103704 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103705 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103706 +
103707 +#ifdef VERBOSE_WRITE
103708 +void XX_Print(char *str, ...);
103709 +#define WRITE_UINT8(arg, data) \
103710 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103711 +#define WRITE_UINT16(arg, data) \
103712 + 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)
103713 +#define WRITE_UINT32(arg, data) \
103714 + 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)
103715 +#define WRITE_UINT64(arg, data) \
103716 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103717 +
103718 +#else /* not VERBOSE_WRITE */
103719 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103720 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103721 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103722 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103723 +#endif /* not VERBOSE_WRITE */
103724 +
103725 +
103726 +/*****************************************************************************/
103727 +/* General stuff */
103728 +/*****************************************************************************/
103729 +#ifdef ARRAY_SIZE
103730 +#undef ARRAY_SIZE
103731 +#endif /* ARRAY_SIZE */
103732 +
103733 +#ifdef MAJOR
103734 +#undef MAJOR
103735 +#endif /* MAJOR */
103736 +
103737 +#ifdef MINOR
103738 +#undef MINOR
103739 +#endif /* MINOR */
103740 +
103741 +#ifdef QE_SIZEOF_BD
103742 +#undef QE_SIZEOF_BD
103743 +#endif /* QE_SIZEOF_BD */
103744 +
103745 +#ifdef BD_BUFFER_CLEAR
103746 +#undef BD_BUFFER_CLEAR
103747 +#endif /* BD_BUFFER_CLEAR */
103748 +
103749 +#ifdef BD_BUFFER
103750 +#undef BD_BUFFER
103751 +#endif /* BD_BUFFER */
103752 +
103753 +#ifdef BD_STATUS_AND_LENGTH_SET
103754 +#undef BD_STATUS_AND_LENGTH_SET
103755 +#endif /* BD_STATUS_AND_LENGTH_SET */
103756 +
103757 +#ifdef BD_STATUS_AND_LENGTH
103758 +#undef BD_STATUS_AND_LENGTH
103759 +#endif /* BD_STATUS_AND_LENGTH */
103760 +
103761 +#ifdef BD_BUFFER_ARG
103762 +#undef BD_BUFFER_ARG
103763 +#endif /* BD_BUFFER_ARG */
103764 +
103765 +#ifdef BD_GET_NEXT
103766 +#undef BD_GET_NEXT
103767 +#endif /* BD_GET_NEXT */
103768 +
103769 +#ifdef QE_SDEBCR_BA_MASK
103770 +#undef QE_SDEBCR_BA_MASK
103771 +#endif /* QE_SDEBCR_BA_MASK */
103772 +
103773 +#ifdef BD_BUFFER_SET
103774 +#undef BD_BUFFER_SET
103775 +#endif /* BD_BUFFER_SET */
103776 +
103777 +#ifdef UPGCR_PROTOCOL
103778 +#undef UPGCR_PROTOCOL
103779 +#endif /* UPGCR_PROTOCOL */
103780 +
103781 +#ifdef UPGCR_TMS
103782 +#undef UPGCR_TMS
103783 +#endif /* UPGCR_TMS */
103784 +
103785 +#ifdef UPGCR_RMS
103786 +#undef UPGCR_RMS
103787 +#endif /* UPGCR_RMS */
103788 +
103789 +#ifdef UPGCR_ADDR
103790 +#undef UPGCR_ADDR
103791 +#endif /* UPGCR_ADDR */
103792 +
103793 +#ifdef UPGCR_DIAG
103794 +#undef UPGCR_DIAG
103795 +#endif /* UPGCR_DIAG */
103796 +
103797 +#ifdef NCSW_PARAMS
103798 +#undef NCSW_PARAMS
103799 +#endif /* NCSW_PARAMS */
103800 +
103801 +#ifdef NO_IRQ
103802 +#undef NO_IRQ
103803 +#endif /* NO_IRQ */
103804 +
103805 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103806 +
103807 +
103808 +#endif /* __TYPES_LINUX_H__ */
103809 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103810 new file mode 100644
103811 index 00000000..0466a473
103812 --- /dev/null
103813 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103814 @@ -0,0 +1,84 @@
103815 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103816 + * All rights reserved.
103817 + *
103818 + * Redistribution and use in source and binary forms, with or without
103819 + * modification, are permitted provided that the following conditions are met:
103820 + * * Redistributions of source code must retain the above copyright
103821 + * notice, this list of conditions and the following disclaimer.
103822 + * * Redistributions in binary form must reproduce the above copyright
103823 + * notice, this list of conditions and the following disclaimer in the
103824 + * documentation and/or other materials provided with the distribution.
103825 + * * Neither the name of Freescale Semiconductor nor the
103826 + * names of its contributors may be used to endorse or promote products
103827 + * derived from this software without specific prior written permission.
103828 + *
103829 + *
103830 + * ALTERNATIVELY, this software may be distributed under the terms of the
103831 + * GNU General Public License ("GPL") as published by the Free Software
103832 + * Foundation, either version 2 of that License or (at your option) any
103833 + * later version.
103834 + *
103835 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103836 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103837 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103838 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103839 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103840 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103841 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103842 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103843 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103844 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103845 + */
103846 +
103847 +/******************************************************************************
103848 + @File fsl_fman_test.h
103849 +
103850 + @Description
103851 +*//***************************************************************************/
103852 +
103853 +#ifndef __FSL_FMAN_TEST_H
103854 +#define __FSL_FMAN_TEST_H
103855 +
103856 +#include <linux/types.h>
103857 +#include <linux/smp.h> /* raw_smp_processor_id() */
103858 +
103859 +//#define FMT_K_DBG
103860 +//#define FMT_K_DBG_RUNTIME
103861 +
103862 +#define _fmt_prk(stage, format, arg...) \
103863 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
103864 +
103865 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
103866 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
103867 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
103868 +
103869 +/* there are two macros for debugging: for runtime and generic.
103870 + * Helps when the runtime functions are not targeted for debugging,
103871 + * thus all the unnecessary information will be skipped.
103872 + */
103873 +/* used for generic debugging */
103874 +#if defined(FMT_K_DBG)
103875 + #define _fmt_dbg(format, arg...) \
103876 + printk("fmt [%s:%u](cpu:%u) - " format, \
103877 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103878 +#else
103879 +# define _fmt_dbg(arg...)
103880 +#endif
103881 +
103882 +/* used for debugging runtime functions */
103883 +#if defined(FMT_K_DBG_RUNTIME)
103884 + #define _fmt_dbgr(format, arg...) \
103885 + printk("fmt [%s:%u](cpu:%u) - " format, \
103886 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103887 +#else
103888 +# define _fmt_dbgr(arg...)
103889 +#endif
103890 +
103891 +#define FMT_RX_ERR_Q 0xffffffff
103892 +#define FMT_RX_DFLT_Q 0xfffffffe
103893 +#define FMT_TX_ERR_Q 0xfffffffd
103894 +#define FMT_TX_CONF_Q 0xfffffffc
103895 +
103896 +#define FMAN_TEST_MAX_TX_FQS 8
103897 +
103898 +#endif /* __FSL_FMAN_TEST_H */
103899 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103900 new file mode 100644
103901 index 00000000..0c0c6c11
103902 --- /dev/null
103903 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103904 @@ -0,0 +1,128 @@
103905 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
103906 + * All rights reserved.
103907 + *
103908 + * Redistribution and use in source and binary forms, with or without
103909 + * modification, are permitted provided that the following conditions are met:
103910 + * * Redistributions of source code must retain the above copyright
103911 + * notice, this list of conditions and the following disclaimer.
103912 + * * Redistributions in binary form must reproduce the above copyright
103913 + * notice, this list of conditions and the following disclaimer in the
103914 + * documentation and/or other materials provided with the distribution.
103915 + * * Neither the name of Freescale Semiconductor nor the
103916 + * names of its contributors may be used to endorse or promote products
103917 + * derived from this software without specific prior written permission.
103918 + *
103919 + *
103920 + * ALTERNATIVELY, this software may be distributed under the terms of the
103921 + * GNU General Public License ("GPL") as published by the Free Software
103922 + * Foundation, either version 2 of that License or (at your option) any
103923 + * later version.
103924 + *
103925 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103926 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103927 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103928 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103929 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103930 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103931 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103932 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103933 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103934 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103935 + */
103936 +
103937 +/*
103938 + @File lnxwrp_exp_sym.h
103939 + @Description FMan exported routines
103940 +*/
103941 +
103942 +#ifndef __LNXWRP_EXP_SYM_H
103943 +#define __LNXWRP_EXP_SYM_H
103944 +
103945 +#include "fm_port_ext.h"
103946 +#include "fm_pcd_ext.h"
103947 +#include "fm_mac_ext.h"
103948 +
103949 +
103950 +/* FMAN Port exported routines */
103951 +EXPORT_SYMBOL(FM_PORT_Disable);
103952 +EXPORT_SYMBOL(FM_PORT_Enable);
103953 +EXPORT_SYMBOL(FM_PORT_SetPCD);
103954 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
103955 +
103956 +/* Runtime PCD exported routines */
103957 +EXPORT_SYMBOL(FM_PCD_Enable);
103958 +EXPORT_SYMBOL(FM_PCD_Disable);
103959 +EXPORT_SYMBOL(FM_PCD_GetCounter);
103960 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
103961 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
103962 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
103963 +EXPORT_SYMBOL(FM_PCD_SetException);
103964 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
103965 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
103966 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
103967 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
103968 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
103969 +
103970 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
103971 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
103972 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
103973 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
103974 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
103975 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
103976 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
103977 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
103978 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
103979 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
103980 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
103981 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
103982 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
103983 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
103984 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
103985 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
103986 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
103987 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
103988 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
103989 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
103990 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
103991 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
103992 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
103993 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
103994 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
103995 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
103996 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
103997 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
103998 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
103999 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
104000 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
104001 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
104002 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
104003 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
104004 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
104005 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
104006 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
104007 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
104008 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
104009 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
104010 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
104011 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
104012 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
104013 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
104014 +#if (DPAA_VERSION >= 11)
104015 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
104016 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
104017 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
104018 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
104019 +#endif /* DPAA_VERSION >= 11 */
104020 +
104021 +#ifdef FM_CAPWAP_SUPPORT
104022 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
104023 +#endif /* FM_CAPWAP_SUPPORT */
104024 +
104025 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
104026 +
104027 +/* FMAN MAC exported routines */
104028 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
104029 +
104030 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
104031 +
104032 +#endif /* __LNXWRP_EXP_SYM_H */
104033 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
104034 new file mode 100644
104035 index 00000000..a72c8670
104036 --- /dev/null
104037 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
104038 @@ -0,0 +1,163 @@
104039 +/*
104040 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104041 + *
104042 + * Redistribution and use in source and binary forms, with or without
104043 + * modification, are permitted provided that the following conditions are met:
104044 + * * Redistributions of source code must retain the above copyright
104045 + * notice, this list of conditions and the following disclaimer.
104046 + * * Redistributions in binary form must reproduce the above copyright
104047 + * notice, this list of conditions and the following disclaimer in the
104048 + * documentation and/or other materials provided with the distribution.
104049 + * * Neither the name of Freescale Semiconductor nor the
104050 + * names of its contributors may be used to endorse or promote products
104051 + * derived from this software without specific prior written permission.
104052 + *
104053 + *
104054 + * ALTERNATIVELY, this software may be distributed under the terms of the
104055 + * GNU General Public License ("GPL") as published by the Free Software
104056 + * Foundation, either version 2 of that License or (at your option) any
104057 + * later version.
104058 + *
104059 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104060 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104061 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104062 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104063 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104064 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104065 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104066 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104067 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104068 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104069 + */
104070 +
104071 +/******************************************************************************
104072 + @File lnxwrp_fm_ext.h
104073 +
104074 + @Description TODO
104075 +*//***************************************************************************/
104076 +
104077 +#ifndef __LNXWRP_FM_EXT_H
104078 +#define __LNXWRP_FM_EXT_H
104079 +
104080 +#include "std_ext.h"
104081 +#include "sys_ext.h"
104082 +#include "fm_ext.h"
104083 +#include "fm_muram_ext.h"
104084 +#include "fm_pcd_ext.h"
104085 +#include "fm_port_ext.h"
104086 +#include "fm_mac_ext.h"
104087 +#include "fm_rtc_ext.h"
104088 +
104089 +
104090 +/**************************************************************************//**
104091 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
104092 +
104093 + @Description FM API functions, definitions and enums.
104094 +
104095 + @{
104096 +*//***************************************************************************/
104097 +
104098 +/**************************************************************************//**
104099 + @Group FM_LnxKern_init_grp Initialization Unit
104100 +
104101 + @Description Initialization Unit
104102 +
104103 + Initialization Flow:
104104 + Initialization of the FM Module will be carried out by the Linux
104105 + kernel according to the following sequence:
104106 + a. Calling the initialization routine with no parameters.
104107 + b. The driver will register to the Device-Tree.
104108 + c. The Linux Device-Tree will initiate a call to the driver for
104109 + initialization.
104110 + d. The driver will read the appropriate information from the Device-Tree
104111 + e. [Optional] Calling the advance initialization routines to change
104112 + driver's defaults.
104113 + f. Initialization of the device will be automatically upon using it.
104114 +
104115 + @{
104116 +*//***************************************************************************/
104117 +
104118 +typedef struct t_WrpFmDevSettings
104119 +{
104120 + t_FmParams param;
104121 + t_SysObjectAdvConfigEntry *advConfig;
104122 +} t_WrpFmDevSettings;
104123 +
104124 +typedef struct t_WrpFmPcdDevSettings
104125 +{
104126 + t_FmPcdParams param;
104127 + t_SysObjectAdvConfigEntry *advConfig;
104128 +} t_WrpFmPcdDevSettings;
104129 +
104130 +typedef struct t_WrpFmPortDevSettings
104131 +{
104132 + bool frag_enabled;
104133 + t_FmPortParams param;
104134 + t_SysObjectAdvConfigEntry *advConfig;
104135 +} t_WrpFmPortDevSettings;
104136 +
104137 +typedef struct t_WrpFmMacDevSettings
104138 +{
104139 + t_FmMacParams param;
104140 + t_SysObjectAdvConfigEntry *advConfig;
104141 +} t_WrpFmMacDevSettings;
104142 +
104143 +
104144 +/**************************************************************************//**
104145 + @Function LNXWRP_FM_Init
104146 +
104147 + @Description Initialize the FM linux wrapper.
104148 +
104149 + @Return A handle (descriptor) of the newly created FM Linux wrapper
104150 + structure.
104151 +*//***************************************************************************/
104152 +t_Handle LNXWRP_FM_Init(void);
104153 +
104154 +/**************************************************************************//**
104155 + @Function LNXWRP_FM_Free
104156 +
104157 + @Description Free the FM linux wrapper.
104158 +
104159 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
104160 +
104161 + @Return E_OK on success; Error code otherwise.
104162 +*//***************************************************************************/
104163 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
104164 +
104165 +/**************************************************************************//**
104166 + @Function LNXWRP_FM_GetMacHandle
104167 +
104168 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
104169 +
104170 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
104171 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
104172 + @Param[in] macId - Index of the mac handle.
104173 +
104174 + @Return A handle of the LLD compressor.
104175 +*//***************************************************************************/
104176 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
104177 +
104178 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
104179 +t_Handle LNXWRP_FM_TEST_Init(void);
104180 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
104181 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
104182 +
104183 +/** @} */ /* end of FM_LnxKern_init_grp group */
104184 +
104185 +
104186 +/**************************************************************************//**
104187 + @Group FM_LnxKern_ctrl_grp Control Unit
104188 +
104189 + @Description Control Unit
104190 +
104191 + TODO
104192 + @{
104193 +*//***************************************************************************/
104194 +
104195 +#include "lnxwrp_fsl_fman.h"
104196 +
104197 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104198 +/** @} */ /* end of FM_LnxKern_grp group */
104199 +
104200 +
104201 +#endif /* __LNXWRP_FM_EXT_H */
104202 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
104203 new file mode 100644
104204 index 00000000..c50031cf
104205 --- /dev/null
104206 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
104207 @@ -0,0 +1,921 @@
104208 +/*
104209 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104210 + *
104211 + * Redistribution and use in source and binary forms, with or without
104212 + * modification, are permitted provided that the following conditions are met:
104213 + * * Redistributions of source code must retain the above copyright
104214 + * notice, this list of conditions and the following disclaimer.
104215 + * * Redistributions in binary form must reproduce the above copyright
104216 + * notice, this list of conditions and the following disclaimer in the
104217 + * documentation and/or other materials provided with the distribution.
104218 + * * Neither the name of Freescale Semiconductor nor the
104219 + * names of its contributors may be used to endorse or promote products
104220 + * derived from this software without specific prior written permission.
104221 + *
104222 + *
104223 + * ALTERNATIVELY, this software may be distributed under the terms of the
104224 + * GNU General Public License ("GPL") as published by the Free Software
104225 + * Foundation, either version 2 of that License or (at your option) any
104226 + * later version.
104227 + *
104228 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104229 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104230 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104231 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104232 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104233 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104234 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104235 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104236 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104237 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104238 + */
104239 +
104240 +/******************************************************************************
104241 + @File lnxwrp_fsl_fman.h
104242 +
104243 + @Description Linux internal kernel API
104244 +*//***************************************************************************/
104245 +
104246 +#ifndef __LNXWRP_FSL_FMAN_H
104247 +#define __LNXWRP_FSL_FMAN_H
104248 +
104249 +#include <linux/types.h>
104250 +#include <linux/device.h> /* struct device */
104251 +#include <linux/fsl_qman.h> /* struct qman_fq */
104252 +#include "dpaa_integration_ext.h"
104253 +#include "fm_port_ext.h"
104254 +#include "fm_mac_ext.h"
104255 +#include "fm_macsec_ext.h"
104256 +#include "fm_rtc_ext.h"
104257 +
104258 +/**************************************************************************//**
104259 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
104260 +
104261 + @Description FM API functions, definitions and enums.
104262 +
104263 + @{
104264 +*//***************************************************************************/
104265 +
104266 +/**************************************************************************//**
104267 + @Group FM_LnxKern_ctrl_grp Control Unit
104268 +
104269 + @Description Control Unit
104270 +
104271 + Internal Kernel Control Unit API
104272 + @{
104273 +*//***************************************************************************/
104274 +
104275 +/*****************************************************************************/
104276 +/* Internal Linux kernel routines */
104277 +/*****************************************************************************/
104278 +
104279 +/**************************************************************************//**
104280 + @Description MACSEC Exceptions wrapper
104281 +*//***************************************************************************/
104282 +typedef enum fm_macsec_exception {
104283 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
104284 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
104285 +} fm_macsec_exception;
104286 +
104287 +/**************************************************************************//**
104288 + @Description Unknown sci frame treatment wrapper
104289 +*//***************************************************************************/
104290 +typedef enum fm_macsec_unknown_sci_frame_treatment {
104291 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
104292 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104293 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
104294 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
104295 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104296 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104297 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
104298 +} fm_macsec_unknown_sci_frame_treatment;
104299 +
104300 +/**************************************************************************//**
104301 + @Description Untag frame treatment wrapper
104302 +*//***************************************************************************/
104303 +typedef enum fm_macsec_untag_frame_treatment {
104304 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
104305 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104306 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
104307 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
104308 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
104309 +} fm_macsec_untag_frame_treatment;
104310 +
104311 +/**************************************************************************//**
104312 +@Description MACSEC SECY Cipher Suite wrapper
104313 +*//***************************************************************************/
104314 +typedef enum fm_macsec_secy_cipher_suite {
104315 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
104316 +#if (DPAA_VERSION >= 11)
104317 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
104318 +#endif /* (DPAA_VERSION >= 11) */
104319 +} fm_macsec_secy_cipher_suite;
104320 +
104321 +/**************************************************************************//**
104322 + @Description MACSEC SECY Exceptions wrapper
104323 +*//***************************************************************************/
104324 +typedef enum fm_macsec_secy_exception {
104325 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
104326 +} fm_macsec_secy_exception;
104327 +
104328 +/**************************************************************************//**
104329 + @Description MACSEC SECY Events wrapper
104330 +*//***************************************************************************/
104331 +typedef enum fm_macsec_secy_event {
104332 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
104333 +} fm_macsec_secy_event;
104334 +
104335 +/**************************************************************************//**
104336 + @Description Valid frame behaviors wrapper
104337 +*//***************************************************************************/
104338 +typedef enum fm_macsec_valid_frame_behavior {
104339 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
104340 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
104341 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
104342 +} fm_macsec_valid_frame_behavior;
104343 +
104344 +/**************************************************************************//**
104345 + @Description SCI insertion modes wrapper
104346 +*//***************************************************************************/
104347 +typedef enum fm_macsec_sci_insertion_mode {
104348 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
104349 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
104350 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
104351 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
104352 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
104353 +} fm_macsec_sci_insertion_mode;
104354 +
104355 +typedef macsecSAKey_t macsec_sa_key_t;
104356 +typedef macsecSCI_t macsec_sci_t;
104357 +typedef macsecAN_t macsec_an_t;
104358 +typedef t_Handle handle_t;
104359 +
104360 +/**************************************************************************//**
104361 + @Function fm_macsec_secy_exception_callback wrapper
104362 + @Description Exceptions user callback routine, will be called upon an
104363 + exception passing the exception identification.
104364 + @Param[in] app_h A handle to an application layer object; This handle
104365 + will be passed by the driver upon calling this callback.
104366 + @Param[in] exception The exception.
104367 +*//***************************************************************************/
104368 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
104369 + fm_macsec_secy_exception exception);
104370 +
104371 +/**************************************************************************//**
104372 + @Function fm_macsec_secy_event_callback wrapper
104373 + @Description Events user callback routine, will be called upon an
104374 + event passing the event identification.
104375 + @Param[in] app_h A handle to an application layer object; This handle
104376 + will be passed by the driver upon calling this callback.
104377 + @Param[in] event The event.
104378 +*//***************************************************************************/
104379 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
104380 + fm_macsec_secy_event event);
104381 +
104382 +/**************************************************************************//**
104383 + @Function fm_macsec_exception_callback wrapper
104384 + @Description Exceptions user callback routine, will be called upon an
104385 + exception passing the exception identification.
104386 + @Param[in] app_h A handle to an application layer object; This handle
104387 + will be passed by the driver upon calling this callback.
104388 + @Param[in] exception The exception.
104389 +*//***************************************************************************/
104390 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
104391 + fm_macsec_exception exception);
104392 +
104393 +/**************************************************************************//**
104394 + @Description MACSEC SecY SC Params wrapper
104395 +*//***************************************************************************/
104396 +struct fm_macsec_secy_sc_params {
104397 + macsec_sci_t sci;
104398 + fm_macsec_secy_cipher_suite cipher_suite;
104399 +};
104400 +
104401 +/**************************************************************************//**
104402 + @Description FM MACSEC SecY config input wrapper
104403 +*//***************************************************************************/
104404 +struct fm_macsec_secy_params {
104405 + handle_t fm_macsec_h;
104406 + struct fm_macsec_secy_sc_params tx_sc_params;
104407 + uint32_t num_receive_channels;
104408 + fm_macsec_secy_exception_callback *exception_f;
104409 + fm_macsec_secy_event_callback *event_f;
104410 + handle_t app_h;
104411 +};
104412 +
104413 +/**************************************************************************//**
104414 + @Description FM MACSEC config input wrapper
104415 +*//***************************************************************************/
104416 +struct fm_macsec_params {
104417 + handle_t fm_h;
104418 + bool guest_mode;
104419 +
104420 + union {
104421 + struct {
104422 + uint8_t fm_mac_id;
104423 + } guest_params;
104424 +
104425 + struct {
104426 + uintptr_t base_addr;
104427 + handle_t fm_mac_h;
104428 + fm_macsec_exception_callback *exception_f;
104429 + handle_t app_h;
104430 + } non_guest_params;
104431 + };
104432 +
104433 +};
104434 +
104435 +/**************************************************************************//**
104436 + @Description FM device opaque structure used for type checking
104437 +*//***************************************************************************/
104438 +struct fm;
104439 +
104440 +/**************************************************************************//**
104441 + @Description FM MAC device opaque structure used for type checking
104442 +*//***************************************************************************/
104443 +struct fm_mac_dev;
104444 +
104445 +/**************************************************************************//**
104446 + @Description FM MACSEC device opaque structure used for type checking
104447 +*//***************************************************************************/
104448 +struct fm_macsec_dev;
104449 +struct fm_macsec_secy_dev;
104450 +
104451 +/**************************************************************************//**
104452 + @Description A structure ..,
104453 +*//***************************************************************************/
104454 +struct fm_port;
104455 +
104456 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
104457 + uint8_t alignment, uint32_t *base_fqid);
104458 +
104459 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
104460 +
104461 +struct fm_port_pcd_param {
104462 + alloc_pcd_fqids cba;
104463 + free_pcd_fqids cbf;
104464 + struct device *dev;
104465 +};
104466 +
104467 +/**************************************************************************//**
104468 + @Description A structure of information about each of the external
104469 + buffer pools used by the port,
104470 +*//***************************************************************************/
104471 +struct fm_port_pool_param {
104472 + uint8_t id; /**< External buffer pool id */
104473 + uint16_t size; /**< External buffer pool buffer size */
104474 +};
104475 +
104476 +/**************************************************************************//**
104477 + @Description structure for additional port parameters
104478 +*//***************************************************************************/
104479 +struct fm_port_params {
104480 + uint32_t errq; /**< Error Queue Id. */
104481 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
104482 + 0 means no Tx conf for processed frames.
104483 + For Rx and OP - default Rx queue. */
104484 + uint8_t num_pools; /**< Number of pools use by this port */
104485 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
104486 + /**< Parameters for each pool */
104487 + uint16_t priv_data_size; /**< Area that user may save for his own
104488 + need (E.g. save the SKB) */
104489 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
104490 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
104491 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
104492 + bool frag_enable; /**< Fragmentation support, for OP only */
104493 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
104494 + if write optimization is used, must be >= 16. */
104495 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
104496 + Note that this field impacts the size of the buffer-prefix
104497 + (i.e. it pushes the data offset); */
104498 +};
104499 +
104500 +/**************************************************************************//**
104501 + @Function fm_bind
104502 +
104503 + @Description Bind to a specific FM device.
104504 +
104505 + @Param[in] fm_dev - the OF handle of the FM device.
104506 +
104507 + @Return A handle of the FM device.
104508 +
104509 + @Cautions Allowed only after the port was created.
104510 +*//***************************************************************************/
104511 +struct fm *fm_bind(struct device *fm_dev);
104512 +
104513 +/**************************************************************************//**
104514 + @Function fm_unbind
104515 +
104516 + @Description Un-bind from a specific FM device.
104517 +
104518 + @Param[in] fm - A handle of the FM device.
104519 +
104520 + @Cautions Allowed only after the port was created.
104521 +*//***************************************************************************/
104522 +void fm_unbind(struct fm *fm);
104523 +
104524 +void *fm_get_handle(struct fm *fm);
104525 +void *fm_get_rtc_handle(struct fm *fm);
104526 +struct resource *fm_get_mem_region(struct fm *fm);
104527 +
104528 +/**************************************************************************//**
104529 + @Function fm_port_bind
104530 +
104531 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
104532 +
104533 + @Param[in] fm_port_dev - the OF handle of the FM port device.
104534 +
104535 + @Return A handle of the FM port device.
104536 +
104537 + @Cautions Allowed only after the port was created.
104538 +*//***************************************************************************/
104539 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
104540 +
104541 +/**************************************************************************//**
104542 + @Function fm_port_unbind
104543 +
104544 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
104545 +
104546 + @Param[in] port - A handle of the FM port device.
104547 +
104548 + @Cautions Allowed only after the port was created.
104549 +*//***************************************************************************/
104550 +void fm_port_unbind(struct fm_port *port);
104551 +
104552 +/**************************************************************************//**
104553 + @Function fm_set_rx_port_params
104554 +
104555 + @Description Configure parameters for a specific Rx FM-port device.
104556 +
104557 + @Param[in] port - A handle of the FM port device.
104558 + @Param[in] params - Rx port parameters
104559 +
104560 + @Cautions Allowed only after the port is binded.
104561 +*//***************************************************************************/
104562 +void fm_set_rx_port_params(struct fm_port *port,
104563 + struct fm_port_params *params);
104564 +
104565 +/**************************************************************************//**
104566 + @Function fm_port_pcd_bind
104567 +
104568 + @Description Bind as a listener on a port PCD.
104569 +
104570 + @Param[in] port - A handle of the FM port device.
104571 + @Param[in] params - PCD port parameters
104572 +
104573 + @Cautions Allowed only after the port is binded.
104574 +*//***************************************************************************/
104575 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104576 +
104577 +/**************************************************************************//**
104578 + @Function fm_port_get_buff_layout_ext_params
104579 +
104580 + @Description Get data_align and manip_extra_space from the device tree
104581 + chosen node if applied.
104582 + This function will only update these two parameters.
104583 + When this port has no such parameters in the device tree
104584 + values will be set to 0.
104585 +
104586 + @Param[in] port - A handle of the FM port device.
104587 + @Param[in] params - PCD port parameters
104588 +
104589 + @Cautions Allowed only after the port is binded.
104590 +*//***************************************************************************/
104591 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104592 +
104593 +/**************************************************************************//**
104594 + @Function fm_get_tx_port_channel
104595 +
104596 + @Description Get qman-channel number for this Tx port.
104597 +
104598 + @Param[in] port - A handle of the FM port device.
104599 +
104600 + @Return qman-channel number for this Tx port.
104601 +
104602 + @Cautions Allowed only after the port is binded.
104603 +*//***************************************************************************/
104604 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104605 +
104606 +/**************************************************************************//**
104607 + @Function fm_set_tx_port_params
104608 +
104609 + @Description Configure parameters for a specific Tx FM-port device
104610 +
104611 + @Param[in] port - A handle of the FM port device.
104612 + @Param[in] params - Tx port parameters
104613 +
104614 + @Cautions Allowed only after the port is binded.
104615 +*//***************************************************************************/
104616 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104617 +
104618 +
104619 +/**************************************************************************//**
104620 + @Function fm_mac_set_handle
104621 +
104622 + @Description Set mac handle
104623 +
104624 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104625 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104626 + @Param[in] mac_id - MAC id.
104627 +*//***************************************************************************/
104628 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104629 + int mac_id);
104630 +
104631 +/**************************************************************************//**
104632 + @Function fm_port_enable
104633 +
104634 + @Description Enable specific FM-port device (may be Rx or Tx port).
104635 +
104636 + @Param[in] port - A handle of the FM port device.
104637 +
104638 + @Cautions Allowed only after the port is initialized.
104639 +*//***************************************************************************/
104640 +int fm_port_enable(struct fm_port *port);
104641 +
104642 +/**************************************************************************//**
104643 + @Function fm_port_disable
104644 +
104645 + @Description Disable specific FM-port device (may be Rx or Tx port).
104646 +
104647 + @Param[in] port - A handle of the FM port device.
104648 +
104649 + @Cautions Allowed only after the port is initialized.
104650 +*//***************************************************************************/
104651 +int fm_port_disable(struct fm_port *port);
104652 +
104653 +void *fm_port_get_handle(const struct fm_port *port);
104654 +
104655 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104656 + const void *data);
104657 +
104658 +/**************************************************************************//**
104659 + @Function fm_port_get_base_address
104660 +
104661 + @Description Get base address of this port. Useful for accessing
104662 + port-specific registers (i.e., not common ones).
104663 +
104664 + @Param[in] port - A handle of the FM port device.
104665 +
104666 + @Param[out] base_addr - The port's base addr (virtual address).
104667 +*//***************************************************************************/
104668 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104669 +
104670 +/**************************************************************************//**
104671 + @Function fm_mutex_lock
104672 +
104673 + @Description Lock function required before any FMD/LLD call.
104674 +*//***************************************************************************/
104675 +void fm_mutex_lock(void);
104676 +
104677 +/**************************************************************************//**
104678 + @Function fm_mutex_unlock
104679 +
104680 + @Description Unlock function required after any FMD/LLD call.
104681 +*//***************************************************************************/
104682 +void fm_mutex_unlock(void);
104683 +
104684 +/**************************************************************************//**
104685 + @Function fm_get_max_frm
104686 +
104687 + @Description Get the maximum frame size
104688 +*//***************************************************************************/
104689 +int fm_get_max_frm(void);
104690 +
104691 +/**************************************************************************//**
104692 + @Function fm_get_rx_extra_headroom
104693 +
104694 + @Description Get the extra headroom size
104695 +*//***************************************************************************/
104696 +int fm_get_rx_extra_headroom(void);
104697 +
104698 +/**************************************************************************//**
104699 +@Function fm_port_set_rate_limit
104700 +
104701 +@Description Configure Shaper parameter on FM-port device (Tx port).
104702 +
104703 +@Param[in] port - A handle of the FM port device.
104704 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104705 +@Param[in] rate_limit - The required rate value.
104706 +
104707 +@Cautions Allowed only after the port is initialized.
104708 +*//***************************************************************************/
104709 +int fm_port_set_rate_limit(struct fm_port *port,
104710 + uint16_t max_burst_size,
104711 + uint32_t rate_limit);
104712 +/**************************************************************************//**
104713 +@Function fm_port_set_rate_limit
104714 +
104715 +@Description Delete Shaper configuration on FM-port device (Tx port).
104716 +
104717 +@Param[in] port - A handle of the FM port device.
104718 +
104719 +@Cautions Allowed only after the port is initialized.
104720 +*//***************************************************************************/
104721 +int fm_port_del_rate_limit(struct fm_port *port);
104722 +
104723 +struct auto_res_tables_sizes
104724 +{
104725 + uint16_t max_num_of_arp_entries;
104726 + uint16_t max_num_of_echo_ipv4_entries;
104727 + uint16_t max_num_of_ndp_entries;
104728 + uint16_t max_num_of_echo_ipv6_entries;
104729 + uint16_t max_num_of_snmp_ipv4_entries;
104730 + uint16_t max_num_of_snmp_ipv6_entries;
104731 + uint16_t max_num_of_snmp_oid_entries;
104732 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104733 + for the snmp table */
104734 + uint16_t max_num_of_ip_prot_filtering;
104735 + uint16_t max_num_of_tcp_port_filtering;
104736 + uint16_t max_num_of_udp_port_filtering;
104737 +};
104738 +/* ARP */
104739 +struct auto_res_arp_entry
104740 +{
104741 + uint32_t ip_address;
104742 + uint8_t mac[6];
104743 + bool is_vlan;
104744 + uint16_t vid;
104745 +};
104746 +struct auto_res_arp_info
104747 +{
104748 + uint8_t table_size;
104749 + struct auto_res_arp_entry *auto_res_table;
104750 + bool enable_conflict_detection; /* when TRUE
104751 + Conflict Detection will be checked and wake the host if
104752 + needed */
104753 +};
104754 +
104755 +/* NDP */
104756 +struct auto_res_ndp_entry
104757 +{
104758 + uint32_t ip_address[4];
104759 + uint8_t mac[6];
104760 + bool is_vlan;
104761 + uint16_t vid;
104762 +};
104763 +struct auto_res_ndp_info
104764 +{
104765 + uint32_t multicast_group;
104766 + uint8_t table_size_assigned;
104767 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104768 + refer to solicitation IP addresses. Note that all IP adresses
104769 + must be from the same multicast group. This will be checked and
104770 + if not operation will fail. */
104771 + uint8_t table_size_tmp;
104772 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104773 + refer to temp IP addresses. Note that all temp IP adresses must
104774 + be from the same multicast group. This will be checked and if
104775 + not operation will fail. */
104776 +
104777 + bool enable_conflict_detection; /* when TRUE
104778 + Conflict Detection will be checked and wake the host if
104779 + needed */
104780 +};
104781 +
104782 +/* ICMP ECHO */
104783 +struct auto_res_echo_ipv4_info
104784 +{
104785 + uint8_t table_size;
104786 + struct auto_res_arp_entry *auto_res_table;
104787 +};
104788 +
104789 +struct auto_res_echo_ipv6_info
104790 +{
104791 + uint8_t table_size;
104792 + struct auto_res_ndp_entry *auto_res_table;
104793 +};
104794 +
104795 +/* SNMP */
104796 +struct auto_res_snmp_entry
104797 +{
104798 + uint16_t oidSize;
104799 + uint8_t *oidVal; /* only the oid string */
104800 + uint16_t resSize;
104801 + uint8_t *resVal; /* resVal will be the entire reply,
104802 + i.e. "Type|Length|Value" */
104803 +};
104804 +
104805 +/**************************************************************************//**
104806 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104807 + Refer to the FMan Controller spec for more details.
104808 +*//***************************************************************************/
104809 +struct auto_res_snmp_ipv4addr_tbl_entry
104810 +{
104811 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104812 + bool is_vlan;
104813 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104814 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104815 +};
104816 +
104817 +/**************************************************************************//**
104818 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104819 + Refer to the FMan Controller spec for more details.
104820 +*//***************************************************************************/
104821 +struct auto_res_snmp_ipv6addr_tbl_entry
104822 +{
104823 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104824 + bool isVlan;
104825 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104826 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104827 +};
104828 +
104829 +struct auto_res_snmp_info
104830 +{
104831 + uint16_t control; /**< Control bits [0-15]. */
104832 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104833 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104834 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104835 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104836 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104837 + char *community_read_write_string;
104838 + char *community_read_only_string;
104839 + struct auto_res_snmp_entry *oid_table;
104840 + uint32_t oid_table_size;
104841 + uint32_t *statistics;
104842 +};
104843 +
104844 +/* Filtering */
104845 +struct auto_res_port_filtering_entry
104846 +{
104847 + uint16_t src_port;
104848 + uint16_t dst_port;
104849 + uint16_t src_port_mask;
104850 + uint16_t dst_port_mask;
104851 +};
104852 +struct auto_res_filtering_info
104853 +{
104854 + /* IP protocol filtering parameters */
104855 + uint8_t ip_prot_table_size;
104856 + uint8_t *ip_prot_table_ptr;
104857 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
104858 + cause the packet to be droped, hit will pass the packet to
104859 + UDP/TCP filters if needed and if not to the classification
104860 + tree. If the classification tree will pass the packet to a
104861 + queue it will cause a wake interupt. When FALSE it the other
104862 + way around. */
104863 + /* UDP port filtering parameters */
104864 + uint8_t udp_ports_table_size;
104865 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
104866 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
104867 + cause the packet to be droped, hit will pass the packet to
104868 + classification tree. If the classification tree will pass the
104869 + packet to a queue it will cause a wake interupt. When FALSE it
104870 + the other way around. */
104871 + /* TCP port filtering parameters */
104872 + uint16_t tcp_flags_mask;
104873 + uint8_t tcp_ports_table_size;
104874 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
104875 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
104876 + cause the packet to be droped, hit will pass the packet to
104877 + classification tree. If the classification tree will pass the
104878 + packet to a queue it will cause a wake interupt. When FALSE it
104879 + the other way around. */
104880 +};
104881 +
104882 +struct auto_res_port_params
104883 +{
104884 + t_Handle h_FmPortTx;
104885 + struct auto_res_arp_info *p_auto_res_arp_info;
104886 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
104887 + struct auto_res_ndp_info *p_auto_res_ndp_info;
104888 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
104889 + struct auto_res_snmp_info *p_auto_res_snmp_info;
104890 + struct auto_res_filtering_info *p_auto_res_filtering_info;
104891 +};
104892 +
104893 +struct auto_res_port_stats
104894 +{
104895 + uint32_t arp_ar_cnt;
104896 + uint32_t echo_icmpv4_ar_cnt;
104897 + uint32_t ndp_ar_cnt;
104898 + uint32_t echo_icmpv6_ar_cnt;
104899 +};
104900 +
104901 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
104902 + struct auto_res_tables_sizes *params);
104903 +
104904 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
104905 + struct auto_res_port_params *params);
104906 +
104907 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
104908 + struct fm_port *port_tx);
104909 +
104910 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
104911 +
104912 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
104913 + struct fm_port *port);
104914 +
104915 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
104916 + *stats);
104917 +
104918 +int fm_port_resume(struct fm_port *port);
104919 +
104920 +int fm_port_suspend(struct fm_port *port);
104921 +
104922 +#ifdef CONFIG_FMAN_PFC
104923 +/**************************************************************************//**
104924 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
104925 +
104926 +@Description Associate a QMan Work Queue with a PFC priority on this
104927 + FM-port device (Tx port).
104928 +
104929 +@Param[in] port - A handle of the FM port device.
104930 +
104931 +@Param[in] prio - The PFC priority.
104932 +
104933 +@Param[in] wq - The Work Queue associated with the PFC priority.
104934 +
104935 +@Cautions Allowed only after the port is initialized.
104936 +*//***************************************************************************/
104937 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
104938 + uint8_t prio, uint8_t wq);
104939 +#endif
104940 +
104941 +/**************************************************************************//**
104942 +@Function fm_mac_set_exception
104943 +
104944 +@Description Set MAC exception state.
104945 +
104946 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
104947 +@Param[in] exception - FM MAC exception type.
104948 +@Param[in] enable - new state.
104949 +
104950 +*//***************************************************************************/
104951 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
104952 + e_FmMacExceptions exception, bool enable);
104953 +
104954 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
104955 +
104956 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
104957 +
104958 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
104959 + int len);
104960 +
104961 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
104962 +
104963 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
104964 +
104965 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
104966 +
104967 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
104968 +
104969 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
104970 +
104971 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
104972 +
104973 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
104974 +
104975 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
104976 +
104977 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
104978 + bool enable);
104979 +
104980 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104981 + t_EnetAddr *mac_addr);
104982 +
104983 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104984 + t_EnetAddr *mac_addr);
104985 +
104986 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
104987 + uint8_t *addr);
104988 +
104989 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
104990 + bool link, int speed, bool duplex);
104991 +
104992 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104993 +
104994 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104995 +
104996 +int fm_mac_set_rx_pause_frames(
104997 + struct fm_mac_dev *fm_mac_dev, bool en);
104998 +
104999 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
105000 + bool en);
105001 +
105002 +int fm_rtc_enable(struct fm *fm_dev);
105003 +
105004 +int fm_rtc_disable(struct fm *fm_dev);
105005 +
105006 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
105007 +
105008 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
105009 +
105010 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
105011 +
105012 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
105013 +
105014 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
105015 + uint64_t time);
105016 +
105017 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
105018 + uint64_t fiper);
105019 +
105020 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
105021 + bool en);
105022 +
105023 +/**************************************************************************//**
105024 +@Function fm_macsec_set_exception
105025 +
105026 +@Description Set MACSEC exception state.
105027 +
105028 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
105029 +@Param[in] exception - FM MACSEC exception type.
105030 +@Param[in] enable - new state.
105031 +
105032 +*//***************************************************************************/
105033 +
105034 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
105035 + fm_macsec_exception exception, bool enable);
105036 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
105037 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
105038 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
105039 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
105040 + *fm_macsec_dev,
105041 + fm_macsec_unknown_sci_frame_treatment treat_mode);
105042 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105043 + bool deliver_uncontrolled);
105044 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105045 + bool discard_uncontrolled);
105046 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105047 + fm_macsec_untag_frame_treatment treat_mode);
105048 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
105049 + uint32_t pnExhThr);
105050 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
105051 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
105052 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
105053 + fm_macsec_exception exception, bool enable);
105054 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
105055 + int *macsec_revision);
105056 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
105057 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
105058 +
105059 +
105060 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105061 + fm_macsec_secy_exception exception,
105062 + bool enable);
105063 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105064 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
105065 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105066 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105067 + fm_macsec_sci_insertion_mode sci_insertion_mode);
105068 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105069 + bool protect_frames);
105070 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105071 + bool replay_protect, uint32_t replay_window);
105072 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105073 + fm_macsec_valid_frame_behavior validate_frames);
105074 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105075 + bool confidentiality_enable,
105076 + uint32_t confidentiality_offset);
105077 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105078 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105079 + fm_macsec_secy_event event,
105080 + bool enable);
105081 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105082 + struct fm_macsec_secy_sc_params *params);
105083 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105084 + struct rx_sc_dev *sc);
105085 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105086 + struct rx_sc_dev *sc, macsec_an_t an,
105087 + uint32_t lowest_pn, macsec_sa_key_t key);
105088 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105089 + struct rx_sc_dev *sc, macsec_an_t an);
105090 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105091 + struct rx_sc_dev *sc,
105092 + macsec_an_t an);
105093 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105094 + struct rx_sc_dev *sc,
105095 + macsec_an_t an);
105096 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105097 + struct rx_sc_dev *sc,
105098 + macsec_an_t an, uint32_t updt_next_pn);
105099 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105100 + struct rx_sc_dev *sc,
105101 + macsec_an_t an, uint32_t updt_lowest_pn);
105102 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105103 + struct rx_sc_dev *sc,
105104 + macsec_an_t an, macsec_sa_key_t key);
105105 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105106 + macsec_an_t an, macsec_sa_key_t key);
105107 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105108 + macsec_an_t an);
105109 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105110 + macsec_an_t next_active_an,
105111 + macsec_sa_key_t key);
105112 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105113 + macsec_an_t an);
105114 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105115 + macsec_an_t *p_an);
105116 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105117 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
105118 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105119 + uint32_t *sc_phys_id);
105120 +
105121 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
105122 +/** @} */ /* end of FM_LnxKern_grp group */
105123 +
105124 +/* default values for initializing PTP 1588 timer clock */
105125 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
105126 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
105127 +
105128 +#endif /* __LNXWRP_FSL_FMAN_H */
105129 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
105130 new file mode 100644
105131 index 00000000..b183c86d
105132 --- /dev/null
105133 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
105134 @@ -0,0 +1,50 @@
105135 +/*
105136 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105137 + *
105138 + * Redistribution and use in source and binary forms, with or without
105139 + * modification, are permitted provided that the following conditions are met:
105140 + * * Redistributions of source code must retain the above copyright
105141 + * notice, this list of conditions and the following disclaimer.
105142 + * * Redistributions in binary form must reproduce the above copyright
105143 + * notice, this list of conditions and the following disclaimer in the
105144 + * documentation and/or other materials provided with the distribution.
105145 + * * Neither the name of Freescale Semiconductor nor the
105146 + * names of its contributors may be used to endorse or promote products
105147 + * derived from this software without specific prior written permission.
105148 + *
105149 + *
105150 + * ALTERNATIVELY, this software may be distributed under the terms of the
105151 + * GNU General Public License ("GPL") as published by the Free Software
105152 + * Foundation, either version 2 of that License or (at your option) any
105153 + * later version.
105154 + *
105155 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105156 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105157 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105158 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105159 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105160 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105161 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105162 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105163 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105164 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105165 + */
105166 +
105167 +#ifndef __XX_H
105168 +#define __XX_H
105169 +
105170 +#include "xx_ext.h"
105171 +
105172 +void * xx_Malloc(uint32_t n);
105173 +void xx_Free(void *p);
105174 +
105175 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
105176 +void xx_FreeSmart(void *p);
105177 +
105178 +/* never used: */
105179 +#define GetDeviceName(irq) ((char *)NULL)
105180 +
105181 +int GetDeviceIrqNum(int irq);
105182 +
105183 +
105184 +#endif /* __XX_H */
105185 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
105186 new file mode 100644
105187 index 00000000..667cd859
105188 --- /dev/null
105189 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
105190 @@ -0,0 +1,10 @@
105191 +#
105192 +# Makefile for the Freescale Ethernet controllers
105193 +#
105194 +ccflags-y += -DVERSION=\"\"
105195 +#
105196 +#Include netcomm SW specific definitions
105197 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105198 +#
105199 +
105200 +obj-y += sys_io.o
105201 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
105202 new file mode 100644
105203 index 00000000..c106a8b7
105204 --- /dev/null
105205 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
105206 @@ -0,0 +1,171 @@
105207 +/*
105208 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105209 + *
105210 + * Redistribution and use in source and binary forms, with or without
105211 + * modification, are permitted provided that the following conditions are met:
105212 + * * Redistributions of source code must retain the above copyright
105213 + * notice, this list of conditions and the following disclaimer.
105214 + * * Redistributions in binary form must reproduce the above copyright
105215 + * notice, this list of conditions and the following disclaimer in the
105216 + * documentation and/or other materials provided with the distribution.
105217 + * * Neither the name of Freescale Semiconductor nor the
105218 + * names of its contributors may be used to endorse or promote products
105219 + * derived from this software without specific prior written permission.
105220 + *
105221 + *
105222 + * ALTERNATIVELY, this software may be distributed under the terms of the
105223 + * GNU General Public License ("GPL") as published by the Free Software
105224 + * Foundation, either version 2 of that License or (at your option) any
105225 + * later version.
105226 + *
105227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105237 + */
105238 +
105239 +#include <linux/version.h>
105240 +
105241 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
105242 +#define MODVERSIONS
105243 +#endif
105244 +#ifdef MODVERSIONS
105245 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
105246 +#include <linux/modversions.h>
105247 +#else
105248 +#include <config/modversions.h>
105249 +#endif /* LINUX_VERSION_CODE */
105250 +#endif /* MODVERSIONS */
105251 +
105252 +#include <linux/module.h>
105253 +#include <linux/kernel.h>
105254 +
105255 +#include <asm/io.h>
105256 +
105257 +#include "std_ext.h"
105258 +#include "error_ext.h"
105259 +#include "string_ext.h"
105260 +#include "list_ext.h"
105261 +#include "sys_io_ext.h"
105262 +
105263 +
105264 +#define __ERR_MODULE__ MODULE_UNKNOWN
105265 +
105266 +
105267 +typedef struct {
105268 + uint64_t virtAddr;
105269 + uint64_t physAddr;
105270 + uint32_t size;
105271 + t_List node;
105272 +} t_IoMap;
105273 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
105274 +
105275 +LIST(mapsList);
105276 +
105277 +
105278 +static void EnqueueIoMap(t_IoMap *p_IoMap)
105279 +{
105280 + uint32_t intFlags;
105281 +
105282 + intFlags = XX_DisableAllIntr();
105283 + LIST_AddToTail(&p_IoMap->node, &mapsList);
105284 + XX_RestoreAllIntr(intFlags);
105285 +}
105286 +
105287 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
105288 +{
105289 + t_IoMap *p_IoMap;
105290 + t_List *p_Pos;
105291 +
105292 + LIST_FOR_EACH(p_Pos, &mapsList)
105293 + {
105294 + p_IoMap = IOMAP_OBJECT(p_Pos);
105295 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
105296 + return p_IoMap;
105297 + }
105298 +
105299 + return NULL;
105300 +}
105301 +
105302 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
105303 +{
105304 + t_IoMap *p_IoMap;
105305 + t_List *p_Pos;
105306 +
105307 + LIST_FOR_EACH(p_Pos, &mapsList)
105308 + {
105309 + p_IoMap = IOMAP_OBJECT(p_Pos);
105310 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
105311 + return p_IoMap;
105312 + }
105313 +
105314 + return NULL;
105315 +}
105316 +
105317 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
105318 +{
105319 + t_IoMap *p_IoMap;
105320 +
105321 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
105322 + if (!p_IoMap)
105323 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
105324 + memset(p_IoMap, 0, sizeof(t_IoMap));
105325 +
105326 + p_IoMap->virtAddr = virtAddr;
105327 + p_IoMap->physAddr = physAddr;
105328 + p_IoMap->size = size;
105329 +
105330 + INIT_LIST(&p_IoMap->node);
105331 + EnqueueIoMap(p_IoMap);
105332 +
105333 + return E_OK;
105334 +}
105335 +
105336 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
105337 +{
105338 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
105339 + if (!p_IoMap)
105340 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
105341 +
105342 + LIST_Del(&p_IoMap->node);
105343 + XX_Free(p_IoMap);
105344 +
105345 + return E_OK;
105346 +}
105347 +
105348 +uint64_t SYS_PhysToVirt(uint64_t addr)
105349 +{
105350 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
105351 + if (p_IoMap)
105352 + {
105353 + /* This is optimization - put the latest in the list-head - like a cache */
105354 + if (mapsList.p_Next != &p_IoMap->node)
105355 + {
105356 + uint32_t intFlags = XX_DisableAllIntr();
105357 + LIST_DelAndInit(&p_IoMap->node);
105358 + LIST_Add(&p_IoMap->node, &mapsList);
105359 + XX_RestoreAllIntr(intFlags);
105360 + }
105361 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
105362 + }
105363 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
105364 +}
105365 +
105366 +uint64_t SYS_VirtToPhys(uint64_t addr)
105367 +{
105368 + t_IoMap *p_IoMap;
105369 +
105370 + if (addr == 0)
105371 + return 0;
105372 +
105373 + p_IoMap = FindIoMapByVirtAddr(addr);
105374 + if (p_IoMap)
105375 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
105376 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
105377 +}
105378 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105379 new file mode 100644
105380 index 00000000..62713d62
105381 --- /dev/null
105382 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105383 @@ -0,0 +1,19 @@
105384 +#
105385 +# Makefile for the Freescale Ethernet controllers
105386 +#
105387 +ccflags-y += -DVERSION=\"\"
105388 +#
105389 +#Include netcomm SW specific definitions
105390 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105391 +
105392 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
105393 +
105394 +ccflags-y += -I$(NCSW_FM_INC)
105395 +ccflags-y += -I$(NET_DPA)
105396 +
105397 +obj-y += fsl-ncsw-PFM.o
105398 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
105399 +
105400 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
105401 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
105402 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
105403 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105404 new file mode 100644
105405 index 00000000..270d07b8
105406 --- /dev/null
105407 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105408 @@ -0,0 +1,1665 @@
105409 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
105410 + * All rights reserved.
105411 + *
105412 + * Redistribution and use in source and binary forms, with or without
105413 + * modification, are permitted provided that the following conditions are met:
105414 + * * Redistributions of source code must retain the above copyright
105415 + * notice, this list of conditions and the following disclaimer.
105416 + * * Redistributions in binary form must reproduce the above copyright
105417 + * notice, this list of conditions and the following disclaimer in the
105418 + * documentation and/or other materials provided with the distribution.
105419 + * * Neither the name of Freescale Semiconductor nor the
105420 + * names of its contributors may be used to endorse or promote products
105421 + * derived from this software without specific prior written permission.
105422 + *
105423 + *
105424 + * ALTERNATIVELY, this software may be distributed under the terms of the
105425 + * GNU General Public License ("GPL") as published by the Free Software
105426 + * Foundation, either version 2 of that License or (at your option) any
105427 + * later version.
105428 + *
105429 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105430 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105431 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105432 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105433 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105434 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105435 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105436 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105437 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105438 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105439 + */
105440 +
105441 +/*
105442 + @File fman_test.c
105443 + @Authors Pistirica Sorin Andrei
105444 + @Description FM Linux test environment
105445 +*/
105446 +
105447 +#include <linux/kernel.h>
105448 +#include <linux/module.h>
105449 +#include <linux/fs.h>
105450 +#include <linux/cdev.h>
105451 +#include <linux/device.h>
105452 +#include <linux/io.h>
105453 +#include <linux/ioport.h>
105454 +#include <linux/of_platform.h>
105455 +#include <linux/ip.h>
105456 +#include <linux/compat.h>
105457 +#include <linux/uaccess.h>
105458 +#include <linux/errno.h>
105459 +#include <linux/netdevice.h>
105460 +#include <linux/spinlock.h>
105461 +#include <linux/types.h>
105462 +#include <linux/fsl_qman.h>
105463 +#include <linux/fsl_bman.h>
105464 +
105465 +/* private headers */
105466 +#include "fm_ext.h"
105467 +#include "lnxwrp_fsl_fman.h"
105468 +#include "fm_port_ext.h"
105469 +#if (DPAA_VERSION == 11)
105470 +#include "../../Peripherals/FM/MAC/memac.h"
105471 +#endif
105472 +#include "fm_test_ioctls.h"
105473 +#include "fsl_fman_test.h"
105474 +
105475 +#include "dpaa_eth.h"
105476 +#include "dpaa_eth_common.h"
105477 +
105478 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
105479 +
105480 +struct fmt_frame_s {
105481 + ioc_fmt_buff_desc_t buff;
105482 + struct list_head list;
105483 +};
105484 +
105485 +struct fmt_fqs_s {
105486 + struct qman_fq fq_base;
105487 + bool init;
105488 + struct fmt_port_s *fmt_port_priv;
105489 +};
105490 +
105491 +struct fmt_port_pcd_s {
105492 + int num_queues;
105493 + struct fmt_fqs_s *fmt_pcd_fqs;
105494 + uint32_t fqid_base;
105495 +};
105496 +
105497 +/* char dev structure: fm test port */
105498 +struct fmt_port_s {
105499 + bool valid;
105500 + uint8_t id;
105501 + ioc_fmt_port_type port_type;
105502 + ioc_diag_mode diag;
105503 + bool compat_test_type;
105504 +
105505 + /* fm ports */
105506 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
105507 + * p_tx_port == p_rx_port */
105508 + /* t_LnxWrpFmPortDev */
105509 + struct fm_port *p_tx_port;
105510 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105511 + void *p_tx_fm_port_dev;
105512 + /* t_LnxWrpFmPortDev */
105513 + struct fm_port *p_rx_port;
105514 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105515 + void *p_rx_fm_port_dev;
105516 +
105517 + void *p_mac_dev;
105518 + uint64_t fm_phys_base_addr;
105519 +
105520 + /* read/write queue manipulation */
105521 + spinlock_t rx_q_lock;
105522 + struct list_head rx_q;
105523 +
105524 + /* tx queuee for injecting traffic */
105525 + int num_of_tx_fqs;
105526 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
105527 +
105528 + /* pcd private queues manipulation */
105529 + struct fmt_port_pcd_s fmt_port_pcd;
105530 +
105531 + /* debugging stuff */
105532 +
105533 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105534 + atomic_t enqueue_to_qman_frm;
105535 + atomic_t enqueue_to_rxq;
105536 + atomic_t dequeue_from_rxq;
105537 + atomic_t not_enqueue_to_rxq_wrong_frm;
105538 +#endif
105539 +
105540 +};
105541 +
105542 +/* The devices. */
105543 +struct fmt_s {
105544 + int major;
105545 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
105546 + struct class *fmt_class;
105547 +};
105548 +
105549 +/* fm test structure */
105550 +static struct fmt_s fm_test;
105551 +
105552 +#if (DPAA_VERSION == 11)
105553 +struct mac_priv_s {
105554 + t_Handle mac;
105555 +};
105556 +#endif
105557 +
105558 +#define DTSEC_BASE_ADDR 0x000e0000
105559 +#define DTSEC_MEM_RANGE 0x00002000
105560 +#define MAC_1G_MACCFG1 0x00000100
105561 +#define MAC_1G_LOOP_MASK 0x00000100
105562 +static int set_1gmac_loopback(
105563 + struct fmt_port_s *fmt_port,
105564 + bool en)
105565 +{
105566 +#if (DPAA_VERSION <= 10)
105567 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
105568 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
105569 + phys_addr_t maccfg1_hw;
105570 + void *maccfg1_map;
105571 + uint32_t maccfg1_val;
105572 +
105573 + /* compute the maccfg1 register address */
105574 + maccfg1_hw = fmt_port->fm_phys_base_addr +
105575 + (phys_addr_t)(DTSEC_BASE_ADDR +
105576 + dtsec_idx_off +
105577 + MAC_1G_MACCFG1);
105578 +
105579 + /* map register */
105580 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105581 +
105582 + /* set register */
105583 + maccfg1_val = in_be32(maccfg1_map);
105584 + if (en)
105585 + maccfg1_val |= MAC_1G_LOOP_MASK;
105586 + else
105587 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105588 + out_be32(maccfg1_map, maccfg1_val);
105589 +
105590 + /* unmap register */
105591 + iounmap(maccfg1_map);
105592 +#else
105593 + struct mac_device *mac_dev;
105594 + struct mac_priv_s *priv;
105595 + t_Memac *p_memac;
105596 +
105597 + if (!fmt_port)
105598 + return -EINVAL;
105599 +
105600 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105601 +
105602 + if (!mac_dev)
105603 + return -EINVAL;
105604 +
105605 + priv = macdev_priv(mac_dev);
105606 +
105607 + if (!priv)
105608 + return -EINVAL;
105609 +
105610 + p_memac = priv->mac;
105611 +
105612 + if (!p_memac)
105613 + return -EINVAL;
105614 +
105615 + memac_set_loopback(p_memac->p_MemMap, en);
105616 +#endif
105617 + return 0;
105618 +}
105619 +
105620 +/* TODO: re-write this function */
105621 +static int set_10gmac_int_loopback(
105622 + struct fmt_port_s *fmt_port,
105623 + bool en)
105624 +{
105625 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105626 +#define FM_10GMAC0_OFFSET 0x000f0000
105627 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105628 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105629 +
105630 + uint64_t base_addr, reg_addr;
105631 + uint32_t tmp_val;
105632 +
105633 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105634 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105635 +
105636 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105637 +
105638 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105639 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105640 + if (en)
105641 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105642 + else
105643 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105644 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105645 +
105646 + iounmap(UINT_TO_PTR(base_addr));
105647 +
105648 + return 0;
105649 +#else
105650 + _fmt_err("TGEC don't have internal-loopback.\n");
105651 + return -EPERM;
105652 +#endif
105653 +}
105654 +
105655 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105656 +{
105657 + int _err = 0;
105658 +
105659 + switch (fmt_port->port_type) {
105660 +
105661 + case e_IOC_FMT_PORT_T_RXTX:
105662 + /* 1G port */
105663 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105664 + _err = set_1gmac_loopback(fmt_port, en);
105665 + /* 10g port */
105666 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105667 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105668 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105669 +
105670 + _err = set_10gmac_int_loopback(fmt_port, en);
105671 + } else
105672 + _err = -EINVAL;
105673 + break;
105674 + /* op port does not have MAC (loopback mode) */
105675 + case e_IOC_FMT_PORT_T_OP:
105676 +
105677 + _err = 0;
105678 + break;
105679 + default:
105680 +
105681 + _err = -EPERM;
105682 + break;
105683 + }
105684 +
105685 + return _err;
105686 +}
105687 +
105688 +static void enqueue_fmt_frame(
105689 + struct fmt_port_s *fmt_port,
105690 + struct fmt_frame_s *p_fmt_frame)
105691 +{
105692 + spinlock_t *rx_q_lock = NULL;
105693 +
105694 + rx_q_lock = &fmt_port->rx_q_lock;
105695 +
105696 + spin_lock(rx_q_lock);
105697 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105698 + spin_unlock(rx_q_lock);
105699 +
105700 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105701 + atomic_inc(&fmt_port->enqueue_to_rxq);
105702 +#endif
105703 +}
105704 +
105705 +static struct fmt_frame_s *dequeue_fmt_frame(
105706 + struct fmt_port_s *fmt_port)
105707 +{
105708 + struct fmt_frame_s *p_fmt_frame = NULL;
105709 + spinlock_t *rx_q_lock = NULL;
105710 +
105711 + rx_q_lock = &fmt_port->rx_q_lock;
105712 +
105713 + spin_lock(rx_q_lock);
105714 +
105715 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105716 +
105717 + if (!list_empty(&fmt_port->rx_q)) {
105718 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105719 + struct fmt_frame_s,
105720 + list);
105721 + list_del(&p_fmt_frame->list);
105722 +
105723 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105724 + atomic_inc(&fmt_port->dequeue_from_rxq);
105725 +#endif
105726 + }
105727 +
105728 + spin_unlock(rx_q_lock);
105729 +
105730 + return p_fmt_frame;
105731 +}
105732 +
105733 +/* eth-dev -to- fmt port association */
105734 +struct fmt_port_s *match_dpa_to_fmt_port(
105735 + struct dpa_priv_s *dpa_priv) {
105736 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105737 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105738 + struct fmt_port_s *fmt_port = NULL;
105739 + int i;
105740 +
105741 + _fmt_dbgr("calling...\n");
105742 +
105743 + /* find the FM-test-port object */
105744 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105745 + if ((fm_test.ports[i].p_mac_dev &&
105746 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105747 + fm_port == fm_test.ports[i].p_tx_port) {
105748 +
105749 + fmt_port = &fm_test.ports[i];
105750 + break;
105751 + }
105752 +
105753 + _fmt_dbgr("called\n");
105754 + return fmt_port;
105755 +}
105756 +
105757 +void dump_frame(
105758 + uint8_t *buffer,
105759 + uint32_t size)
105760 +{
105761 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105762 + unsigned int i;
105763 +
105764 + for (i = 0; i < size; i++) {
105765 + if (i%16 == 0)
105766 + printk(KERN_DEBUG "\n");
105767 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105768 + }
105769 +#endif
105770 + return;
105771 +}
105772 +
105773 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105774 + uint32_t fqid,
105775 + uint8_t *buffer,
105776 + uint32_t size)
105777 +{
105778 + struct fmt_frame_s *p_fmt_frame = NULL;
105779 + bool test_and_steal_frame_frame;
105780 + uint32_t data_offset;
105781 + uint32_t i;
105782 +
105783 + _fmt_dbgr("calling...\n");
105784 +
105785 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105786 + return false;
105787 +
105788 + /* check watermark */
105789 + test_and_steal_frame_frame = false;
105790 + for (i = 0; i < size; i++) {
105791 + uint64_t temp = *((uint64_t *)(buffer + i));
105792 +
105793 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105794 + _fmt_dbgr("watermark found!\n");
105795 + test_and_steal_frame_frame = true;
105796 + break;
105797 + }
105798 + }
105799 +
105800 + if (!test_and_steal_frame_frame) {
105801 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105802 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105803 +#endif
105804 + _fmt_dbgr("NOT watermark found!\n");
105805 + return false;
105806 + }
105807 +
105808 + /* do not enqueue the tx conf/err frames */
105809 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105810 + goto _test_and_steal_frame_return_true;
105811 +
105812 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105813 + data_offset = FM_PORT_GetBufferDataOffset(
105814 + fmt_port->p_rx_fm_port_dev);
105815 +
105816 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105817 +
105818 + /* dump frame... no more space left on device */
105819 + if (p_fmt_frame == NULL) {
105820 + _fmt_err("no space left on device!\n");
105821 + goto _test_and_steal_frame_return_true;
105822 + }
105823 +
105824 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105825 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105826 +
105827 + /* No more space left on device*/
105828 + if (p_fmt_frame->buff.p_data == NULL) {
105829 + _fmt_err("no space left on device!\n");
105830 + kfree(p_fmt_frame);
105831 + goto _test_and_steal_frame_return_true;
105832 + }
105833 +
105834 + p_fmt_frame->buff.size = size-data_offset;
105835 + p_fmt_frame->buff.qid = fqid;
105836 +
105837 + memcpy(p_fmt_frame->buff.p_data,
105838 + (uint8_t *)PTR_MOVE(buffer, data_offset),
105839 + p_fmt_frame->buff.size);
105840 +
105841 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
105842 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
105843 + (char *)buffer),
105844 + 32);
105845 +
105846 + /* enqueue frame - this frame will go to us */
105847 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
105848 +
105849 +_test_and_steal_frame_return_true:
105850 + return true;
105851 +}
105852 +
105853 +static int fmt_fq_release(const struct qm_fd *fd)
105854 +{
105855 + struct dpa_bp *_dpa_bp;
105856 + struct bm_buffer _bmb;
105857 +
105858 + if (fd->format == qm_fd_contig) {
105859 + _dpa_bp = dpa_bpid2pool(fd->bpid);
105860 + BUG_ON(IS_ERR(_dpa_bp));
105861 +
105862 + _bmb.hi = fd->addr_hi;
105863 + _bmb.lo = fd->addr_lo;
105864 +
105865 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
105866 + cpu_relax();
105867 +
105868 + } else {
105869 + _fmt_err("frame not supported !\n");
105870 + return -1;
105871 + }
105872 +
105873 + return 0;
105874 +}
105875 +
105876 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
105877 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
105878 + fm_get_rx_extra_headroom() + \
105879 + DPA_PARSE_RESULTS_SIZE + \
105880 + DPA_HASH_RESULTS_SIZE)
105881 +#define MAC_HEADER_LENGTH 14
105882 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
105883 +
105884 +/* dpa ingress hooks definition */
105885 +enum dpaa_eth_hook_result fmt_rx_default_hook(
105886 + struct sk_buff *skb,
105887 + struct net_device *net_dev,
105888 + u32 fqid)
105889 +{
105890 + struct dpa_priv_s *dpa_priv = NULL;
105891 + struct fmt_port_s *fmt_port = NULL;
105892 + uint8_t *buffer;
105893 + uint32_t buffer_len;
105894 +
105895 + _fmt_dbgr("calling...\n");
105896 +
105897 + dpa_priv = netdev_priv(net_dev);
105898 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105899 +
105900 + /* conversion from skb to fd:
105901 + * skb cames processed for L3, so we need to go back for
105902 + * layer 2 offset */
105903 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
105904 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
105905 +
105906 + /* if is not out frame let dpa to handle it */
105907 + if (test_and_steal_frame(fmt_port,
105908 + FMT_RX_DFLT_Q,
105909 + buffer,
105910 + buffer_len))
105911 + goto _fmt_rx_default_hook_stolen;
105912 +
105913 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105914 + return DPAA_ETH_CONTINUE;
105915 +
105916 +_fmt_rx_default_hook_stolen:
105917 + dev_kfree_skb(skb);
105918 +
105919 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105920 + return DPAA_ETH_STOLEN;
105921 +}
105922 +
105923 +enum dpaa_eth_hook_result fmt_rx_error_hook(
105924 + struct net_device *net_dev,
105925 + const struct qm_fd *fd,
105926 + u32 fqid)
105927 +{
105928 + struct dpa_priv_s *dpa_priv = NULL;
105929 + struct dpa_bp *dpa_bp = NULL;
105930 + struct fmt_port_s *fmt_port = NULL;
105931 + void *fd_virt_addr = NULL;
105932 + dma_addr_t addr = qm_fd_addr(fd);
105933 +
105934 + _fmt_dbgr("calling...\n");
105935 +
105936 + dpa_priv = netdev_priv(net_dev);
105937 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105938 +
105939 + /* dpaa doesn't do this... we have to do it here */
105940 + dpa_bp = dpa_bpid2pool(fd->bpid);
105941 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105942 +
105943 + fd_virt_addr = phys_to_virt(addr);
105944 + /* if is not out frame let dpa to handle it */
105945 + if (test_and_steal_frame(fmt_port,
105946 + FMT_RX_ERR_Q,
105947 + fd_virt_addr,
105948 + fd->length20 + fd->offset)) {
105949 + goto _fmt_rx_error_hook_stolen;
105950 + }
105951 +
105952 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105953 + return DPAA_ETH_CONTINUE;
105954 +
105955 +_fmt_rx_error_hook_stolen:
105956 + /* the frame data doesn't matter,
105957 + * so, no mapping is needed */
105958 + fmt_fq_release(fd);
105959 +
105960 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105961 + return DPAA_ETH_STOLEN;
105962 +}
105963 +
105964 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
105965 + struct net_device *net_dev,
105966 + const struct qm_fd *fd,
105967 + u32 fqid)
105968 +{
105969 + struct dpa_priv_s *dpa_priv = NULL;
105970 + struct fmt_port_s *fmt_port = NULL;
105971 + dma_addr_t addr = qm_fd_addr(fd);
105972 + void *fd_virt_addr = NULL;
105973 + uint32_t fd_len = 0;
105974 +
105975 + _fmt_dbgr("calling...\n");
105976 +
105977 + dpa_priv = netdev_priv(net_dev);
105978 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105979 +
105980 + fd_virt_addr = phys_to_virt(addr);
105981 + fd_len = fd->length20 + fd->offset;
105982 +
105983 + if (fd_len > fm_get_max_frm()) {
105984 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
105985 + goto _fmt_tx_confirm_hook_continue;
105986 + }
105987 +
105988 + if (test_and_steal_frame(fmt_port,
105989 + FMT_TX_CONF_Q,
105990 + fd_virt_addr,
105991 + fd_len))
105992 + goto _fmt_tx_confirm_hook_stolen;
105993 +
105994 +_fmt_tx_confirm_hook_continue:
105995 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105996 + return DPAA_ETH_CONTINUE;
105997 +
105998 +_fmt_tx_confirm_hook_stolen:
105999 + kfree(fd_virt_addr);
106000 +
106001 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106002 + return DPAA_ETH_STOLEN;
106003 +}
106004 +
106005 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
106006 + struct net_device *net_dev,
106007 + const struct qm_fd *fd,
106008 + u32 fqid)
106009 +{
106010 + struct dpa_priv_s *dpa_priv = NULL;
106011 + struct fmt_port_s *fmt_port = NULL;
106012 + dma_addr_t addr = qm_fd_addr(fd);
106013 + void *fd_virt_addr = NULL;
106014 + uint32_t fd_len = 0;
106015 +
106016 + _fmt_dbgr("calling...\n");
106017 +
106018 + dpa_priv = netdev_priv(net_dev);
106019 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106020 +
106021 + fd_virt_addr = phys_to_virt(addr);
106022 + fd_len = fd->length20 + fd->offset;
106023 +
106024 + if (fd_len > fm_get_max_frm()) {
106025 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
106026 + goto _priv_ingress_tx_err_continue;
106027 + }
106028 +
106029 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
106030 + goto _priv_ingress_tx_err_stolen;
106031 +
106032 +_priv_ingress_tx_err_continue:
106033 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
106034 + return DPAA_ETH_CONTINUE;
106035 +
106036 +_priv_ingress_tx_err_stolen:
106037 + kfree(fd_virt_addr);
106038 +
106039 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106040 + return DPAA_ETH_STOLEN;
106041 +}
106042 +
106043 +/* egress callbacks definition */
106044 +enum qman_cb_dqrr_result fmt_egress_dqrr(
106045 + struct qman_portal *portal,
106046 + struct qman_fq *fq,
106047 + const struct qm_dqrr_entry *dqrr)
106048 +{
106049 + /* this callback should never be called */
106050 + BUG();
106051 + return qman_cb_dqrr_consume;
106052 +}
106053 +
106054 +static void fmt_egress_error_dqrr(
106055 + struct qman_portal *p,
106056 + struct qman_fq *fq,
106057 + const struct qm_mr_entry *msg)
106058 +{
106059 + uint8_t *fd_virt_addr = NULL;
106060 +
106061 + /* tx failure, on the ern callback - release buffer */
106062 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
106063 + kfree(fd_virt_addr);
106064 +
106065 + return;
106066 +}
106067 +
106068 +static const struct qman_fq fmt_egress_fq = {
106069 + .cb = { .dqrr = fmt_egress_dqrr,
106070 + .ern = fmt_egress_error_dqrr,
106071 + .fqs = NULL}
106072 +};
106073 +
106074 +int fmt_fq_alloc(
106075 + struct fmt_fqs_s *fmt_fqs,
106076 + const struct qman_fq *qman_fq,
106077 + uint32_t fqid, uint32_t flags,
106078 + uint16_t channel, uint8_t wq)
106079 +{
106080 + int _errno = 0;
106081 +
106082 + _fmt_dbg("calling...\n");
106083 +
106084 + fmt_fqs->fq_base = *qman_fq;
106085 +
106086 + if (fqid == 0) {
106087 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
106088 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
106089 + } else
106090 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
106091 +
106092 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
106093 +
106094 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
106095 + if (_errno < 0) {
106096 + _fmt_err("frame queues create failed.\n");
106097 + return -EINVAL;
106098 + }
106099 +
106100 + if (fmt_fqs->init) {
106101 + struct qm_mcc_initfq initfq;
106102 +
106103 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
106104 + initfq.fqd.dest.channel = channel;
106105 + initfq.fqd.dest.wq = wq;
106106 +
106107 + _errno = qman_init_fq(&fmt_fqs->fq_base,
106108 + QMAN_INITFQ_FLAG_SCHED,
106109 + &initfq);
106110 + if (_errno < 0) {
106111 + _fmt_err("frame queues init erorr.\n");
106112 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
106113 + return -EINVAL;
106114 + }
106115 + }
106116 +
106117 + _fmt_dbg("called.\n");
106118 + return 0;
106119 +}
106120 +
106121 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
106122 +{
106123 + int _err = 0;
106124 +
106125 + _fmt_dbg("calling...\n");
106126 +
106127 + if (fmt_fq->init) {
106128 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
106129 + if (unlikely(_err < 0))
106130 + _fmt_err("qman_retire_fq(%u) = %d\n",
106131 + qman_fq_fqid(&fmt_fq->fq_base), _err);
106132 +
106133 + _err = qman_oos_fq(&fmt_fq->fq_base);
106134 + if (unlikely(_err < 0))
106135 + _fmt_err("qman_oos_fq(%u) = %d\n",
106136 + qman_fq_fqid(&fmt_fq->fq_base), _err);
106137 + }
106138 +
106139 + qman_destroy_fq(&fmt_fq->fq_base, 0);
106140 +
106141 + _fmt_dbg("called.\n");
106142 + return _err;
106143 +}
106144 +
106145 +/* private pcd dqrr calbacks */
106146 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
106147 + struct qman_portal *portal,
106148 + struct qman_fq *fq,
106149 + const struct qm_dqrr_entry *dq)
106150 +{
106151 + struct dpa_bp *dpa_bp = NULL;
106152 + dma_addr_t addr = qm_fd_addr(&dq->fd);
106153 + uint8_t *fd_virt_addr = NULL;
106154 + struct fmt_port_s *fmt_port;
106155 + struct fmt_port_pcd_s *fmt_port_pcd;
106156 + uint32_t relative_fqid = 0;
106157 + uint32_t fd_len = 0;
106158 +
106159 + _fmt_dbgr("calling...\n");
106160 +
106161 + /* upcast - from pcd_alloc_fq */
106162 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
106163 + if (!fmt_port) {
106164 + _fmt_err(" wrong fmt port -to- fq match.\n");
106165 + goto _fmt_pcd_dqrr_return;
106166 + }
106167 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106168 +
106169 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
106170 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
106171 + relative_fqid, fmt_port_pcd->fqid_base);
106172 +
106173 + fd_len = dq->fd.length20 + dq->fd.offset;
106174 +
106175 + if (fd_len > fm_get_max_frm()) {
106176 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
106177 + fd_len, dq->fd.length20, dq->fd.offset);
106178 + goto _fmt_pcd_dqrr_return;
106179 + }
106180 +
106181 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
106182 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
106183 +
106184 + fd_virt_addr = phys_to_virt(addr);
106185 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
106186 + fd_len)) {
106187 +
106188 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106189 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
106190 +#endif
106191 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
106192 + " frame len: %u (dropped).\n",
106193 + dq->fqid, dq->fd.length20);
106194 + dump_frame(fd_virt_addr, fd_len);
106195 + }
106196 +
106197 +_fmt_pcd_dqrr_return:
106198 + /* no need to map again here */
106199 + fmt_fq_release(&dq->fd);
106200 +
106201 + _fmt_dbgr("calle.\n");
106202 + return qman_cb_dqrr_consume;
106203 +}
106204 +
106205 +static void fmt_pcd_err_dqrr(
106206 + struct qman_portal *qm,
106207 + struct qman_fq *fq,
106208 + const struct qm_mr_entry *msg)
106209 +{
106210 + _fmt_err("this callback should never be called.\n");
106211 + BUG();
106212 + return;
106213 +}
106214 +
106215 +static void fmt_pcd_fqs_dqrr(
106216 + struct qman_portal *qm,
106217 + struct qman_fq *fq,
106218 + const struct qm_mr_entry *msg)
106219 +{
106220 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
106221 + return;
106222 +}
106223 +
106224 +/* private pcd queue template */
106225 +static const struct qman_fq pcd_fq = {
106226 + .cb = { .dqrr = fmt_pcd_dqrr,
106227 + .ern = fmt_pcd_err_dqrr,
106228 + .fqs = fmt_pcd_fqs_dqrr}
106229 +};
106230 +
106231 +/* defined as weak in dpaa driver. */
106232 +/* ! parameters come from IOCTL call - US */
106233 +int dpa_alloc_pcd_fqids(
106234 + struct device *dev,
106235 + uint32_t num, uint8_t alignment,
106236 + uint32_t *base_fqid)
106237 +{
106238 + int _err = 0, i;
106239 + struct net_device *net_dev = NULL;
106240 + struct dpa_priv_s *dpa_priv = NULL;
106241 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106242 + struct fmt_fqs_s *fmt_fqs = NULL;
106243 + struct fmt_port_s *fmt_port = NULL;
106244 + int num_allocated = 0;
106245 +
106246 + _fmt_dbg("calling...\n");
106247 +
106248 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106249 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106250 +
106251 + if (!netif_msg_probe(dpa_priv)) {
106252 + _fmt_err("dpa not probe.\n");
106253 + _err = -ENODEV;
106254 + goto _pcd_alloc_fqs_err;
106255 + }
106256 +
106257 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106258 + if (!fmt_port) {
106259 + _fmt_err("fmt port not found.");
106260 + _err = -EINVAL;
106261 + goto _pcd_alloc_fqs_err;
106262 + }
106263 +
106264 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106265 +
106266 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
106267 +
106268 + if ((num_allocated <= 0) ||
106269 + (num_allocated < num) ||
106270 + (alignment && (*base_fqid) % alignment)) {
106271 + *base_fqid = 0;
106272 + _fmt_err("Failed to alloc pcd fqs rang.\n");
106273 + _err = -EINVAL;
106274 + goto _pcd_alloc_fqs_err;
106275 + }
106276 +
106277 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
106278 + num, alignment, num_allocated, *base_fqid);
106279 +
106280 + /* alloc pcd queues */
106281 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
106282 + sizeof(struct fmt_fqs_s),
106283 + GFP_KERNEL);
106284 + fmt_port_pcd->num_queues = num_allocated;
106285 + fmt_port_pcd->fqid_base = *base_fqid;
106286 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106287 +
106288 + /* alloc the pcd queues */
106289 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
106290 + _err = fmt_fq_alloc(
106291 + fmt_fqs,
106292 + &pcd_fq,
106293 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
106294 + dpa_priv->channel, 7);
106295 +
106296 + if (_err < 0)
106297 + goto _pcd_alloc_fqs_err;
106298 +
106299 + /* upcast to identify from where the frames came from */
106300 + fmt_fqs->fmt_port_priv = fmt_port;
106301 + }
106302 +
106303 + _fmt_dbg("called.\n");
106304 + return _err;
106305 +_pcd_alloc_fqs_err:
106306 + if (num_allocated > 0)
106307 + qman_release_fqid_range(*base_fqid, num_allocated);
106308 + /*TODO: free fmt_pcd_fqs if are any */
106309 +
106310 + _fmt_dbg("called(_err:%d).\n", _err);
106311 + return _err;
106312 +}
106313 +
106314 +/* defined as weak in dpaa driver. */
106315 +int dpa_free_pcd_fqids(
106316 + struct device *dev,
106317 + uint32_t base_fqid)
106318 +{
106319 +
106320 + int _err = 0, i;
106321 + struct net_device *net_dev = NULL;
106322 + struct dpa_priv_s *dpa_priv = NULL;
106323 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106324 + struct fmt_fqs_s *fmt_fqs = NULL;
106325 + struct fmt_port_s *fmt_port = NULL;
106326 + int num_allocated = 0;
106327 +
106328 + _fmt_dbg("calling...\n");
106329 +
106330 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106331 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106332 +
106333 + if (!netif_msg_probe(dpa_priv)) {
106334 + _fmt_err("dpa not probe.\n");
106335 + _err = -ENODEV;
106336 + goto _pcd_free_fqs_err;
106337 + }
106338 +
106339 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106340 + if (!fmt_port) {
106341 + _fmt_err("fmt port not found.");
106342 + _err = -EINVAL;
106343 + goto _pcd_free_fqs_err;
106344 + }
106345 +
106346 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106347 + num_allocated = fmt_port_pcd->num_queues;
106348 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106349 +
106350 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
106351 + fmt_fq_free(fmt_fqs);
106352 +
106353 + qman_release_fqid_range(base_fqid,num_allocated);
106354 +
106355 + kfree(fmt_port_pcd->fmt_pcd_fqs);
106356 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
106357 +
106358 + /* debugging stuff */
106359 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106360 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
106361 + _fmt_dbg(" frames enqueue to qman: %u.\n",
106362 + atomic_read(&fmt_port->enqueue_to_qman_frm));
106363 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
106364 + atomic_read(&fmt_port->enqueue_to_rxq));
106365 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
106366 + atomic_read(&fmt_port->dequeue_from_rxq));
106367 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
106368 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
106369 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106370 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106371 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106372 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106373 +#endif
106374 + return 0;
106375 +
106376 +_pcd_free_fqs_err:
106377 + return _err;
106378 +}
106379 +
106380 +static int fmt_port_init(
106381 + struct fmt_port_s *fmt_port,
106382 + ioc_fmt_port_param_t *p_Params)
106383 +{
106384 + struct device_node *fm_node, *fm_port_node;
106385 + const uint32_t *uint32_prop;
106386 + int _errno = 0, lenp = 0, i;
106387 + static struct of_device_id fm_node_of_match[] = {
106388 + { .compatible = "fsl,fman", },
106389 + { /* end of list */ },
106390 + };
106391 +
106392 + _fmt_dbg("calling...\n");
106393 +
106394 + /* init send/receive tu US list */
106395 + INIT_LIST_HEAD(&fmt_port->rx_q);
106396 +
106397 + /* check parameters */
106398 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
106399 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
106400 + _fmt_dbg("wrong test parameters.\n");
106401 + return -EINVAL;
106402 + }
106403 +
106404 + /* set port parameters */
106405 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
106406 + fmt_port->id = p_Params->fm_port_id;
106407 + fmt_port->port_type = p_Params->fm_port_type;
106408 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
106409 +
106410 + /* init debugging stuff */
106411 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106412 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106413 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106414 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106415 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106416 +#endif
106417 +
106418 + /* TODO: This should be done at probe time not at runtime
106419 + * very ugly function */
106420 + /* fill fmt port properties from dts */
106421 + for_each_matching_node(fm_node, fm_node_of_match) {
106422 +
106423 + uint32_prop = (uint32_t *)of_get_property(fm_node,
106424 + "cell-index", &lenp);
106425 + if (unlikely(uint32_prop == NULL)) {
106426 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106427 + fm_node->full_name);
106428 + return -EINVAL;
106429 + }
106430 + if (WARN_ON(lenp != sizeof(uint32_t))) {
106431 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106432 + fm_node->full_name);
106433 + return -EINVAL;
106434 + }
106435 +
106436 + if (*uint32_prop == p_Params->fm_id) {
106437 + struct resource res;
106438 +
106439 + /* Get the FM address */
106440 + _errno = of_address_to_resource(fm_node, 0, &res);
106441 + if (unlikely(_errno < 0)) {
106442 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
106443 + return -EINVAL;
106444 + }
106445 +
106446 + fmt_port->fm_phys_base_addr = res.start;
106447 +
106448 + for_each_child_of_node(fm_node, fm_port_node) {
106449 + struct platform_device *of_dev;
106450 +
106451 + if (!of_device_is_available(fm_port_node))
106452 + continue;
106453 +
106454 + uint32_prop = (uint32_t *)of_get_property(
106455 + fm_port_node,
106456 + "cell-index",
106457 + &lenp);
106458 + if (uint32_prop == NULL)
106459 + continue;
106460 +
106461 + if (of_device_is_compatible(fm_port_node,
106462 + "fsl,fman-port-oh") &&
106463 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
106464 +
106465 + if (*uint32_prop == fmt_port->id) {
106466 + of_dev = of_find_device_by_node(fm_port_node);
106467 + if (unlikely(of_dev == NULL)) {
106468 + _fmt_wrn("fm id invalid\n");
106469 + return -EINVAL;
106470 + }
106471 +
106472 + fmt_port->p_tx_port =
106473 + fm_port_bind(&of_dev->dev);
106474 + fmt_port->p_tx_fm_port_dev =
106475 + (void *)fm_port_get_handle(
106476 + fmt_port->p_tx_port);
106477 + fmt_port->p_rx_port =
106478 + fmt_port->p_tx_port;
106479 + fmt_port->p_rx_fm_port_dev =
106480 + fmt_port->p_tx_fm_port_dev;
106481 + fmt_port->p_mac_dev = NULL;
106482 + break;
106483 + }
106484 + } else if ((*uint32_prop == fmt_port->id) &&
106485 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106486 +
106487 + of_dev = of_find_device_by_node(fm_port_node);
106488 + if (unlikely(of_dev == NULL)) {
106489 + _fmt_wrn("dtb fm id invalid value");
106490 + return -EINVAL;
106491 + }
106492 +
106493 + if (of_device_is_compatible(fm_port_node,
106494 + "fsl,fman-port-1g-tx")) {
106495 + fmt_port->p_tx_port =
106496 + fm_port_bind(&of_dev->dev);
106497 + fmt_port->p_tx_fm_port_dev = (void *)
106498 + fm_port_get_handle(
106499 + fmt_port->p_tx_port);
106500 + } else if (of_device_is_compatible(fm_port_node,
106501 + "fsl,fman-port-1g-rx")) {
106502 + fmt_port->p_rx_port =
106503 + fm_port_bind(&of_dev->dev);
106504 + fmt_port->p_rx_fm_port_dev = (void *)
106505 + fm_port_get_handle(
106506 + fmt_port->p_rx_port);
106507 + } else if (of_device_is_compatible(fm_port_node,
106508 + "fsl,fman-1g-mac") ||
106509 + of_device_is_compatible(fm_port_node,
106510 + "fsl,fman-memac"))
106511 + fmt_port->p_mac_dev =
106512 + (typeof(fmt_port->p_mac_dev))
106513 + dev_get_drvdata(&of_dev->dev);
106514 + else
106515 + continue;
106516 +
106517 + if (fmt_port->p_tx_fm_port_dev &&
106518 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106519 + break;
106520 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
106521 + fmt_port->id) &&
106522 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106523 +
106524 + of_dev = of_find_device_by_node(fm_port_node);
106525 + if (unlikely(of_dev == NULL)) {
106526 + _fmt_wrn("dtb fm id invalid value\n");
106527 + return -EINVAL;
106528 + }
106529 +
106530 + if (of_device_is_compatible(fm_port_node,
106531 + "fsl,fman-port-10g-tx")) {
106532 + fmt_port->p_tx_port =
106533 + fm_port_bind(&of_dev->dev);
106534 + fmt_port->p_tx_fm_port_dev = (void *)
106535 + fm_port_get_handle(
106536 + fmt_port->p_tx_port);
106537 + } else if (of_device_is_compatible(fm_port_node,
106538 + "fsl,fman-port-10g-rx")) {
106539 + fmt_port->p_rx_port =
106540 + fm_port_bind(&of_dev->dev);
106541 + fmt_port->p_rx_fm_port_dev = (void *)
106542 + fm_port_get_handle(
106543 + fmt_port->p_rx_port);
106544 + } else if (of_device_is_compatible(fm_port_node,
106545 + "fsl,fman-10g-mac") ||
106546 + of_device_is_compatible(fm_port_node,
106547 + "fsl,fman-memac"))
106548 + fmt_port->p_mac_dev =
106549 + (typeof(fmt_port->p_mac_dev))
106550 + dev_get_drvdata(&of_dev->dev);
106551 + else
106552 + continue;
106553 +
106554 + if (fmt_port->p_tx_fm_port_dev &&
106555 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106556 + break;
106557 + }
106558 + } /* for_each_child */
106559 + }
106560 + } /* for each matching node */
106561 +
106562 + if (fmt_port->p_tx_fm_port_dev == 0 ||
106563 + fmt_port->p_rx_fm_port_dev == 0) {
106564 +
106565 + _fmt_err("bad fm port pointers.\n");
106566 + return -EINVAL;
106567 + }
106568 +
106569 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
106570 +
106571 + /* init fman test egress dynamic frame queues */
106572 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
106573 + int _errno;
106574 + _errno = fmt_fq_alloc(
106575 + &fmt_port->p_tx_fqs[i],
106576 + &fmt_egress_fq,
106577 + 0,
106578 + QMAN_FQ_FLAG_TO_DCPORTAL,
106579 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106580 + i);
106581 +
106582 + if (_errno < 0) {
106583 + _fmt_err("tx queues allocation failed.\n");
106584 + /* TODO: memory leak here if 1 queue is allocated and
106585 + * next queues are failing ... */
106586 + return -EINVAL;
106587 + }
106588 + }
106589 +
106590 + /* port is valid and ready to use. */
106591 + fmt_port->valid = TRUE;
106592 +
106593 + _fmt_dbg("called.\n");
106594 + return 0;
106595 +}
106596 +
106597 +/* fm test chardev functions */
106598 +static int fmt_open(struct inode *inode, struct file *file)
106599 +{
106600 + unsigned int minor = iminor(inode);
106601 +
106602 + _fmt_dbg("calling...\n");
106603 +
106604 + if (file->private_data != NULL)
106605 + return 0;
106606 +
106607 + /* The minor represent the port number.
106608 + * Set the port structure accordingly, thus all the operations
106609 + * will be done on this port. */
106610 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106611 + (minor < DEV_FM_TEST_MAX_MINORS))
106612 + file->private_data = &fm_test.ports[minor];
106613 + else
106614 + return -ENXIO;
106615 +
106616 + _fmt_dbg("called.\n");
106617 + return 0;
106618 +}
106619 +
106620 +static int fmt_close(struct inode *inode, struct file *file)
106621 +{
106622 + struct fmt_port_s *fmt_port = NULL;
106623 + struct fmt_frame_s *fmt_frame = NULL;
106624 +
106625 + int err = 0;
106626 +
106627 + _fmt_dbg("calling...\n");
106628 +
106629 + fmt_port = file->private_data;
106630 + if (!fmt_port)
106631 + return -ENODEV;
106632 +
106633 + /* Close the current test port by invalidating it. */
106634 + fmt_port->valid = FALSE;
106635 +
106636 + /* clean the fmt port queue */
106637 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106638 + if (fmt_frame && fmt_frame->buff.p_data){
106639 + kfree(fmt_frame->buff.p_data);
106640 + kfree(fmt_frame);
106641 + }
106642 + }
106643 +
106644 + /* !!! the qman queues are cleaning from fm_ioctl...
106645 + * - very ugly */
106646 +
106647 + _fmt_dbg("called.\n");
106648 + return err;
106649 +}
106650 +
106651 +static int fmt_ioctls(unsigned int minor,
106652 + struct file *file,
106653 + unsigned int cmd,
106654 + unsigned long arg,
106655 + bool compat)
106656 +{
106657 + struct fmt_port_s *fmt_port = NULL;
106658 +
106659 + _fmt_dbg("IOCTL minor:%u "
106660 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106661 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106662 +
106663 + fmt_port = file->private_data;
106664 + if (!fmt_port) {
106665 + _fmt_err("invalid fmt port.\n");
106666 + return -ENODEV;
106667 + }
106668 +
106669 + /* set test type properly */
106670 + if (compat)
106671 + fmt_port->compat_test_type = true;
106672 + else
106673 + fmt_port->compat_test_type = false;
106674 +
106675 + switch (cmd) {
106676 + case FMT_PORT_IOC_INIT:
106677 + {
106678 + ioc_fmt_port_param_t param;
106679 +
106680 + if (fmt_port->valid) {
106681 + _fmt_wrn("port is already initialized.\n");
106682 + return -EFAULT;
106683 + }
106684 +#if defined(CONFIG_COMPAT)
106685 + if (compat) {
106686 + if (copy_from_user(&param,
106687 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106688 + sizeof(ioc_fmt_port_param_t)))
106689 +
106690 + return -EFAULT;
106691 + } else
106692 +#endif
106693 + {
106694 + if (copy_from_user(&param,
106695 + (ioc_fmt_port_param_t *) arg,
106696 + sizeof(ioc_fmt_port_param_t)))
106697 +
106698 + return -EFAULT;
106699 + }
106700 +
106701 + return fmt_port_init(fmt_port, &param);
106702 + }
106703 +
106704 + case FMT_PORT_IOC_SET_DIAG_MODE:
106705 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106706 + return -EFAULT;
106707 +
106708 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106709 + return set_mac_int_loopback(fmt_port, TRUE);
106710 + else
106711 + return set_mac_int_loopback(fmt_port, FALSE);
106712 + break;
106713 +
106714 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106715 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106716 + default:
106717 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106718 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106719 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106720 + return -EFAULT;
106721 + }
106722 +
106723 + return 0;
106724 +}
106725 +
106726 +#ifdef CONFIG_COMPAT
106727 +static long fmt_compat_ioctl(
106728 + struct file *file,
106729 + unsigned int cmd,
106730 + unsigned long arg)
106731 +{
106732 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106733 +
106734 + _fmt_dbg("calling...\n");
106735 + return fmt_ioctls(minor, file, cmd, arg, true);
106736 +}
106737 +#endif
106738 +
106739 +static long fmt_ioctl(
106740 + struct file *file,
106741 + unsigned int cmd,
106742 + unsigned long arg)
106743 +{
106744 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106745 + unsigned int res;
106746 +
106747 + _fmt_dbg("calling...\n");
106748 +
106749 + fm_mutex_lock();
106750 + res = fmt_ioctls(minor, file, cmd, arg, false);
106751 + fm_mutex_unlock();
106752 +
106753 + _fmt_dbg("called.\n");
106754 +
106755 + return res;
106756 +}
106757 +
106758 +#ifdef CONFIG_COMPAT
106759 +void copy_compat_test_frame_buffer(
106760 + ioc_fmt_buff_desc_t *buff,
106761 + ioc_fmt_compat_buff_desc_t *compat_buff)
106762 +{
106763 + compat_buff->qid = buff->qid;
106764 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106765 + compat_buff->size = buff->size;
106766 + compat_buff->status = buff->status;
106767 +
106768 + compat_buff->buff_context.p_user_priv =
106769 + ptr_to_compat(buff->buff_context.p_user_priv);
106770 + memcpy(compat_buff->buff_context.fm_prs_res,
106771 + buff->buff_context.fm_prs_res,
106772 + FM_PRS_MAX * sizeof(uint8_t));
106773 + memcpy(compat_buff->buff_context.fm_time_stamp,
106774 + buff->buff_context.fm_time_stamp,
106775 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106776 +}
106777 +#endif
106778 +
106779 +ssize_t fmt_read(
106780 + struct file *file,
106781 + char __user *buf,
106782 + size_t size,
106783 + loff_t *ppos)
106784 +{
106785 + struct fmt_port_s *fmt_port = NULL;
106786 + struct fmt_frame_s *p_fmt_frame = NULL;
106787 + ssize_t cnt = 0;
106788 +
106789 + fmt_port = file->private_data;
106790 + if (!fmt_port || !fmt_port->valid) {
106791 + _fmt_err("fmt port not valid!\n");
106792 + return -ENODEV;
106793 + }
106794 +
106795 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106796 + if (p_fmt_frame == NULL)
106797 + return 0;
106798 +
106799 + _fmt_dbgr("calling...\n");
106800 +
106801 +#ifdef CONFIG_COMPAT
106802 + if (fmt_port->compat_test_type){
106803 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106804 + }
106805 + else
106806 +#endif
106807 + {
106808 + cnt = sizeof(ioc_fmt_buff_desc_t);
106809 + }
106810 +
106811 + if (size < cnt) {
106812 + _fmt_err("illegal buffer-size!\n");
106813 + cnt = 0;
106814 + goto _fmt_read_return;
106815 + }
106816 +
106817 + /* Copy structure */
106818 +#ifdef CONFIG_COMPAT
106819 + if (fmt_port->compat_test_type) {
106820 + {
106821 + ioc_fmt_compat_buff_desc_t compat_buff;
106822 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106823 + &compat_buff);
106824 +
106825 + if (copy_to_user(buf, &compat_buff, cnt)) {
106826 + _fmt_err("copy_to_user failed!\n");
106827 + goto _fmt_read_return;
106828 + }
106829 + }
106830 +
106831 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106832 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106833 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106834 + } else
106835 +#endif
106836 + {
106837 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
106838 + _fmt_err("copy_to_user failed!\n");
106839 + goto _fmt_read_return;
106840 + }
106841 +
106842 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
106843 + buf + sizeof(ioc_fmt_buff_desc_t);
106844 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106845 + }
106846 +
106847 + if (size < cnt) {
106848 + _fmt_err("illegal buffer-size!\n");
106849 + goto _fmt_read_return;
106850 + }
106851 +
106852 + /* copy frame */
106853 +#ifdef CONFIG_COMPAT
106854 + if (fmt_port->compat_test_type) {
106855 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
106856 + p_fmt_frame->buff.p_data, cnt)) {
106857 + _fmt_err("copy_to_user failed!\n");
106858 + goto _fmt_read_return;
106859 + }
106860 + } else
106861 +#endif
106862 + {
106863 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
106864 + p_fmt_frame->buff.p_data, cnt)) {
106865 + _fmt_err("copy_to_user failed!\n");
106866 + goto _fmt_read_return;
106867 + }
106868 + }
106869 +
106870 +_fmt_read_return:
106871 + kfree(p_fmt_frame->buff.p_data);
106872 + kfree(p_fmt_frame);
106873 +
106874 + _fmt_dbgr("called.\n");
106875 + return cnt;
106876 +}
106877 +
106878 +ssize_t fmt_write(
106879 + struct file *file,
106880 + const char __user *buf,
106881 + size_t size,
106882 + loff_t *ppos)
106883 +{
106884 + struct fmt_port_s *fmt_port = NULL;
106885 + ioc_fmt_buff_desc_t buff_desc;
106886 +#ifdef CONFIG_COMPAT
106887 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
106888 +#endif
106889 + uint8_t *p_data = NULL;
106890 + uint32_t data_offset;
106891 + int _errno;
106892 + t_DpaaFD fd;
106893 +
106894 + _fmt_dbgr("calling...\n");
106895 +
106896 + fmt_port = file->private_data;
106897 + if (!fmt_port || !fmt_port->valid) {
106898 + _fmt_err("fmt port not valid.\n");
106899 + return -EINVAL;
106900 + }
106901 +
106902 + /* If Compat (32B UserSpace - 64B KernelSpace) */
106903 +#ifdef CONFIG_COMPAT
106904 + if (fmt_port->compat_test_type) {
106905 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
106906 + _fmt_err("invalid buff_desc size.\n");
106907 + return -EFAULT;
106908 + }
106909 +
106910 + if (copy_from_user(&buff_desc_compat, buf,
106911 + sizeof(ioc_fmt_compat_buff_desc_t)))
106912 + return -EFAULT;
106913 +
106914 + buff_desc.qid = buff_desc_compat.qid;
106915 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
106916 + buff_desc.size = buff_desc_compat.size;
106917 + buff_desc.status = buff_desc_compat.status;
106918 +
106919 + buff_desc.buff_context.p_user_priv =
106920 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
106921 + memcpy(buff_desc.buff_context.fm_prs_res,
106922 + buff_desc_compat.buff_context.fm_prs_res,
106923 + FM_PRS_MAX * sizeof(uint8_t));
106924 + memcpy(buff_desc.buff_context.fm_time_stamp,
106925 + buff_desc_compat.buff_context.fm_time_stamp,
106926 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106927 + } else
106928 +#endif
106929 + {
106930 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
106931 + _fmt_err("invalid buff_desc size.\n");
106932 + return -EFAULT;
106933 + }
106934 +
106935 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
106936 + sizeof(ioc_fmt_buff_desc_t)))
106937 + return -EFAULT;
106938 + }
106939 +
106940 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
106941 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
106942 + if (!p_data)
106943 + return -ENOMEM;
106944 +
106945 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
106946 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
106947 + buff_desc.p_data,
106948 + buff_desc.size)) {
106949 + kfree(p_data);
106950 + return -EFAULT;
106951 + }
106952 +
106953 + /* TODO: dma_map_single here (cannot access the bpool struct) */
106954 +
106955 + /* prepare fd */
106956 + memset(&fd, 0, sizeof(fd));
106957 + DPAA_FD_SET_ADDR(&fd, p_data);
106958 + DPAA_FD_SET_OFFSET(&fd, data_offset);
106959 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
106960 +
106961 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
106962 + (struct qm_fd *)&fd, 0);
106963 + if (_errno) {
106964 + buff_desc.status = (uint32_t)_errno;
106965 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
106966 + sizeof(ioc_fmt_buff_desc_t))) {
106967 + kfree(p_data);
106968 + return -EFAULT;
106969 + }
106970 + }
106971 +
106972 + /* for debugging */
106973 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106974 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
106975 +#endif
106976 + _fmt_dbgr("called.\n");
106977 + return buff_desc.size;
106978 +}
106979 +
106980 +/* fm test character device definition */
106981 +static const struct file_operations fmt_fops =
106982 +{
106983 + .owner = THIS_MODULE,
106984 +#ifdef CONFIG_COMPAT
106985 + .compat_ioctl = fmt_compat_ioctl,
106986 +#endif
106987 + .unlocked_ioctl = fmt_ioctl,
106988 + .open = fmt_open,
106989 + .release = fmt_close,
106990 + .read = fmt_read,
106991 + .write = fmt_write,
106992 +};
106993 +
106994 +static int fmt_init(void)
106995 +{
106996 + int id;
106997 +
106998 + _fmt_dbg("calling...\n");
106999 +
107000 + /* Register to the /dev for IOCTL API */
107001 + /* Register dynamically a new major number for the character device: */
107002 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
107003 + if (fm_test.major <= 0) {
107004 + _fmt_wrn("Failed to allocate major number for device %s.\n",
107005 + DEV_FM_TEST_NAME);
107006 + return -ENODEV;
107007 + }
107008 +
107009 + /* Creating class for FMan_test */
107010 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
107011 + if (IS_ERR(fm_test.fmt_class)) {
107012 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
107013 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
107014 + return -ENODEV;
107015 + }
107016 +
107017 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
107018 + if (NULL == device_create(fm_test.fmt_class, NULL,
107019 + MKDEV(fm_test.major,
107020 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
107021 + DEV_FM_TEST_NAME "%d", id)) {
107022 +
107023 + _fmt_err("Error creating %s device.\n",
107024 + DEV_FM_TEST_NAME);
107025 + return -ENODEV;
107026 + }
107027 +
107028 + return 0;
107029 +}
107030 +
107031 +static void fmt_free(void)
107032 +{
107033 + int id;
107034 +
107035 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
107036 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
107037 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
107038 + class_destroy(fm_test.fmt_class);
107039 +}
107040 +
107041 +static int __init __cold fmt_load(void)
107042 +{
107043 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
107044 +
107045 + /* set dpaa hooks for default queues */
107046 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
107047 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
107048 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
107049 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
107050 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
107051 +
107052 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
107053 +
107054 + /* initialize the fman test environment */
107055 + if (fmt_init() < 0) {
107056 + _fmt_err("Failed to init FM-test modul.\n");
107057 + fmt_free();
107058 + return -ENODEV;
107059 + }
107060 +
107061 + _fmt_inf("FSL FM test module loaded.\n");
107062 +
107063 + return 0;
107064 +}
107065 +
107066 +static void __exit __cold fmt_unload(void)
107067 +{
107068 + fmt_free();
107069 + _fmt_inf("FSL FM test module unloaded.\n");
107070 +}
107071 +
107072 +module_init(fmt_load);
107073 +module_exit(fmt_unload);
107074 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
107075 new file mode 100755
107076 index 00000000..31f654b4
107077 --- /dev/null
107078 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
107079 @@ -0,0 +1,2908 @@
107080 +/*
107081 + * Copyright 2008-2012 Freescale Semiconductor Inc.
107082 + *
107083 + * Redistribution and use in source and binary forms, with or without
107084 + * modification, are permitted provided that the following conditions are met:
107085 + * * Redistributions of source code must retain the above copyright
107086 + * notice, this list of conditions and the following disclaimer.
107087 + * * Redistributions in binary form must reproduce the above copyright
107088 + * notice, this list of conditions and the following disclaimer in the
107089 + * documentation and/or other materials provided with the distribution.
107090 + * * Neither the name of Freescale Semiconductor nor the
107091 + * names of its contributors may be used to endorse or promote products
107092 + * derived from this software without specific prior written permission.
107093 + *
107094 + *
107095 + * ALTERNATIVELY, this software may be distributed under the terms of the
107096 + * GNU General Public License ("GPL") as published by the Free Software
107097 + * Foundation, either version 2 of that License or (at your option) any
107098 + * later version.
107099 + *
107100 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
107101 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
107102 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107103 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
107104 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
107105 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
107106 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
107107 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
107108 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
107109 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107110 + */
107111 +
107112 +/*
107113 + @File lnxwrp_fm.c
107114 + @Author Shlomi Gridish
107115 + @Description FM Linux wrapper functions.
107116 +*/
107117 +
107118 +#include <linux/version.h>
107119 +#include <linux/slab.h>
107120 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
107121 +#define MODVERSIONS
107122 +#endif
107123 +#ifdef MODVERSIONS
107124 +#include <config/modversions.h>
107125 +#endif /* MODVERSIONS */
107126 +#include <linux/kernel.h>
107127 +#include <linux/module.h>
107128 +#include <linux/fs.h>
107129 +#include <linux/cdev.h>
107130 +#include <linux/device.h>
107131 +#include <linux/irq.h>
107132 +#include <linux/interrupt.h>
107133 +#include <linux/io.h>
107134 +#include <linux/ioport.h>
107135 +#include <linux/of_platform.h>
107136 +#include <linux/of_address.h>
107137 +#include <linux/of_irq.h>
107138 +#include <linux/clk.h>
107139 +#include <asm/uaccess.h>
107140 +#include <asm/errno.h>
107141 +#ifndef CONFIG_FMAN_ARM
107142 +#include <sysdev/fsl_soc.h>
107143 +#include <linux/fsl/guts.h>
107144 +#include <linux/fsl/svr.h>
107145 +#endif
107146 +#include <linux/stat.h> /* For file access mask */
107147 +#include <linux/skbuff.h>
107148 +#include <linux/proc_fs.h>
107149 +
107150 +/* NetCommSw Headers --------------- */
107151 +#include "std_ext.h"
107152 +#include "error_ext.h"
107153 +#include "sprint_ext.h"
107154 +#include "debug_ext.h"
107155 +#include "sys_io_ext.h"
107156 +
107157 +#include "fm_ioctls.h"
107158 +
107159 +#include "lnxwrp_fm.h"
107160 +#include "lnxwrp_resources.h"
107161 +#include "lnxwrp_sysfs_fm.h"
107162 +#include "lnxwrp_sysfs_fm_port.h"
107163 +#include "lnxwrp_exp_sym.h"
107164 +#include "fm_common.h"
107165 +#include "../../sdk_fman/Peripherals/FM/fm.h"
107166 +#define __ERR_MODULE__ MODULE_FM
107167 +
107168 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
107169 + e_FmPortType portType,
107170 + uint8_t portId);
107171 +
107172 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
107173 +
107174 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
107175 + do { \
107176 + if (i<max){ \
107177 + p_Entry = &p_Entrys[i]; \
107178 + p_Entry->p_Function = _func; \
107179 + _param \
107180 + i++; \
107181 + } \
107182 + else \
107183 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
107184 + ("Number of advanced-configuration entries exceeded"));\
107185 + } while (0)
107186 +
107187 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
107188 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
107189 +
107190 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
107191 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
107192 +
107193 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
107194 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
107195 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
107196 +
107197 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
107198 +#define FSL_FM_PAUSE_TIME_DISABLE 0
107199 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
107200 +
107201 +/*
107202 + * Max frame size, across all interfaces.
107203 + * Configurable from Kconfig or bootargs, to avoid allocating
107204 + * oversized (socket) buffers when not using jumbo frames.
107205 + * Must be large enough to accommodate the network MTU, but small enough
107206 + * to avoid wasting skb memory.
107207 + *
107208 + * Could be overridden once, at boot-time, via the
107209 + * fm_set_max_frm() callback.
107210 + */
107211 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107212 +
107213 +/*
107214 + * Extra headroom for Rx buffers.
107215 + * FMan is instructed to allocate, on the Rx path, this amount of
107216 + * space at the beginning of a data buffer, beside the DPA private
107217 + * data area and the IC fields.
107218 + * Does not impact Tx buffer layout.
107219 + *
107220 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
107221 + * on particular forwarding scenarios that add extra headers to the
107222 + * forwarded frame.
107223 + */
107224 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107225 +
107226 +#ifdef CONFIG_FMAN_PFC
107227 +static int fsl_fm_pfc_quanta[] = {
107228 + CONFIG_FMAN_PFC_QUANTA_0,
107229 + CONFIG_FMAN_PFC_QUANTA_1,
107230 + CONFIG_FMAN_PFC_QUANTA_2,
107231 + CONFIG_FMAN_PFC_QUANTA_3
107232 +};
107233 +#endif
107234 +
107235 +static t_LnxWrpFm lnxWrpFm;
107236 +
107237 +int fm_get_max_frm()
107238 +{
107239 + return fsl_fm_max_frm;
107240 +}
107241 +EXPORT_SYMBOL(fm_get_max_frm);
107242 +
107243 +int fm_get_rx_extra_headroom()
107244 +{
107245 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
107246 +}
107247 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
107248 +
107249 +static int __init fm_set_max_frm(char *str)
107250 +{
107251 + int ret = 0;
107252 +
107253 + ret = get_option(&str, &fsl_fm_max_frm);
107254 + if (ret != 1) {
107255 + /*
107256 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
107257 + * and something like "earlyprintk=serial,uart0,115200" is
107258 + * specified in the bootargs
107259 + */
107260 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107261 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
107262 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
107263 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107264 +
107265 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107266 + return 1;
107267 + }
107268 +
107269 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
107270 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
107271 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
107272 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
107273 + "from Kconfig.\n",
107274 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
107275 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107276 +
107277 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107278 + return 1;
107279 + }
107280 +
107281 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
107282 + fsl_fm_max_frm);
107283 + return 0;
107284 +}
107285 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
107286 +
107287 +static int __init fm_set_rx_extra_headroom(char *str)
107288 +{
107289 + int ret;
107290 +
107291 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
107292 +
107293 + if (ret != 1) {
107294 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107295 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
107296 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107297 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107298 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107299 +
107300 + return 1;
107301 + }
107302 +
107303 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
107304 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
107305 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
107306 + "bootargs; will use the default "
107307 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
107308 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107309 + fsl_fm_rx_extra_headroom,
107310 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107311 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107312 + }
107313 +
107314 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
107315 + fsl_fm_rx_extra_headroom);
107316 +
107317 + return 0;
107318 +}
107319 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
107320 +
107321 +static irqreturn_t fm_irq(int irq, void *_dev)
107322 +{
107323 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107324 +#ifdef CONFIG_PM_SLEEP
107325 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
107326 +#endif
107327 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107328 + return IRQ_NONE;
107329 +
107330 +#ifdef CONFIG_PM_SLEEP
107331 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
107332 + {
107333 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
107334 + }
107335 +#endif
107336 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
107337 + return IRQ_HANDLED;
107338 +}
107339 +
107340 +static irqreturn_t fm_err_irq(int irq, void *_dev)
107341 +{
107342 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107343 +
107344 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107345 + return IRQ_NONE;
107346 +
107347 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
107348 + return IRQ_HANDLED;
107349 +
107350 + return IRQ_NONE;
107351 +}
107352 +
107353 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
107354 +static struct mutex lnxwrp_mutex;
107355 +
107356 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
107357 +{
107358 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107359 + int j;
107360 +
107361 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
107362 + if (!p_LnxWrpFmDev)
107363 + {
107364 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
107365 + return NULL;
107366 + }
107367 +
107368 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
107369 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107370 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107371 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107372 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107373 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107374 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107375 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107376 + {
107377 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107378 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107379 + }
107380 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107381 + {
107382 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107383 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107384 + }
107385 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107386 + {
107387 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107388 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107389 + }
107390 +
107391 + return p_LnxWrpFmDev;
107392 +}
107393 +
107394 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107395 +{
107396 + int j;
107397 +
107398 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107399 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
107400 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
107401 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107402 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
107403 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
107404 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107405 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
107406 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
107407 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
107408 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
107409 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
107410 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
107411 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
107412 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
107413 +
107414 + XX_Free(p_LnxWrpFmDev);
107415 +}
107416 +
107417 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
107418 +{
107419 +#define FM_BMI_PPIDS_OFFSET 0x00080304
107420 +#define FM_DMA_PLR_OFFSET 0x000c2060
107421 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
107422 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
107423 +#define DMA_LOW_LIODN_MASK 0x00000FFF
107424 +#define DMA_LIODN_SHIFT 16
107425 +
107426 +typedef _Packed struct {
107427 + uint32_t plr[32];
107428 +} _PackedType t_Plr;
107429 +
107430 +typedef _Packed struct {
107431 + volatile uint32_t fmbm_ppid[63];
107432 +} _PackedType t_Ppids;
107433 +
107434 + t_Plr *p_Plr;
107435 + t_Ppids *p_Ppids;
107436 + int i,j;
107437 + uint32_t fmRev;
107438 +
107439 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
107440 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
107441 +#if (DPAA_VERSION >= 11)
107442 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
107443 +#else
107444 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
107445 +#endif
107446 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
107447 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
107448 +
107449 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
107450 + fmRev &= 0xffff;
107451 +
107452 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
107453 +#ifdef MODULE
107454 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
107455 + p_Plr->plr[i] = 0;
107456 +#endif /* MODULE */
107457 +
107458 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
107459 + {
107460 + uint16_t liodnBase = (uint16_t)((i%2) ?
107461 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
107462 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
107463 +#ifdef FM_PARTITION_ARRAY
107464 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
107465 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
107466 +#endif /* FM_PARTITION_ARRAY */
107467 +
107468 + if ((i >= phys1GRxPortId[0]) &&
107469 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
107470 + {
107471 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
107472 + if (phys1GRxPortId[j] == i)
107473 + break;
107474 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
107475 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
107476 + }
107477 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
107478 + (i >= phys10GRxPortId[0]) &&
107479 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
107480 + {
107481 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
107482 + if (phys10GRxPortId[j] == i)
107483 + break;
107484 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
107485 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
107486 + }
107487 + else if ((i >= physOhPortId[0]) &&
107488 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
107489 + {
107490 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
107491 + if (physOhPortId[j] == i)
107492 + break;
107493 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
107494 + if (j == 0)
107495 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
107496 + else
107497 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
107498 + }
107499 + else if ((i >= phys1GTxPortId[0]) &&
107500 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
107501 + {
107502 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
107503 + if (phys1GTxPortId[j] == i)
107504 + break;
107505 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
107506 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
107507 + }
107508 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
107509 + (i >= phys10GTxPortId[0]) &&
107510 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
107511 + {
107512 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
107513 + if (phys10GTxPortId[j] == i)
107514 + break;
107515 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
107516 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
107517 + }
107518 + }
107519 +
107520 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
107521 +
107522 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
107523 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
107524 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
107525 +
107526 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
107527 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
107528 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
107529 +
107530 + return E_OK;
107531 +}
107532 +
107533 +/* Structure that defines QE firmware binary files.
107534 + *
107535 + * See Documentation/powerpc/qe_firmware.txt for a description of these
107536 + * fields.
107537 + */
107538 +struct qe_firmware {
107539 + struct qe_header {
107540 + __be32 length; /* Length of the entire structure, in bytes */
107541 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
107542 + u8 version; /* Version of this layout. First ver is '1' */
107543 + } header;
107544 + u8 id[62]; /* Null-terminated identifier string */
107545 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
107546 + u8 count; /* Number of microcode[] structures */
107547 + struct {
107548 + __be16 model; /* The SOC model */
107549 + u8 major; /* The SOC revision major */
107550 + u8 minor; /* The SOC revision minor */
107551 + } __attribute__ ((packed)) soc;
107552 + u8 padding[4]; /* Reserved, for alignment */
107553 + __be64 extended_modes; /* Extended modes */
107554 + __be32 vtraps[8]; /* Virtual trap addresses */
107555 + u8 reserved[4]; /* Reserved, for future expansion */
107556 + struct qe_microcode {
107557 + u8 id[32]; /* Null-terminated identifier */
107558 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
107559 + __be32 eccr; /* The value for the ECCR register */
107560 + __be32 iram_offset; /* Offset into I-RAM for the code */
107561 + __be32 count; /* Number of 32-bit words of the code */
107562 + __be32 code_offset; /* Offset of the actual microcode */
107563 + u8 major; /* The microcode version major */
107564 + u8 minor; /* The microcode version minor */
107565 + u8 revision; /* The microcode version revision */
107566 + u8 padding; /* Reserved, for alignment */
107567 + u8 reserved[4]; /* Reserved, for future expansion */
107568 + } __attribute__ ((packed)) microcode[1];
107569 + /* All microcode binaries should be located here */
107570 + /* CRC32 should be located here, after the microcode binaries */
107571 +} __attribute__ ((packed));
107572 +
107573 +
107574 +/**
107575 + * FindFmanMicrocode - find the Fman microcode
107576 + *
107577 + * This function returns a pointer to the QE Firmware blob that holds
107578 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107579 + * is similar to QE microcode, so there's no point in defining a new layout.
107580 + *
107581 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107582 + * so we check for that first. Each Fman node in the device tree contains a
107583 + * node or a pointer to node that holds the firmware. Technically, we should
107584 + * be fetching the firmware node for the current Fman, but we don't have that
107585 + * information any more, so we assume that there is only one firmware node in
107586 + * the device tree, and that all Fmen use the same firmware.
107587 + */
107588 +static const struct qe_firmware *FindFmanMicrocode(void)
107589 +{
107590 + static const struct qe_firmware *P4080_UCPatch;
107591 + struct device_node *np;
107592 +
107593 + if (P4080_UCPatch)
107594 + return P4080_UCPatch;
107595 +
107596 + /* The firmware should be inside the device tree. */
107597 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107598 + if (np) {
107599 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107600 + of_node_put(np);
107601 + if (P4080_UCPatch)
107602 + return P4080_UCPatch;
107603 + else
107604 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107605 + }
107606 +
107607 + /* Returning NULL here forces the reuse of the IRAM content */
107608 + return NULL;
107609 +}
107610 +#define SVR_SECURITY_MASK 0x00080000
107611 +#define SVR_PERSONALITY_MASK 0x0000FF00
107612 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107613 +#define SVR_B4860_REV1_VALUE 0x86800010
107614 +#define SVR_B4860_REV2_VALUE 0x86800020
107615 +#define SVR_T4240_VALUE 0x82400000
107616 +#define SVR_T4120_VALUE 0x82400100
107617 +#define SVR_T4160_VALUE 0x82410000
107618 +#define SVR_T4080_VALUE 0x82410200
107619 +#define SVR_T4_DEVICE_ID 0x82400000
107620 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107621 +
107622 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107623 +
107624 +/* searches for a subnode with the given name/compatible */
107625 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107626 + struct of_device_id *ids,
107627 + const char *name,
107628 + const char *compatible)
107629 +{
107630 + struct device_node *dev_node;
107631 + bool ret = false;
107632 +
107633 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107634 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107635 + return false;
107636 + strcpy(ids[0].name, name);
107637 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107638 + return false;
107639 + strcpy(ids[0].compatible, compatible);
107640 + for_each_child_of_node(fm_node, dev_node)
107641 + if (of_match_node(ids, dev_node) != NULL)
107642 + ret = true;
107643 + return ret;
107644 +}
107645 +
107646 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107647 +{
107648 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107649 + struct device_node *fm_node, *dev_node;
107650 + struct of_device_id ids[OF_DEV_ID_NUM];
107651 + struct resource res;
107652 + struct clk *clk;
107653 + u32 clk_rate;
107654 + const uint32_t *uint32_prop;
107655 + int _errno=0, lenp;
107656 + uint32_t tmp_prop;
107657 +
107658 + fm_node = of_node_get(of_dev->dev.of_node);
107659 +
107660 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107661 + if (unlikely(uint32_prop == NULL)) {
107662 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107663 + return NULL;
107664 + }
107665 + tmp_prop = be32_to_cpu(*uint32_prop);
107666 +
107667 + if (WARN_ON(lenp != sizeof(uint32_t)))
107668 + return NULL;
107669 +
107670 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107671 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107672 + return NULL;
107673 + }
107674 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107675 + if (!p_LnxWrpFmDev) {
107676 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107677 + return NULL;
107678 + }
107679 + p_LnxWrpFmDev->dev = &of_dev->dev;
107680 + p_LnxWrpFmDev->id = tmp_prop;
107681 +
107682 + /* Get the FM interrupt */
107683 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107684 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107685 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107686 + DestroyFmDev(p_LnxWrpFmDev);
107687 + return NULL;
107688 + }
107689 +
107690 + /* Get the FM error interrupt */
107691 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107692 +
107693 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107694 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107695 + DestroyFmDev(p_LnxWrpFmDev);
107696 + return NULL;
107697 + }
107698 +
107699 + /* Get the FM address */
107700 + _errno = of_address_to_resource(fm_node, 0, &res);
107701 + if (unlikely(_errno < 0)) {
107702 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107703 + DestroyFmDev(p_LnxWrpFmDev);
107704 + return NULL;
107705 + }
107706 +
107707 +
107708 + p_LnxWrpFmDev->fmBaseAddr = 0;
107709 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107710 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107711 +
107712 + clk = of_clk_get(fm_node, 0);
107713 + if (IS_ERR(clk)) {
107714 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107715 + __func__);
107716 + of_node_put(fm_node);
107717 + DestroyFmDev(p_LnxWrpFmDev);
107718 + return NULL;
107719 + }
107720 +
107721 + clk_rate = clk_get_rate(clk);
107722 + if (!clk_rate) {
107723 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107724 + __func__);
107725 + of_node_put(fm_node);
107726 + DestroyFmDev(p_LnxWrpFmDev);
107727 + return NULL;
107728 + }
107729 +
107730 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107731 + /* Get the MURAM base address and size */
107732 + memset(ids, 0, sizeof(ids));
107733 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107734 + return NULL;
107735 + strcpy(ids[0].name, "muram");
107736 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107737 + return NULL;
107738 + strcpy(ids[0].compatible, "fsl,fman-muram");
107739 + for_each_child_of_node(fm_node, dev_node) {
107740 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107741 + _errno = of_address_to_resource(dev_node, 0, &res);
107742 + if (unlikely(_errno < 0)) {
107743 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107744 + DestroyFmDev(p_LnxWrpFmDev);
107745 + return NULL;
107746 + }
107747 +
107748 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107749 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107750 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107751 +
107752 +#ifndef CONFIG_FMAN_ARM
107753 + {
107754 + uint32_t svr;
107755 + svr = mfspr(SPRN_SVR);
107756 +
107757 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107758 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107759 + }
107760 +#endif
107761 + }
107762 + }
107763 +
107764 + /* Get the RTC base address and size */
107765 + memset(ids, 0, sizeof(ids));
107766 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107767 + return NULL;
107768 + strcpy(ids[0].name, "ptp-timer");
107769 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107770 + return NULL;
107771 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107772 + for_each_child_of_node(fm_node, dev_node) {
107773 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107774 + _errno = of_address_to_resource(dev_node, 0, &res);
107775 + if (unlikely(_errno < 0)) {
107776 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107777 + DestroyFmDev(p_LnxWrpFmDev);
107778 + return NULL;
107779 + }
107780 +
107781 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107782 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107783 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107784 + }
107785 + }
107786 +
107787 +#if (DPAA_VERSION >= 11)
107788 + /* Get the VSP base address */
107789 + for_each_child_of_node(fm_node, dev_node) {
107790 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107791 + _errno = of_address_to_resource(dev_node, 0, &res);
107792 + if (unlikely(_errno < 0)) {
107793 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107794 + DestroyFmDev(p_LnxWrpFmDev);
107795 + return NULL;
107796 + }
107797 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107798 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107799 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107800 + }
107801 + }
107802 +#endif
107803 +
107804 + /* Get all PCD nodes */
107805 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107806 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107807 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107808 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107809 +
107810 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107811 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107812 + p_LnxWrpFmDev->pcdActive = TRUE;
107813 +
107814 + if (p_LnxWrpFmDev->pcdActive)
107815 + {
107816 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107817 + if (str_prop) {
107818 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107819 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107820 + }
107821 + else
107822 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107823 + }
107824 +
107825 + of_node_put(fm_node);
107826 +
107827 + p_LnxWrpFmDev->hcCh =
107828 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107829 +
107830 + p_LnxWrpFmDev->active = TRUE;
107831 +
107832 + return p_LnxWrpFmDev;
107833 +}
107834 +
107835 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107836 +{
107837 + struct device_node *dev_node;
107838 + const uint32_t *uint32_prop;
107839 + int lenp;
107840 + uint32_t tmp_prop;
107841 +
107842 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
107843 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
107844 + if (unlikely(uint32_prop == NULL)) {
107845 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
107846 + ("of_get_property(%s, cell-index) failed",
107847 + dev_node->full_name));
107848 + return NULL;
107849 + }
107850 + tmp_prop = be32_to_cpu(*uint32_prop);
107851 + if (WARN_ON(lenp != sizeof(uint32_t)))
107852 + return NULL;
107853 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107854 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107855 + return NULL;
107856 + }
107857 + if (fmIndx == tmp_prop)
107858 + return dev_node;
107859 + }
107860 +
107861 + return NULL;
107862 +}
107863 +
107864 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
107865 +{
107866 + struct device_node *dev_node;
107867 + t_Error err = E_INVALID_VALUE;
107868 + const uint32_t *uint32_prop;
107869 + const char *str_prop;
107870 + int lenp;
107871 + uint32_t tmp_prop;
107872 +
107873 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
107874 + if (!dev_node) /* no advance parameters for FMan */
107875 + return E_OK;
107876 +
107877 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
107878 + if (str_prop) {
107879 + if (strcmp(str_prop, "port") == 0)
107880 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
107881 + else if (strcmp(str_prop, "tnum") == 0)
107882 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
107883 +
107884 + if (err != E_OK)
107885 + RETURN_ERROR(MINOR, err, NO_MSG);
107886 + }
107887 +
107888 + uint32_prop = (uint32_t *)of_get_property(dev_node,
107889 + "total-fifo-size", &lenp);
107890 + if (uint32_prop) {
107891 + tmp_prop = be32_to_cpu(*uint32_prop);
107892 + if (WARN_ON(lenp != sizeof(uint32_t)))
107893 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107894 +
107895 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
107896 + tmp_prop) != E_OK)
107897 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107898 + }
107899 +
107900 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
107901 + &lenp);
107902 + if (uint32_prop) {
107903 + tmp_prop = be32_to_cpu(*uint32_prop);
107904 + if (WARN_ON(lenp != sizeof(uint32_t)))
107905 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107906 +
107907 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
107908 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
107909 +
107910 + if (err != E_OK)
107911 + RETURN_ERROR(MINOR, err, NO_MSG);
107912 + }
107913 +
107914 + of_node_put(dev_node);
107915 +
107916 + return E_OK;
107917 +}
107918 +
107919 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
107920 +{
107921 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107922 +
107923 + ASSERT_COND(p_LnxWrpFmDev);
107924 +
107925 + DBG(INFO, ("got fm exception %d", exception));
107926 +
107927 + /* do nothing */
107928 + UNUSED(exception);
107929 +}
107930 +
107931 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
107932 + e_FmPortType portType,
107933 + uint8_t portId,
107934 + uint64_t addr,
107935 + uint8_t tnum,
107936 + uint16_t liodn)
107937 +{
107938 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107939 +
107940 + ASSERT_COND(p_LnxWrpFmDev);
107941 +
107942 + /* do nothing */
107943 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
107944 +}
107945 +
107946 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107947 +{
107948 + struct resource *dev_res;
107949 + int _errno;
107950 +
107951 + if (!p_LnxWrpFmDev->active)
107952 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107953 +
107954 +#ifndef MODULE
107955 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
107956 + if (unlikely(_errno < 0))
107957 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107958 +#endif
107959 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
107960 + if (unlikely(_errno < 0))
107961 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
107962 +
107963 + enable_irq_wake(p_LnxWrpFmDev->irq);
107964 +
107965 + if (p_LnxWrpFmDev->err_irq != 0) {
107966 +#ifndef MODULE
107967 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
107968 + if (unlikely(_errno < 0))
107969 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107970 +#endif
107971 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
107972 + if (unlikely(_errno < 0))
107973 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
107974 +
107975 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
107976 + }
107977 +
107978 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
107979 + if (unlikely(p_LnxWrpFmDev->res == NULL))
107980 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
107981 +
107982 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
107983 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
107984 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107985 +
107986 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
107987 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
107988 +
107989 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
107990 + if (unlikely(dev_res == NULL))
107991 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107992 +
107993 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
107994 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
107995 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107996 +
107997 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
107998 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
107999 +
108000 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
108001 + {
108002 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
108003 + if (unlikely(dev_res == NULL))
108004 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
108005 +
108006 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
108007 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
108008 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108009 +
108010 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
108011 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
108012 + }
108013 +
108014 +#if (DPAA_VERSION >= 11)
108015 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
108016 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
108017 + if (unlikely(dev_res == NULL))
108018 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
108019 +
108020 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
108021 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
108022 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108023 + }
108024 +#endif
108025 +
108026 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
108027 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
108028 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
108029 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
108030 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
108031 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
108032 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
108033 +
108034 + return FillRestFmInfo(p_LnxWrpFmDev);
108035 +}
108036 +
108037 +#ifndef CONFIG_FMAN_ARM
108038 +/*
108039 + * Table for matching compatible strings, for device tree
108040 + * guts node, for QorIQ SOCs.
108041 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
108042 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
108043 + * string would be used.
108044 +*/
108045 +static const struct of_device_id guts_device_ids[] = {
108046 + { .compatible = "fsl,qoriq-device-config-1.0", },
108047 + { .compatible = "fsl,qoriq-device-config-2.0", },
108048 + {}
108049 +};
108050 +
108051 +static unsigned int get_rcwsr(int regnum)
108052 +{
108053 + struct ccsr_guts __iomem *guts_regs = NULL;
108054 + struct device_node *guts_node;
108055 +
108056 + guts_node = of_find_matching_node(NULL, guts_device_ids);
108057 + if (!guts_node) {
108058 + pr_err("could not find GUTS node\n");
108059 + return 0;
108060 + }
108061 + guts_regs = of_iomap(guts_node, 0);
108062 + of_node_put(guts_node);
108063 + if (!guts_regs) {
108064 + pr_err("ioremap of GUTS node failed\n");
108065 + return 0;
108066 + }
108067 +
108068 + return ioread32be(&guts_regs->rcwsr[regnum]);
108069 +}
108070 +
108071 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
108072 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
108073 +
108074 +/**
108075 + * @Function ResetOnInitErrata_A007273
108076 + *
108077 + * @Description Workaround for Errata A-007273
108078 + * This workaround is required to avoid a FMan hang during reset on initialization.
108079 + * Enable all MACs in guts.devdisr2 register,
108080 + * then perform a regular FMan reset and then restore MACs to their original state.
108081 + *
108082 + * @Param[in] h_Fm - FM module descriptor
108083 + *
108084 + * @Return None.
108085 + */
108086 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
108087 +{
108088 + struct ccsr_guts __iomem *guts_regs = NULL;
108089 + struct device_node *guts_node;
108090 + u32 devdisr2, enableMacs;
108091 +
108092 + /* Get guts registers */
108093 + guts_node = of_find_matching_node(NULL, guts_device_ids);
108094 + if (!guts_node) {
108095 + pr_err("could not find GUTS node\n");
108096 + return;
108097 + }
108098 + guts_regs = of_iomap(guts_node, 0);
108099 + of_node_put(guts_node);
108100 + if (!guts_regs) {
108101 + pr_err("ioremap of GUTS node failed\n");
108102 + return;
108103 + }
108104 +
108105 + /* Read current state */
108106 + devdisr2 = ioread32be(&guts_regs->devdisr2);
108107 +
108108 + if (FmGetId(h_Fm) == 0)
108109 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
108110 + else
108111 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
108112 +
108113 + /* Enable all MACs */
108114 + iowrite32be(enableMacs, &guts_regs->devdisr2);
108115 +
108116 + /* Perform standard FMan reset */
108117 + FmReset(h_Fm);
108118 +
108119 + /* Restore devdisr2 value */
108120 + iowrite32be(devdisr2, &guts_regs->devdisr2);
108121 +
108122 + iounmap(guts_regs);
108123 +}
108124 +#endif
108125 +
108126 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108127 +{
108128 + const struct qe_firmware *fw;
108129 +
108130 + if (!p_LnxWrpFmDev->active)
108131 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
108132 +
108133 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
108134 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
108135 +
108136 + /* Loading the fman-controller code */
108137 + fw = FindFmanMicrocode();
108138 +
108139 + if (!fw) {
108140 + /* this forces the reuse of the current IRAM content */
108141 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
108142 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
108143 + } else {
108144 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
108145 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
108146 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
108147 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
108148 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
108149 + fw->microcode[0].major,
108150 + fw->microcode[0].minor,
108151 + fw->microcode[0].revision));
108152 + }
108153 +
108154 +#ifdef CONFIG_FMAN_ARM
108155 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
108156 + int i;
108157 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
108158 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
108159 + u32 *dest = kzalloc(usz, GFP_KERNEL);
108160 +
108161 + if (p_Code && dest)
108162 + for(i=0; i < usz / 4; ++i)
108163 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
108164 +
108165 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
108166 + }
108167 +#endif
108168 +
108169 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
108170 +
108171 +#if (DPAA_VERSION >= 11)
108172 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
108173 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
108174 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
108175 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
108176 + }
108177 +#endif
108178 +
108179 +#ifdef CONFIG_FMAN_ARM
108180 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
108181 +#else
108182 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
108183 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
108184 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
108185 + else
108186 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
108187 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
108188 +
108189 + {
108190 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
108191 + uint32_t svr;
108192 + svr = mfspr(SPRN_SVR);
108193 +
108194 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
108195 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
108196 + }
108197 +#endif /* CONFIG_FMAN_ARM */
108198 +
108199 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
108200 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
108201 +
108202 +
108203 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108204 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108205 +
108206 +#ifndef CONFIG_FMAN_ARM
108207 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
108208 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
108209 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108210 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
108211 +#endif /* CONFIG_FMAN_ARM */
108212 +
108213 +#ifdef CONFIG_FMAN_P1023
108214 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108215 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108216 +#endif
108217 +
108218 +
108219 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
108220 +
108221 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
108222 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108223 +
108224 + /* TODO: Why we mask these interrupts? */
108225 + if (p_LnxWrpFmDev->err_irq == 0) {
108226 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
108227 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
108228 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
108229 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
108230 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
108231 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
108232 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
108233 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
108234 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
108235 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
108236 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
108237 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
108238 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
108239 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
108240 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
108241 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
108242 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
108243 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
108244 + }
108245 +
108246 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108247 + {
108248 + t_FmRtcParams fmRtcParam;
108249 +
108250 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
108251 + fmRtcParam.h_App = p_LnxWrpFmDev;
108252 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
108253 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
108254 +
108255 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
108256 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
108257 +
108258 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
108259 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108260 +
108261 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
108262 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108263 + }
108264 +
108265 + return E_OK;
108266 +}
108267 +
108268 +/* TODO: to be moved back here */
108269 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
108270 +
108271 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108272 +{
108273 + if (!p_LnxWrpFmDev->active)
108274 + return;
108275 +
108276 + FreeFmPcdDev(p_LnxWrpFmDev);
108277 +
108278 + if (p_LnxWrpFmDev->h_RtcDev)
108279 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
108280 +
108281 + if (p_LnxWrpFmDev->h_Dev)
108282 + FM_Free(p_LnxWrpFmDev->h_Dev);
108283 +
108284 + if (p_LnxWrpFmDev->h_MuramDev)
108285 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
108286 +
108287 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108288 + {
108289 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
108290 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
108291 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
108292 + }
108293 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
108294 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
108295 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
108296 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
108297 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
108298 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
108299 + if (p_LnxWrpFmDev->err_irq != 0) {
108300 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
108301 + }
108302 +
108303 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
108304 +}
108305 +
108306 +/* FMan character device file operations */
108307 +extern struct file_operations fm_fops;
108308 +
108309 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
108310 +{
108311 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108312 +
108313 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
108314 + return -EIO;
108315 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
108316 + return -EIO;
108317 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
108318 + return -EIO;
108319 +
108320 + /* IOCTL ABI checking */
108321 + LnxWrpPCDIOCTLEnumChecking();
108322 + LnxWrpPCDIOCTLTypeChecking();
108323 +
108324 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
108325 +
108326 + /* Register to the /dev for IOCTL API */
108327 + /* Register dynamically a new major number for the character device: */
108328 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
108329 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
108330 + return -EIO;
108331 + }
108332 +
108333 + /* Creating classes for FM */
108334 + DBG(TRACE ,("class_create fm_class"));
108335 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
108336 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
108337 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108338 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
108339 + return -EIO;
108340 + }
108341 +
108342 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
108343 + "fm%d", p_LnxWrpFmDev->id);
108344 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
108345 + "fm%d-pcd", p_LnxWrpFmDev->id);
108346 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
108347 +
108348 + /* create sysfs entries for stats and regs */
108349 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
108350 + {
108351 + FreeFmDev(p_LnxWrpFmDev);
108352 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
108353 + return -EIO;
108354 + }
108355 +
108356 +#ifdef CONFIG_PM
108357 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
108358 +#endif
108359 +
108360 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
108361 +
108362 + return 0;
108363 +}
108364 +
108365 +static int fm_remove(struct platform_device *of_dev)
108366 +{
108367 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108368 + struct device *dev;
108369 +
108370 + dev = &of_dev->dev;
108371 + p_LnxWrpFmDev = dev_get_drvdata(dev);
108372 +
108373 + fm_sysfs_destroy(dev);
108374 +
108375 + DBG(TRACE, ("destroy fm_class"));
108376 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
108377 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
108378 + class_destroy(p_LnxWrpFmDev->fm_class);
108379 +
108380 + /* Destroy chardev */
108381 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108382 +
108383 + FreeFmDev(p_LnxWrpFmDev);
108384 +
108385 + DestroyFmDev(p_LnxWrpFmDev);
108386 +
108387 + dev_set_drvdata(dev, NULL);
108388 +
108389 + return 0;
108390 +}
108391 +
108392 +static const struct of_device_id fm_match[] = {
108393 + {
108394 + .compatible = "fsl,fman"
108395 + },
108396 + {}
108397 +};
108398 +#ifndef MODULE
108399 +MODULE_DEVICE_TABLE(of, fm_match);
108400 +#endif /* !MODULE */
108401 +
108402 +#ifdef CONFIG_PM
108403 +
108404 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
108405 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
108406 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
108407 +
108408 +struct device *g_fm_dev;
108409 +
108410 +static int fm_soc_suspend(struct device *dev)
108411 +{
108412 + int err = 0;
108413 + uint32_t *fmclk;
108414 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108415 + g_fm_dev = dev;
108416 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108417 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
108418 + if (p_LnxWrpFmDev->h_DsarRxPort)
108419 + {
108420 +#ifdef CONFIG_FSL_QORIQ_PM
108421 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
108422 +#endif
108423 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
108424 + p_LnxWrpFmDev->h_DsarTxPort);
108425 + }
108426 + return err;
108427 +}
108428 +
108429 +static int fm_soc_resume(struct device *dev)
108430 +{
108431 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108432 + uint32_t *fmclk;
108433 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108434 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
108435 + if (p_LnxWrpFmDev->h_DsarRxPort)
108436 + {
108437 +#ifdef CONFIG_FSL_QORIQ_PM
108438 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
108439 +#endif
108440 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
108441 + p_LnxWrpFmDev->h_DsarTxPort);
108442 + p_LnxWrpFmDev->h_DsarRxPort = 0;
108443 + p_LnxWrpFmDev->h_DsarTxPort = 0;
108444 + }
108445 + return 0;
108446 +}
108447 +
108448 +static const struct dev_pm_ops fm_pm_ops = {
108449 + .suspend = fm_soc_suspend,
108450 + .resume = fm_soc_resume,
108451 +};
108452 +
108453 +#define FM_PM_OPS (&fm_pm_ops)
108454 +
108455 +#else /* CONFIG_PM */
108456 +
108457 +#define FM_PM_OPS NULL
108458 +
108459 +#endif /* CONFIG_PM */
108460 +
108461 +static struct platform_driver fm_driver = {
108462 + .driver = {
108463 + .name = "fsl-fman",
108464 + .of_match_table = fm_match,
108465 + .owner = THIS_MODULE,
108466 + .pm = FM_PM_OPS,
108467 + },
108468 + .probe = fm_probe,
108469 + .remove = fm_remove
108470 +};
108471 +
108472 +t_Handle LNXWRP_FM_Init(void)
108473 +{
108474 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
108475 + mutex_init(&lnxwrp_mutex);
108476 +
108477 + /* Register to the DTB for basic FM API */
108478 + platform_driver_register(&fm_driver);
108479 +
108480 + return &lnxWrpFm;
108481 +}
108482 +
108483 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
108484 +{
108485 + platform_driver_unregister(&fm_driver);
108486 + mutex_destroy(&lnxwrp_mutex);
108487 +
108488 + return E_OK;
108489 +}
108490 +
108491 +
108492 +struct fm * fm_bind(struct device *fm_dev)
108493 +{
108494 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
108495 +}
108496 +EXPORT_SYMBOL(fm_bind);
108497 +
108498 +void fm_unbind(struct fm *fm)
108499 +{
108500 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108501 +
108502 + put_device(p_LnxWrpFmDev->dev);
108503 +}
108504 +EXPORT_SYMBOL(fm_unbind);
108505 +
108506 +struct resource * fm_get_mem_region(struct fm *fm)
108507 +{
108508 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108509 +
108510 + return p_LnxWrpFmDev->res;
108511 +}
108512 +EXPORT_SYMBOL(fm_get_mem_region);
108513 +
108514 +void * fm_get_handle(struct fm *fm)
108515 +{
108516 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108517 +
108518 + return (void *)p_LnxWrpFmDev->h_Dev;
108519 +}
108520 +EXPORT_SYMBOL(fm_get_handle);
108521 +
108522 +void * fm_get_rtc_handle(struct fm *fm)
108523 +{
108524 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108525 +
108526 + return (void *)p_LnxWrpFmDev->h_RtcDev;
108527 +}
108528 +EXPORT_SYMBOL(fm_get_rtc_handle);
108529 +
108530 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
108531 +{
108532 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
108533 +}
108534 +EXPORT_SYMBOL(fm_port_bind);
108535 +
108536 +void fm_port_unbind(struct fm_port *port)
108537 +{
108538 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108539 +
108540 + put_device(p_LnxWrpFmPortDev->dev);
108541 +}
108542 +EXPORT_SYMBOL(fm_port_unbind);
108543 +
108544 +void *fm_port_get_handle(const struct fm_port *port)
108545 +{
108546 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108547 +
108548 + return (void *)p_LnxWrpFmPortDev->h_Dev;
108549 +}
108550 +EXPORT_SYMBOL(fm_port_get_handle);
108551 +
108552 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
108553 + const void *data)
108554 +{
108555 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
108556 + (void *)data);
108557 +}
108558 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
108559 +
108560 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
108561 +{
108562 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108563 +
108564 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
108565 +}
108566 +EXPORT_SYMBOL(fm_port_get_base_addr);
108567 +
108568 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
108569 +{
108570 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108571 +
108572 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
108573 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
108574 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
108575 +}
108576 +EXPORT_SYMBOL(fm_port_pcd_bind);
108577 +
108578 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108579 +{
108580 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108581 + struct device_node *fm_node, *port_node;
108582 + const uint32_t *uint32_prop;
108583 + int lenp;
108584 +
108585 + params->data_align = 0;
108586 + params->manip_extra_space = 0;
108587 +
108588 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108589 + if (!fm_node) /* no advance parameters for FMan */
108590 + return;
108591 +
108592 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108593 + p_LnxWrpFmPortDev->settings.param.portType,
108594 + p_LnxWrpFmPortDev->settings.param.portId);
108595 + if (!port_node) /* no advance parameters for FMan-Port */
108596 + return;
108597 +
108598 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108599 + if (uint32_prop) {
108600 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108601 + return;
108602 +
108603 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108604 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108605 + }
108606 +
108607 + of_node_put(port_node);
108608 + of_node_put(fm_node);
108609 +}
108610 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108611 +
108612 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108613 +{
108614 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108615 +
108616 + return p_LnxWrpFmPortDev->txCh;
108617 +}
108618 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108619 +
108620 +int fm_port_enable (struct fm_port *port)
108621 +{
108622 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108623 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108624 +
108625 + return GET_ERROR_TYPE(err);
108626 +}
108627 +EXPORT_SYMBOL(fm_port_enable);
108628 +
108629 +int fm_port_disable(struct fm_port *port)
108630 +{
108631 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108632 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108633 +
108634 + return GET_ERROR_TYPE(err);
108635 +}
108636 +EXPORT_SYMBOL(fm_port_disable);
108637 +
108638 +int fm_port_set_rate_limit(struct fm_port *port,
108639 + uint16_t max_burst_size,
108640 + uint32_t rate_limit)
108641 +{
108642 + t_FmPortRateLimit param;
108643 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108644 + int err = 0;
108645 +
108646 + param.maxBurstSize = max_burst_size;
108647 + param.rateLimit = rate_limit;
108648 + param.rateLimitDivider = 0;
108649 +
108650 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108651 + return err;
108652 +}
108653 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108654 +
108655 +int fm_port_del_rate_limit(struct fm_port *port)
108656 +{
108657 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108658 +
108659 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108660 + return 0;
108661 +}
108662 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108663 +
108664 +void FM_PORT_Dsar_DumpRegs(void);
108665 +int ar_showmem(struct file *file, const char __user *buffer,
108666 + unsigned long count, void *data)
108667 +{
108668 + FM_PORT_Dsar_DumpRegs();
108669 + return 2;
108670 +}
108671 +
108672 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108673 + struct fm_port *port)
108674 +{
108675 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108676 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108677 +}
108678 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108679 +
108680 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108681 + struct auto_res_port_params *params)
108682 +{
108683 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108684 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108685 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108686 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108687 +
108688 + /*Register other under /proc/autoresponse */
108689 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108690 + return -EFAULT;
108691 +
108692 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108693 + return 0;
108694 +}
108695 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108696 +
108697 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108698 + struct fm_port *port_tx)
108699 +{
108700 +}
108701 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108702 +
108703 +int fm_port_get_autores_stats(struct fm_port *port,
108704 + struct auto_res_port_stats *stats)
108705 +{
108706 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108707 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108708 + return -EFAULT;
108709 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108710 +}
108711 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108712 +
108713 +int fm_port_suspend(struct fm_port *port)
108714 +{
108715 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108716 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108717 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108718 + else
108719 + return 0;
108720 +}
108721 +EXPORT_SYMBOL(fm_port_suspend);
108722 +
108723 +int fm_port_resume(struct fm_port *port)
108724 +{
108725 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108726 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108727 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108728 + else
108729 + return 0;
108730 +}
108731 +EXPORT_SYMBOL(fm_port_resume);
108732 +
108733 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108734 +{
108735 + return FM_PORT_IsInDsar(port);
108736 +}
108737 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108738 +
108739 +#ifdef CONFIG_FMAN_PFC
108740 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108741 + uint8_t prio, uint8_t wq)
108742 +{
108743 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108744 + int err;
108745 + int _errno;
108746 +
108747 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108748 + prio, wq);
108749 + _errno = -GET_ERROR_TYPE(err);
108750 + if (unlikely(_errno < 0))
108751 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108752 +
108753 + return _errno;
108754 +}
108755 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108756 +#endif
108757 +
108758 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108759 + e_FmMacExceptions exception, bool enable)
108760 +{
108761 + int err;
108762 + int _errno;
108763 +
108764 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108765 +
108766 + _errno = -GET_ERROR_TYPE(err);
108767 + if (unlikely(_errno < 0))
108768 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108769 +
108770 + return _errno;
108771 +}
108772 +EXPORT_SYMBOL(fm_mac_set_exception);
108773 +
108774 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108775 +{
108776 + int err;
108777 + int _error;
108778 +
108779 + err = FM_MAC_Free(fm_mac_dev);
108780 + _error = -GET_ERROR_TYPE(err);
108781 +
108782 + if (unlikely(_error < 0))
108783 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108784 +
108785 + return _error;
108786 +}
108787 +EXPORT_SYMBOL(fm_mac_free);
108788 +
108789 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108790 +{
108791 + struct fm_mac_dev *fm_mac_dev;
108792 +
108793 + fm_mac_dev = FM_MAC_Config(params);
108794 + if (unlikely(fm_mac_dev == NULL))
108795 + pr_err("FM_MAC_Config() failed\n");
108796 +
108797 + return fm_mac_dev;
108798 +}
108799 +EXPORT_SYMBOL(fm_mac_config);
108800 +
108801 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108802 + int len)
108803 +{
108804 + int err;
108805 + int _errno;
108806 +
108807 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108808 + _errno = -GET_ERROR_TYPE(err);
108809 + if (unlikely(_errno < 0))
108810 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108811 +
108812 + return _errno;
108813 +}
108814 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108815 +
108816 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108817 +{
108818 + int err;
108819 + int _errno;
108820 +
108821 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108822 + _errno = -GET_ERROR_TYPE(err);
108823 + if (unlikely(_errno < 0))
108824 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108825 +
108826 + return _errno;
108827 +}
108828 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108829 +
108830 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108831 +{
108832 + int err;
108833 + int _errno;
108834 +
108835 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108836 + _errno = -GET_ERROR_TYPE(err);
108837 + if (unlikely(_errno < 0))
108838 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
108839 +
108840 + return _errno;
108841 +}
108842 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
108843 +
108844 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
108845 +{
108846 + int err;
108847 + int _errno;
108848 +
108849 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
108850 + _errno = -GET_ERROR_TYPE(err);
108851 + if (unlikely(_errno < 0))
108852 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
108853 +
108854 + return _errno;
108855 +}
108856 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
108857 +
108858 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
108859 +{
108860 + int err;
108861 + int _errno;
108862 +
108863 + err = FM_MAC_Init(fm_mac_dev);
108864 + _errno = -GET_ERROR_TYPE(err);
108865 + if (unlikely(_errno < 0))
108866 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
108867 +
108868 + return _errno;
108869 +}
108870 +EXPORT_SYMBOL(fm_mac_init);
108871 +
108872 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
108873 +{
108874 + int err;
108875 + int _errno;
108876 +
108877 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
108878 + _errno = -GET_ERROR_TYPE(err);
108879 + if (unlikely(_errno < 0))
108880 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
108881 +
108882 + return _errno;
108883 +}
108884 +EXPORT_SYMBOL(fm_mac_get_version);
108885 +
108886 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
108887 +{
108888 + int _errno;
108889 + t_Error err;
108890 +
108891 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108892 + _errno = -GET_ERROR_TYPE(err);
108893 + if (unlikely(_errno < 0))
108894 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
108895 +
108896 + return _errno;
108897 +}
108898 +EXPORT_SYMBOL(fm_mac_enable);
108899 +
108900 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
108901 +{
108902 + int _errno;
108903 + t_Error err;
108904 +
108905 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108906 + _errno = -GET_ERROR_TYPE(err);
108907 + if (unlikely(_errno < 0))
108908 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
108909 +
108910 + return _errno;
108911 +}
108912 +EXPORT_SYMBOL(fm_mac_disable);
108913 +
108914 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
108915 +{
108916 + int _errno;
108917 + t_Error err;
108918 +
108919 + err = FM_MAC_Resume(fm_mac_dev);
108920 + _errno = -GET_ERROR_TYPE(err);
108921 + if (unlikely(_errno < 0))
108922 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
108923 +
108924 + return _errno;
108925 +}
108926 +EXPORT_SYMBOL(fm_mac_resume);
108927 +
108928 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
108929 + bool enable)
108930 +{
108931 + int _errno;
108932 + t_Error err;
108933 +
108934 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
108935 + _errno = -GET_ERROR_TYPE(err);
108936 + if (unlikely(_errno < 0))
108937 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
108938 +
108939 + return _errno;
108940 +}
108941 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
108942 +
108943 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108944 + t_EnetAddr *mac_addr)
108945 +{
108946 + int _errno;
108947 + t_Error err;
108948 +
108949 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
108950 + _errno = -GET_ERROR_TYPE(err);
108951 + if (_errno < 0) {
108952 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
108953 + return _errno;
108954 + }
108955 +
108956 + return 0;
108957 +}
108958 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
108959 +
108960 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108961 + t_EnetAddr *mac_addr)
108962 +{
108963 + int _errno;
108964 + t_Error err;
108965 +
108966 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
108967 + _errno = -GET_ERROR_TYPE(err);
108968 + if (_errno < 0) {
108969 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
108970 + return _errno;
108971 + }
108972 +
108973 + return 0;
108974 +}
108975 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
108976 +
108977 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
108978 + uint8_t *addr)
108979 +{
108980 + int _errno;
108981 + t_Error err;
108982 +
108983 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
108984 + _errno = -GET_ERROR_TYPE(err);
108985 + if (_errno < 0)
108986 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
108987 +
108988 + return _errno;
108989 +}
108990 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
108991 +
108992 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
108993 + bool link, int speed, bool duplex)
108994 +{
108995 + int _errno;
108996 + t_Error err;
108997 +
108998 + if (!link) {
108999 +#if (DPAA_VERSION < 11)
109000 + FM_MAC_RestartAutoneg(fm_mac_dev);
109001 +#endif
109002 + return 0;
109003 + }
109004 +
109005 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
109006 + _errno = -GET_ERROR_TYPE(err);
109007 + if (unlikely(_errno < 0))
109008 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
109009 +
109010 + return _errno;
109011 +}
109012 +EXPORT_SYMBOL(fm_mac_adjust_link);
109013 +
109014 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
109015 +{
109016 + int _errno;
109017 + t_Error err;
109018 +
109019 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
109020 + _errno = -GET_ERROR_TYPE(err);
109021 + if (unlikely(_errno < 0))
109022 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
109023 + return _errno;
109024 +}
109025 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
109026 +
109027 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
109028 +{
109029 + int _errno;
109030 + t_Error err;
109031 +
109032 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
109033 + _errno = -GET_ERROR_TYPE(err);
109034 + if (unlikely(_errno < 0))
109035 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
109036 + return _errno;
109037 +}
109038 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
109039 +
109040 +int fm_mac_set_rx_pause_frames(
109041 + struct fm_mac_dev *fm_mac_dev, bool en)
109042 +{
109043 + int _errno;
109044 + t_Error err;
109045 +
109046 + /* if rx pause is enabled, do NOT ignore pause frames */
109047 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
109048 +
109049 + _errno = -GET_ERROR_TYPE(err);
109050 + if (_errno < 0)
109051 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
109052 +
109053 + return _errno;
109054 +}
109055 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
109056 +
109057 +#ifdef CONFIG_FMAN_PFC
109058 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
109059 + bool en)
109060 +{
109061 + int _errno, i;
109062 + t_Error err;
109063 +
109064 + if (en)
109065 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
109066 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
109067 + i, fsl_fm_pfc_quanta[i],
109068 + FSL_FM_PAUSE_THRESH_DEFAULT);
109069 + _errno = -GET_ERROR_TYPE(err);
109070 + if (_errno < 0) {
109071 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
109072 + return _errno;
109073 + }
109074 + }
109075 + else
109076 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
109077 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
109078 + i, FSL_FM_PAUSE_TIME_DISABLE,
109079 + FSL_FM_PAUSE_THRESH_DEFAULT);
109080 + _errno = -GET_ERROR_TYPE(err);
109081 + if (_errno < 0) {
109082 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
109083 + return _errno;
109084 + }
109085 + }
109086 +
109087 + return _errno;
109088 +}
109089 +#else
109090 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
109091 + bool en)
109092 +{
109093 + int _errno;
109094 + t_Error err;
109095 +
109096 + if (en)
109097 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
109098 + FSL_FM_PAUSE_TIME_ENABLE);
109099 + else
109100 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
109101 + FSL_FM_PAUSE_TIME_DISABLE);
109102 +
109103 + _errno = -GET_ERROR_TYPE(err);
109104 + if (_errno < 0)
109105 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
109106 +
109107 + return _errno;
109108 +}
109109 +#endif
109110 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
109111 +
109112 +int fm_rtc_enable(struct fm *fm_dev)
109113 +{
109114 + int _errno;
109115 + t_Error err;
109116 +
109117 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
109118 + _errno = -GET_ERROR_TYPE(err);
109119 + if (unlikely(_errno < 0))
109120 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
109121 +
109122 + return _errno;
109123 +}
109124 +EXPORT_SYMBOL(fm_rtc_enable);
109125 +
109126 +int fm_rtc_disable(struct fm *fm_dev)
109127 +{
109128 + int _errno;
109129 + t_Error err;
109130 +
109131 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
109132 + _errno = -GET_ERROR_TYPE(err);
109133 + if (unlikely(_errno < 0))
109134 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
109135 +
109136 + return _errno;
109137 +}
109138 +EXPORT_SYMBOL(fm_rtc_disable);
109139 +
109140 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
109141 +{
109142 + int _errno;
109143 + t_Error err;
109144 +
109145 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
109146 + _errno = -GET_ERROR_TYPE(err);
109147 + if (unlikely(_errno < 0))
109148 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
109149 +
109150 + return _errno;
109151 +}
109152 +EXPORT_SYMBOL(fm_rtc_get_cnt);
109153 +
109154 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
109155 +{
109156 + int _errno;
109157 + t_Error err;
109158 +
109159 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
109160 + _errno = -GET_ERROR_TYPE(err);
109161 + if (unlikely(_errno < 0))
109162 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
109163 +
109164 + return _errno;
109165 +}
109166 +EXPORT_SYMBOL(fm_rtc_set_cnt);
109167 +
109168 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
109169 +{
109170 + int _errno;
109171 + t_Error err;
109172 +
109173 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
109174 + drift);
109175 + _errno = -GET_ERROR_TYPE(err);
109176 + if (unlikely(_errno < 0))
109177 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
109178 +
109179 + return _errno;
109180 +}
109181 +EXPORT_SYMBOL(fm_rtc_get_drift);
109182 +
109183 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
109184 +{
109185 + int _errno;
109186 + t_Error err;
109187 +
109188 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
109189 + drift);
109190 + _errno = -GET_ERROR_TYPE(err);
109191 + if (unlikely(_errno < 0))
109192 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
109193 +
109194 + return _errno;
109195 +}
109196 +EXPORT_SYMBOL(fm_rtc_set_drift);
109197 +
109198 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
109199 + uint64_t time)
109200 +{
109201 + t_FmRtcAlarmParams alarm;
109202 + int _errno;
109203 + t_Error err;
109204 +
109205 + alarm.alarmId = id;
109206 + alarm.alarmTime = time;
109207 + alarm.f_AlarmCallback = NULL;
109208 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
109209 + &alarm);
109210 + _errno = -GET_ERROR_TYPE(err);
109211 + if (unlikely(_errno < 0))
109212 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
109213 +
109214 + return _errno;
109215 +}
109216 +EXPORT_SYMBOL(fm_rtc_set_alarm);
109217 +
109218 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
109219 + uint64_t fiper)
109220 +{
109221 + t_FmRtcPeriodicPulseParams pp;
109222 + int _errno;
109223 + t_Error err;
109224 +
109225 + pp.periodicPulseId = id;
109226 + pp.periodicPulsePeriod = fiper;
109227 + pp.f_PeriodicPulseCallback = NULL;
109228 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
109229 + _errno = -GET_ERROR_TYPE(err);
109230 + if (unlikely(_errno < 0))
109231 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
109232 +
109233 + return _errno;
109234 +}
109235 +EXPORT_SYMBOL(fm_rtc_set_fiper);
109236 +
109237 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
109238 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
109239 +{
109240 + int _errno;
109241 + t_Error err;
109242 +
109243 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
109244 + events);
109245 + _errno = -GET_ERROR_TYPE(err);
109246 + if (unlikely(_errno < 0))
109247 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
109248 +
109249 + return _errno;
109250 +}
109251 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
109252 +
109253 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
109254 +{
109255 + int _errno;
109256 + t_Error err;
109257 +
109258 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
109259 + events);
109260 + _errno = -GET_ERROR_TYPE(err);
109261 + if (unlikely(_errno < 0))
109262 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
109263 +
109264 + return _errno;
109265 +}
109266 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
109267 +#endif
109268 +
109269 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
109270 +{
109271 + int _errno;
109272 + t_Error err;
109273 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109274 +
109275 + /* Do not set WoL on AR ports */
109276 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
109277 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
109278 + return 0;
109279 + }
109280 +
109281 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
109282 +
109283 + _errno = -GET_ERROR_TYPE(err);
109284 + if (_errno < 0)
109285 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
109286 +
109287 + return _errno;
109288 +}
109289 +EXPORT_SYMBOL(fm_mac_set_wol);
109290 +
109291 +void fm_mutex_lock(void)
109292 +{
109293 + mutex_lock(&lnxwrp_mutex);
109294 +}
109295 +EXPORT_SYMBOL(fm_mutex_lock);
109296 +
109297 +void fm_mutex_unlock(void)
109298 +{
109299 + mutex_unlock(&lnxwrp_mutex);
109300 +}
109301 +EXPORT_SYMBOL(fm_mutex_unlock);
109302 +
109303 +/*Macsec wrapper functions*/
109304 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
109305 +{
109306 + struct fm_macsec_dev *fm_macsec_dev;
109307 +
109308 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
109309 + if (unlikely(fm_macsec_dev == NULL))
109310 + pr_err("FM_MACSEC_Config() failed\n");
109311 +
109312 + return fm_macsec_dev;
109313 +}
109314 +EXPORT_SYMBOL(fm_macsec_config);
109315 +
109316 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
109317 +{
109318 + int err;
109319 + int _errno;
109320 +
109321 + err = FM_MACSEC_Init(fm_macsec_dev);
109322 + _errno = -GET_ERROR_TYPE(err);
109323 + if (unlikely(_errno < 0))
109324 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
109325 +
109326 + return _errno;
109327 +}
109328 +EXPORT_SYMBOL(fm_macsec_init);
109329 +
109330 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
109331 +{
109332 + int err;
109333 + int _error;
109334 +
109335 + err = FM_MACSEC_Free(fm_macsec_dev);
109336 + _error = -GET_ERROR_TYPE(err);
109337 +
109338 + if (unlikely(_error < 0))
109339 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
109340 +
109341 + return _error;
109342 +}
109343 +EXPORT_SYMBOL(fm_macsec_free);
109344 +
109345 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
109346 + *fm_macsec_dev,
109347 + fm_macsec_unknown_sci_frame_treatment treat_mode)
109348 +{
109349 + int err;
109350 + int _errno;
109351 +
109352 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
109353 + treat_mode);
109354 + _errno = -GET_ERROR_TYPE(err);
109355 + if (unlikely(_errno < 0))
109356 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
109357 +
109358 + return _errno;
109359 +}
109360 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
109361 +
109362 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109363 + bool deliver_uncontrolled)
109364 +{
109365 + int err;
109366 + int _errno;
109367 +
109368 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
109369 + deliver_uncontrolled);
109370 + _errno = -GET_ERROR_TYPE(err);
109371 + if (unlikely(_errno < 0))
109372 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
109373 +
109374 + return _errno;
109375 +}
109376 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
109377 +
109378 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109379 + bool discard_uncontrolled)
109380 +{
109381 + int err;
109382 + int _errno;
109383 +
109384 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
109385 + discard_uncontrolled);
109386 + _errno = -GET_ERROR_TYPE(err);
109387 + if (unlikely(_errno < 0))
109388 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
109389 +
109390 + return _errno;
109391 +}
109392 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
109393 +
109394 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109395 + fm_macsec_untag_frame_treatment treat_mode)
109396 +{
109397 + int err;
109398 + int _errno;
109399 +
109400 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
109401 + _errno = -GET_ERROR_TYPE(err);
109402 + if (unlikely(_errno < 0))
109403 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
109404 +
109405 + return _errno;
109406 +}
109407 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
109408 +
109409 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
109410 + uint32_t pn_exh_thr)
109411 +{
109412 + int err;
109413 + int _errno;
109414 +
109415 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
109416 + _errno = -GET_ERROR_TYPE(err);
109417 + if (unlikely(_errno < 0))
109418 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
109419 +
109420 + return _errno;
109421 +}
109422 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
109423 +
109424 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
109425 +{
109426 + int err;
109427 + int _errno;
109428 +
109429 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
109430 + _errno = -GET_ERROR_TYPE(err);
109431 + if (unlikely(_errno < 0))
109432 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
109433 +
109434 + return _errno;
109435 +}
109436 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
109437 +
109438 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
109439 +{
109440 + int err;
109441 + int _errno;
109442 +
109443 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
109444 + _errno = -GET_ERROR_TYPE(err);
109445 + if (unlikely(_errno < 0))
109446 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
109447 +
109448 + return _errno;
109449 +}
109450 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
109451 +
109452 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
109453 + fm_macsec_exception exception, bool enable)
109454 +{
109455 + int err;
109456 + int _errno;
109457 +
109458 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
109459 + _errno = -GET_ERROR_TYPE(err);
109460 + if (unlikely(_errno < 0))
109461 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
109462 +
109463 + return _errno;
109464 +}
109465 +EXPORT_SYMBOL(fm_macsec_config_exception);
109466 +
109467 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
109468 + int *macsec_revision)
109469 +{
109470 + int err;
109471 + int _errno;
109472 +
109473 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
109474 + _errno = -GET_ERROR_TYPE(err);
109475 + if (unlikely(_errno < 0))
109476 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
109477 +
109478 + return _errno;
109479 +}
109480 +EXPORT_SYMBOL(fm_macsec_get_revision);
109481 +
109482 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
109483 +{
109484 + int err;
109485 + int _errno;
109486 +
109487 + err = FM_MACSEC_Enable(fm_macsec_dev);
109488 + _errno = -GET_ERROR_TYPE(err);
109489 + if (unlikely(_errno < 0))
109490 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
109491 +
109492 + return _errno;
109493 +}
109494 +EXPORT_SYMBOL(fm_macsec_enable);
109495 +
109496 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
109497 +{
109498 + int err;
109499 + int _errno;
109500 +
109501 + err = FM_MACSEC_Disable(fm_macsec_dev);
109502 + _errno = -GET_ERROR_TYPE(err);
109503 + if (unlikely(_errno < 0))
109504 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
109505 +
109506 + return _errno;
109507 +}
109508 +EXPORT_SYMBOL(fm_macsec_disable);
109509 +
109510 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
109511 + fm_macsec_exception exception, bool enable)
109512 +{
109513 + int err;
109514 + int _errno;
109515 +
109516 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
109517 + _errno = -GET_ERROR_TYPE(err);
109518 + if (unlikely(_errno < 0))
109519 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
109520 +
109521 + return _errno;
109522 +}
109523 +EXPORT_SYMBOL(fm_macsec_set_exception);
109524 +
109525 +/* Macsec SECY wrapper API */
109526 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
109527 +{
109528 + struct fm_macsec_secy_dev *fm_macsec_secy;
109529 +
109530 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
109531 + if (unlikely(fm_macsec_secy < 0))
109532 + pr_err("FM_MACSEC_SECY_Config() failed\n");
109533 +
109534 + return fm_macsec_secy;
109535 +}
109536 +EXPORT_SYMBOL(fm_macsec_secy_config);
109537 +
109538 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109539 +{
109540 + int err;
109541 + int _errno;
109542 +
109543 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
109544 + _errno = -GET_ERROR_TYPE(err);
109545 + if (unlikely(_errno < 0))
109546 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
109547 +
109548 + return _errno;
109549 +}
109550 +EXPORT_SYMBOL(fm_macsec_secy_init);
109551 +
109552 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109553 +{
109554 + int err;
109555 + int _errno;
109556 +
109557 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
109558 + _errno = -GET_ERROR_TYPE(err);
109559 + if (unlikely(_errno < 0))
109560 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
109561 +
109562 + return _errno;
109563 +}
109564 +EXPORT_SYMBOL(fm_macsec_secy_free);
109565 +
109566 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109567 + fm_macsec_sci_insertion_mode sci_insertion_mode)
109568 +{
109569 + int err;
109570 + int _errno;
109571 +
109572 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
109573 + sci_insertion_mode);
109574 + _errno = -GET_ERROR_TYPE(err);
109575 + if (unlikely(_errno < 0))
109576 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
109577 +
109578 + return _errno;
109579 +}
109580 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109581 +
109582 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109583 + bool protect_frames)
109584 +{
109585 + int err;
109586 + int _errno;
109587 +
109588 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109589 + protect_frames);
109590 + _errno = -GET_ERROR_TYPE(err);
109591 + if (unlikely(_errno < 0))
109592 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109593 +
109594 + return _errno;
109595 +}
109596 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109597 +
109598 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109599 + bool replay_protect, uint32_t replay_window)
109600 +{
109601 + int err;
109602 + int _errno;
109603 +
109604 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109605 + replay_protect, replay_window);
109606 + _errno = -GET_ERROR_TYPE(err);
109607 + if (unlikely(_errno < 0))
109608 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109609 +
109610 + return _errno;
109611 +}
109612 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109613 +
109614 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109615 + fm_macsec_valid_frame_behavior validate_frames)
109616 +{
109617 + int err;
109618 + int _errno;
109619 +
109620 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109621 + validate_frames);
109622 + _errno = -GET_ERROR_TYPE(err);
109623 + if (unlikely(_errno < 0))
109624 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109625 +
109626 + return _errno;
109627 +}
109628 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109629 +
109630 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109631 + bool confidentiality_enable,
109632 + uint32_t confidentiality_offset)
109633 +{
109634 + int err;
109635 + int _errno;
109636 +
109637 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109638 + confidentiality_enable,
109639 + confidentiality_offset);
109640 + _errno = -GET_ERROR_TYPE(err);
109641 + if (unlikely(_errno < 0))
109642 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109643 + err);
109644 +
109645 + return _errno;
109646 +}
109647 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109648 +
109649 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109650 +{
109651 + int err;
109652 + int _errno;
109653 +
109654 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109655 + _errno = -GET_ERROR_TYPE(err);
109656 + if (unlikely(_errno < 0))
109657 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109658 + err);
109659 +
109660 + return _errno;
109661 +}
109662 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109663 +
109664 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109665 + fm_macsec_secy_exception exception,
109666 + bool enable)
109667 +{
109668 + int err;
109669 + int _errno;
109670 +
109671 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109672 + enable);
109673 + _errno = -GET_ERROR_TYPE(err);
109674 + if (unlikely(_errno < 0))
109675 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109676 + err);
109677 +
109678 + return _errno;
109679 +}
109680 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109681 +
109682 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109683 + fm_macsec_secy_event event,
109684 + bool enable)
109685 +{
109686 + int err;
109687 + int _errno;
109688 +
109689 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109690 + _errno = -GET_ERROR_TYPE(err);
109691 + if (unlikely(_errno < 0))
109692 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109693 + err);
109694 +
109695 + return _errno;
109696 +}
109697 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109698 +
109699 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109700 + struct fm_macsec_secy_sc_params *params)
109701 +{
109702 + struct rx_sc_dev *rx_sc_dev;
109703 +
109704 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109705 + if (unlikely(rx_sc_dev == NULL))
109706 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109707 +
109708 + return rx_sc_dev;
109709 +}
109710 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109711 +
109712 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109713 + struct rx_sc_dev *sc)
109714 +{
109715 + int err;
109716 + int _errno;
109717 +
109718 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109719 + _errno = -GET_ERROR_TYPE(err);
109720 + if (unlikely(_errno < 0))
109721 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109722 + err);
109723 +
109724 + return _errno;
109725 +}
109726 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109727 +
109728 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109729 + struct rx_sc_dev *sc, macsec_an_t an,
109730 + uint32_t lowest_pn, macsec_sa_key_t key)
109731 +{
109732 + int err;
109733 + int _errno;
109734 +
109735 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109736 + lowest_pn, key);
109737 + _errno = -GET_ERROR_TYPE(err);
109738 + if (unlikely(_errno < 0))
109739 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109740 + err);
109741 +
109742 + return _errno;
109743 +}
109744 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109745 +
109746 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109747 + struct rx_sc_dev *sc, macsec_an_t an)
109748 +{
109749 + int err;
109750 + int _errno;
109751 +
109752 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109753 + _errno = -GET_ERROR_TYPE(err);
109754 + if (unlikely(_errno < 0))
109755 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109756 + err);
109757 +
109758 + return _errno;
109759 +}
109760 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109761 +
109762 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109763 + struct rx_sc_dev *sc,
109764 + macsec_an_t an)
109765 +{
109766 + int err;
109767 + int _errno;
109768 +
109769 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109770 + _errno = -GET_ERROR_TYPE(err);
109771 + if (unlikely(_errno < 0))
109772 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109773 + err);
109774 +
109775 + return _errno;
109776 +}
109777 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109778 +
109779 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109780 + struct rx_sc_dev *sc,
109781 + macsec_an_t an)
109782 +{
109783 + int err;
109784 + int _errno;
109785 +
109786 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109787 + _errno = -GET_ERROR_TYPE(err);
109788 + if (unlikely(_errno < 0))
109789 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109790 + err);
109791 +
109792 + return _errno;
109793 +}
109794 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109795 +
109796 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109797 + struct rx_sc_dev *sc,
109798 + macsec_an_t an, uint32_t updt_next_pn)
109799 +{
109800 + int err;
109801 + int _errno;
109802 +
109803 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109804 + updt_next_pn);
109805 + _errno = -GET_ERROR_TYPE(err);
109806 + if (unlikely(_errno < 0))
109807 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109808 +
109809 + return _errno;
109810 +}
109811 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109812 +
109813 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109814 + struct rx_sc_dev *sc,
109815 + macsec_an_t an, uint32_t updt_lowest_pn)
109816 +{
109817 + int err;
109818 + int _errno;
109819 +
109820 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109821 + updt_lowest_pn);
109822 + _errno = -GET_ERROR_TYPE(err);
109823 + if (unlikely(_errno < 0))
109824 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109825 + err);
109826 +
109827 + return _errno;
109828 +}
109829 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109830 +
109831 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109832 + struct rx_sc_dev *sc,
109833 + macsec_an_t an, macsec_sa_key_t key)
109834 +{
109835 + int err;
109836 + int _errno;
109837 +
109838 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
109839 + _errno = -GET_ERROR_TYPE(err);
109840 + if (unlikely(_errno < 0))
109841 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
109842 + err);
109843 +
109844 + return _errno;
109845 +}
109846 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
109847 +
109848 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109849 + macsec_an_t an, macsec_sa_key_t key)
109850 +{
109851 + int err;
109852 + int _errno;
109853 +
109854 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
109855 + _errno = -GET_ERROR_TYPE(err);
109856 + if (unlikely(_errno < 0))
109857 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
109858 + err);
109859 +
109860 + return _errno;
109861 +}
109862 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
109863 +
109864 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109865 + macsec_an_t an)
109866 +{
109867 + int err;
109868 + int _errno;
109869 +
109870 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
109871 + _errno = -GET_ERROR_TYPE(err);
109872 + if (unlikely(_errno < 0))
109873 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
109874 + err);
109875 +
109876 + return _errno;
109877 +}
109878 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
109879 +
109880 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109881 + macsec_an_t next_active_an,
109882 + macsec_sa_key_t key)
109883 +{
109884 + int err;
109885 + int _errno;
109886 +
109887 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
109888 + key);
109889 + _errno = -GET_ERROR_TYPE(err);
109890 + if (unlikely(_errno < 0))
109891 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
109892 + err);
109893 +
109894 + return _errno;
109895 +}
109896 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
109897 +
109898 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109899 + macsec_an_t an)
109900 +{
109901 + int err;
109902 + int _errno;
109903 +
109904 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
109905 + _errno = -GET_ERROR_TYPE(err);
109906 + if (unlikely(_errno < 0))
109907 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
109908 + err);
109909 +
109910 + return _errno;
109911 +}
109912 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
109913 +
109914 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109915 + macsec_an_t *p_an)
109916 +{
109917 + int err;
109918 + int _errno;
109919 +
109920 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
109921 + _errno = -GET_ERROR_TYPE(err);
109922 + if (unlikely(_errno < 0))
109923 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
109924 + err);
109925 +
109926 + return _errno;
109927 +}
109928 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
109929 +
109930 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109931 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
109932 +{
109933 + int err;
109934 + int _errno;
109935 +
109936 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
109937 + _errno = -GET_ERROR_TYPE(err);
109938 + if (unlikely(_errno < 0))
109939 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
109940 + err);
109941 +
109942 + return _errno;
109943 +}
109944 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
109945 +
109946 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109947 + uint32_t *sc_phys_id)
109948 +{
109949 + int err;
109950 + int _errno;
109951 +
109952 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
109953 + _errno = -GET_ERROR_TYPE(err);
109954 + if (unlikely(_errno < 0))
109955 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
109956 + err);
109957 +
109958 + return _errno;
109959 +}
109960 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
109961 +
109962 +static t_Handle h_FmLnxWrp;
109963 +
109964 +static int __init __cold fm_load (void)
109965 +{
109966 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
109967 + {
109968 + printk("Failed to init FM wrapper!\n");
109969 + return -ENODEV;
109970 + }
109971 +
109972 + printk(KERN_CRIT "Freescale FM module," \
109973 + " FMD API version %d.%d.%d\n",
109974 + FMD_API_VERSION_MAJOR,
109975 + FMD_API_VERSION_MINOR,
109976 + FMD_API_VERSION_RESPIN);
109977 + return 0;
109978 +}
109979 +
109980 +static void __exit __cold fm_unload (void)
109981 +{
109982 + if (h_FmLnxWrp)
109983 + LNXWRP_FM_Free(h_FmLnxWrp);
109984 +}
109985 +
109986 +module_init (fm_load);
109987 +module_exit (fm_unload);
109988 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109989 new file mode 100644
109990 index 00000000..09832563
109991 --- /dev/null
109992 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109993 @@ -0,0 +1,294 @@
109994 +/*
109995 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109996 + *
109997 + * Redistribution and use in source and binary forms, with or without
109998 + * modification, are permitted provided that the following conditions are met:
109999 + * * Redistributions of source code must retain the above copyright
110000 + * notice, this list of conditions and the following disclaimer.
110001 + * * Redistributions in binary form must reproduce the above copyright
110002 + * notice, this list of conditions and the following disclaimer in the
110003 + * documentation and/or other materials provided with the distribution.
110004 + * * Neither the name of Freescale Semiconductor nor the
110005 + * names of its contributors may be used to endorse or promote products
110006 + * derived from this software without specific prior written permission.
110007 + *
110008 + *
110009 + * ALTERNATIVELY, this software may be distributed under the terms of the
110010 + * GNU General Public License ("GPL") as published by the Free Software
110011 + * Foundation, either version 2 of that License or (at your option) any
110012 + * later version.
110013 + *
110014 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
110015 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
110016 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110017 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
110018 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
110019 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
110020 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
110021 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110022 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
110023 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110024 + */
110025 +
110026 +/*
110027 + @File lnxwrp_fm.h
110028 +
110029 + @Author Shlomi Gridish
110030 +
110031 + @Description FM Linux wrapper functions.
110032 +
110033 +*/
110034 +
110035 +#ifndef __LNXWRP_FM_H__
110036 +#define __LNXWRP_FM_H__
110037 +
110038 +#include <linux/fsl_qman.h> /* struct qman_fq */
110039 +
110040 +#include "std_ext.h"
110041 +#include "error_ext.h"
110042 +#include "list_ext.h"
110043 +
110044 +#include "lnxwrp_fm_ext.h"
110045 +
110046 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
110047 +
110048 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
110049 +
110050 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110051 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
110052 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
110053 +#else
110054 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
110055 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
110056 +#endif
110057 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
110058 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
110059 +
110060 +#define FRAG_MANIP_SPACE 128
110061 +#define FRAG_DATA_ALIGN 64
110062 +
110063 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
110064 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
110065 +#endif
110066 +
110067 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
110068 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
110069 +#endif
110070 +
110071 +typedef enum {
110072 + e_NO_PCD = 0,
110073 + e_FM_PCD_3_TUPLE
110074 +} e_LnxWrpFmPortPcdDefUseCase;
110075 +
110076 +
110077 +typedef struct t_FmTestFq {
110078 + struct qman_fq fq_base;
110079 + t_Handle h_Arg;
110080 +} t_FmTestFq;
110081 +
110082 +typedef struct {
110083 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
110084 + int minor;
110085 + char name[20];
110086 + bool active;
110087 + uint64_t phys_baseAddr;
110088 + uint64_t baseAddr; /* Port's *virtual* address */
110089 + uint32_t memSize;
110090 + t_WrpFmPortDevSettings settings;
110091 + t_FmExtPools opExtPools;
110092 + uint8_t totalNumOfSchemes;
110093 + uint8_t schemesBase;
110094 + uint8_t numOfSchemesUsed;
110095 + uint32_t pcdBaseQ;
110096 + uint16_t pcdNumOfQs;
110097 + struct fm_port_pcd_param pcd_owner_params;
110098 + e_LnxWrpFmPortPcdDefUseCase defPcd;
110099 + t_Handle h_DefNetEnv;
110100 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
110101 + t_FmBufferPrefixContent buffPrefixContent;
110102 + t_Handle h_Dev;
110103 + t_Handle h_DfltVsp;
110104 + t_Handle h_LnxWrpFmDev;
110105 + uint16_t txCh;
110106 + struct device *dev;
110107 + struct device_attribute *dev_attr_stats;
110108 + struct device_attribute *dev_attr_regs;
110109 + struct device_attribute *dev_attr_bmi_regs;
110110 + struct device_attribute *dev_attr_qmi_regs;
110111 +#if (DPAA_VERSION >= 11)
110112 + struct device_attribute *dev_attr_ipv4_opt;
110113 +#endif
110114 + struct device_attribute *dev_attr_dsar_regs;
110115 + struct device_attribute *dev_attr_dsar_mem;
110116 + struct auto_res_tables_sizes dsar_table_sizes;
110117 +} t_LnxWrpFmPortDev;
110118 +
110119 +typedef struct {
110120 + uint8_t id;
110121 + bool active;
110122 + uint64_t baseAddr;
110123 + uint32_t memSize;
110124 + t_WrpFmMacDevSettings settings;
110125 + t_Handle h_Dev;
110126 + t_Handle h_LnxWrpFmDev;
110127 +} t_LnxWrpFmMacDev;
110128 +
110129 +/* information about all active ports for an FMan.
110130 + * !Some ports may be disabled by u-boot, thus will not be available */
110131 +struct fm_active_ports {
110132 + uint32_t num_oh_ports;
110133 + uint32_t num_tx_ports;
110134 + uint32_t num_rx_ports;
110135 + uint32_t num_tx25_ports;
110136 + uint32_t num_rx25_ports;
110137 + uint32_t num_tx10_ports;
110138 + uint32_t num_rx10_ports;
110139 +};
110140 +
110141 +/* FMan resources precalculated at fm probe based
110142 + * on available FMan port. */
110143 +struct fm_resource_settings {
110144 + /* buffers - fifo sizes */
110145 + uint32_t tx1g_num_buffers;
110146 + uint32_t rx1g_num_buffers;
110147 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
110148 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
110149 + uint32_t tx10g_num_buffers;
110150 + uint32_t rx10g_num_buffers;
110151 + uint32_t oh_num_buffers;
110152 + uint32_t shared_ext_buffers;
110153 +
110154 + /* open DMAs */
110155 + uint32_t tx_1g_dmas;
110156 + uint32_t rx_1g_dmas;
110157 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
110158 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
110159 + uint32_t tx_10g_dmas;
110160 + uint32_t rx_10g_dmas;
110161 + uint32_t oh_dmas;
110162 + uint32_t shared_ext_open_dma;
110163 +
110164 + /* Tnums */
110165 + uint32_t tx_1g_tnums;
110166 + uint32_t rx_1g_tnums;
110167 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
110168 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
110169 + uint32_t tx_10g_tnums;
110170 + uint32_t rx_10g_tnums;
110171 + uint32_t oh_tnums;
110172 + uint32_t shared_ext_tnums;
110173 +};
110174 +
110175 +typedef struct {
110176 + uint8_t id;
110177 + char name[10];
110178 + bool active;
110179 + bool pcdActive;
110180 + bool prsActive;
110181 + bool kgActive;
110182 + bool ccActive;
110183 + bool plcrActive;
110184 + e_LnxWrpFmPortPcdDefUseCase defPcd;
110185 + uint32_t usedSchemes;
110186 + uint8_t totalNumOfSharedSchemes;
110187 + uint8_t sharedSchemesBase;
110188 + uint8_t numOfSchemesUsed;
110189 + uint8_t defNetEnvId;
110190 + uint64_t fmPhysBaseAddr;
110191 + uint64_t fmBaseAddr;
110192 + uint32_t fmMemSize;
110193 + uint64_t fmMuramPhysBaseAddr;
110194 + uint64_t fmMuramBaseAddr;
110195 + uint32_t fmMuramMemSize;
110196 + uint64_t fmRtcPhysBaseAddr;
110197 + uint64_t fmRtcBaseAddr;
110198 + uint32_t fmRtcMemSize;
110199 + uint64_t fmVspPhysBaseAddr;
110200 + uint64_t fmVspBaseAddr;
110201 + uint32_t fmVspMemSize;
110202 + int irq;
110203 + int err_irq;
110204 + t_WrpFmDevSettings fmDevSettings;
110205 + t_WrpFmPcdDevSettings fmPcdDevSettings;
110206 + t_Handle h_Dev;
110207 + uint16_t hcCh;
110208 +
110209 + t_Handle h_MuramDev;
110210 + t_Handle h_PcdDev;
110211 + t_Handle h_RtcDev;
110212 +
110213 + t_Handle h_DsarRxPort;
110214 + t_Handle h_DsarTxPort;
110215 +
110216 + t_LnxWrpFmPortDev hcPort;
110217 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
110218 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
110219 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
110220 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
110221 + struct fm_active_ports fm_active_ports_info;
110222 + struct fm_resource_settings fm_resource_settings_info;
110223 +
110224 + struct device *dev;
110225 + struct resource *res;
110226 + int major;
110227 + struct class *fm_class;
110228 + struct device_attribute *dev_attr_stats;
110229 + struct device_attribute *dev_attr_regs;
110230 + struct device_attribute *dev_attr_risc_load;
110231 +
110232 + struct device_attribute *dev_pcd_attr_stats;
110233 + struct device_attribute *dev_plcr_attr_regs;
110234 + struct device_attribute *dev_prs_attr_regs;
110235 + struct device_attribute *dev_fm_fpm_attr_regs;
110236 + struct device_attribute *dev_fm_kg_attr_regs;
110237 + struct device_attribute *dev_fm_kg_pe_attr_regs;
110238 + struct device_attribute *dev_attr_muram_free_size;
110239 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
110240 +
110241 +
110242 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
110243 +} t_LnxWrpFmDev;
110244 +
110245 +typedef struct {
110246 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
110247 +} t_LnxWrpFm;
110248 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
110249 +
110250 +
110251 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
110252 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
110253 +
110254 +
110255 +#if 0
110256 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
110257 +{
110258 + uint32_t schemeMask;
110259 + uint8_t i;
110260 +
110261 + if (!numSchemes)
110262 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110263 +
110264 + schemeMask = 0x80000000;
110265 + *p_BaseSchemeNum = 0xff;
110266 +
110267 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
110268 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
110269 + {
110270 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
110271 + numSchemes--;
110272 + if (*p_BaseSchemeNum==0xff)
110273 + *p_BaseSchemeNum = i;
110274 + }
110275 + else if (*p_BaseSchemeNum!=0xff)
110276 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
110277 +
110278 + if (numSchemes)
110279 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
110280 + return E_OK;
110281 +}
110282 +#endif
110283 +
110284 +void LnxWrpPCDIOCTLTypeChecking(void);
110285 +void LnxWrpPCDIOCTLEnumChecking(void);
110286 +
110287 +#endif /* __LNXWRP_FM_H__ */
110288 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
110289 new file mode 100644
110290 index 00000000..00ab4bcb
110291 --- /dev/null
110292 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
110293 @@ -0,0 +1,1480 @@
110294 +/*
110295 + * Copyright 2008-2012 Freescale Semiconductor Inc.
110296 + *
110297 + * Redistribution and use in source and binary forms, with or without
110298 + * modification, are permitted provided that the following conditions are met:
110299 + * * Redistributions of source code must retain the above copyright
110300 + * notice, this list of conditions and the following disclaimer.
110301 + * * Redistributions in binary form must reproduce the above copyright
110302 + * notice, this list of conditions and the following disclaimer in the
110303 + * documentation and/or other materials provided with the distribution.
110304 + * * Neither the name of Freescale Semiconductor nor the
110305 + * names of its contributors may be used to endorse or promote products
110306 + * derived from this software without specific prior written permission.
110307 + *
110308 + *
110309 + * ALTERNATIVELY, this software may be distributed under the terms of the
110310 + * GNU General Public License ("GPL") as published by the Free Software
110311 + * Foundation, either version 2 of that License or (at your option) any
110312 + * later version.
110313 + *
110314 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
110315 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
110316 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110317 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
110318 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
110319 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
110320 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
110321 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110322 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
110323 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110324 + */
110325 +
110326 +/*
110327 + @File lnxwrp_fm_port.c
110328 +
110329 + @Description FMD wrapper - FMan port functions.
110330 +
110331 +*/
110332 +
110333 +#include <linux/version.h>
110334 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
110335 +#define MODVERSIONS
110336 +#endif
110337 +#ifdef MODVERSIONS
110338 +#include <config/modversions.h>
110339 +#endif /* MODVERSIONS */
110340 +#include <linux/kernel.h>
110341 +#include <linux/module.h>
110342 +#include <linux/of_platform.h>
110343 +#include <linux/of_address.h>
110344 +#include <linux/cdev.h>
110345 +#include <linux/slab.h>
110346 +#include <linux/spinlock.h>
110347 +#ifndef CONFIG_FMAN_ARM
110348 +#include <linux/fsl/svr.h>
110349 +#endif
110350 +#include <linux/io.h>
110351 +
110352 +#include "sprint_ext.h"
110353 +#include "fm_common.h"
110354 +#include "lnxwrp_fsl_fman.h"
110355 +#include "fm_port_ext.h"
110356 +#if (DPAA_VERSION >= 11)
110357 +#include "fm_vsp_ext.h"
110358 +#endif /* DPAA_VERSION >= 11 */
110359 +#include "fm_ioctls.h"
110360 +#include "lnxwrp_resources.h"
110361 +#include "lnxwrp_sysfs_fm_port.h"
110362 +
110363 +#define __ERR_MODULE__ MODULE_FM
110364 +
110365 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
110366 +
110367 +/* TODO: duplicated, see lnxwrp_fm.c */
110368 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
110369 +do {\
110370 + if (i < max) {\
110371 + p_Entry = &p_Entrys[i];\
110372 + p_Entry->p_Function = _func;\
110373 + _param\
110374 + i++;\
110375 + } else {\
110376 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
110377 + ("Number of advanced-configuration entries exceeded"));\
110378 + } \
110379 +} while (0)
110380 +
110381 +#ifndef CONFIG_FMAN_ARM
110382 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
110383 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
110384 +#endif
110385 +
110386 +static volatile int hcFrmRcv/* = 0 */;
110387 +static spinlock_t lock;
110388 +
110389 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
110390 + struct qman_fq *fq,
110391 + const struct qm_dqrr_entry
110392 + *dq)
110393 +{
110394 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
110395 + unsigned long flags;
110396 +
110397 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110398 +{
110399 + /* extract the HC frame address */
110400 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
110401 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
110402 + int i;
110403 +
110404 + /* 32b byteswap of all data in the HC Frame */
110405 + for(i = 0; i < hcf_l / 4; ++i)
110406 + hcf_va[i] =
110407 + ___constant_swab32(hcf_va[i]);
110408 +}
110409 +#endif
110410 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
110411 + spin_lock_irqsave(&lock, flags);
110412 + hcFrmRcv--;
110413 + spin_unlock_irqrestore(&lock, flags);
110414 +
110415 + return qman_cb_dqrr_consume;
110416 +}
110417 +
110418 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
110419 + struct qman_fq *fq,
110420 + const struct qm_dqrr_entry *dq)
110421 +{
110422 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110423 + __func__);
110424 + return qman_cb_dqrr_consume;
110425 +}
110426 +
110427 +static void qm_err_cb(struct qman_portal *portal,
110428 + struct qman_fq *fq, const struct qm_mr_entry *msg)
110429 +{
110430 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110431 + __func__);
110432 +}
110433 +
110434 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
110435 + uint32_t fqid,
110436 + uint32_t flags, uint16_t channel, uint8_t wq)
110437 +{
110438 + int _errno;
110439 + struct qman_fq *fq = NULL;
110440 + t_FmTestFq *p_FmtFq;
110441 + struct qm_mcc_initfq initfq;
110442 +
110443 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
110444 + if (!p_FmtFq) {
110445 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
110446 + return NULL;
110447 + }
110448 +
110449 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
110450 + ? qm_tx_conf_dqrr_cb
110451 + : qm_tx_dqrr_cb);
110452 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
110453 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
110454 + /* qm_err_cb wrongly called when the FQ is parked */
110455 + p_FmtFq->fq_base.cb.fqs = NULL;
110456 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
110457 + if (fqid == 0) {
110458 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
110459 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
110460 + } else {
110461 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
110462 + }
110463 +
110464 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
110465 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
110466 + XX_Free(p_FmtFq);
110467 + return NULL;
110468 + }
110469 + fq = &p_FmtFq->fq_base;
110470 +
110471 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
110472 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
110473 + initfq.fqd.dest.channel = channel;
110474 + initfq.fqd.dest.wq = wq;
110475 +
110476 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
110477 + if (unlikely(_errno < 0)) {
110478 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
110479 + ("FQ obj - qman_init_fq!!!"));
110480 + qman_destroy_fq(fq, 0);
110481 + XX_Free(p_FmtFq);
110482 + return NULL;
110483 + }
110484 + }
110485 +
110486 + DBG(TRACE,
110487 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
110488 + flags, channel, wq));
110489 +
110490 + return fq;
110491 +}
110492 +
110493 +static void FqFree(struct qman_fq *fq)
110494 +{
110495 + int _errno;
110496 +
110497 + _errno = qman_retire_fq(fq, NULL);
110498 + if (unlikely(_errno < 0))
110499 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110500 +
110501 + _errno = qman_oos_fq(fq);
110502 + if (unlikely(_errno < 0))
110503 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110504 +
110505 + qman_destroy_fq(fq, 0);
110506 + XX_Free((t_FmTestFq *) fq);
110507 +}
110508 +
110509 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
110510 +{
110511 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
110512 + int _errno, timeout = 1000000;
110513 + unsigned long flags;
110514 +
110515 + ASSERT_COND(p_LnxWrpFmDev);
110516 +
110517 + spin_lock_irqsave(&lock, flags);
110518 + hcFrmRcv++;
110519 + spin_unlock_irqrestore(&lock, flags);
110520 +
110521 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110522 +{
110523 + /* extract the HC frame address */
110524 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
110525 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
110526 + int i;
110527 +
110528 + /* 32b byteswap of all data in the HC Frame */
110529 + for(i = 0; i < hcf_l / 4; ++i)
110530 + hcf_va[i] =
110531 + ___constant_swab32(hcf_va[i]);
110532 +}
110533 +#endif
110534 +
110535 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
110536 + 0);
110537 + if (_errno)
110538 + RETURN_ERROR(MINOR, E_INVALID_STATE,
110539 + ("qman_enqueue() failed"));
110540 +
110541 + while (hcFrmRcv && --timeout) {
110542 + udelay(1);
110543 + cpu_relax();
110544 + }
110545 + if (timeout == 0) {
110546 + dump_stack();
110547 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
110548 + ("timeout waiting for Tx confirmation"));
110549 + return E_WRITE_FAILED;
110550 + }
110551 +
110552 + return E_OK;
110553 +}
110554 +
110555 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
110556 + *of_dev)
110557 +{
110558 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110559 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110560 + struct device_node *fm_node, *port_node;
110561 + struct resource res;
110562 + const uint32_t *uint32_prop;
110563 + int _errno = 0, lenp;
110564 + uint32_t tmp_prop;
110565 +
110566 +#ifdef CONFIG_FMAN_P1023
110567 + static unsigned char have_oh_port/* = 0 */;
110568 +#endif
110569 +
110570 + port_node = of_node_get(of_dev->dev.of_node);
110571 +
110572 + /* Get the FM node */
110573 + fm_node = of_get_parent(port_node);
110574 + if (unlikely(fm_node == NULL)) {
110575 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
110576 + ("of_get_parent() = %d", _errno));
110577 + return NULL;
110578 + }
110579 +
110580 + p_LnxWrpFmDev =
110581 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
110582 + of_node_put(fm_node);
110583 +
110584 + /* if fm_probe() failed, no point in going further with port probing */
110585 + if (p_LnxWrpFmDev == NULL)
110586 + return NULL;
110587 +
110588 + uint32_prop =
110589 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110590 + if (unlikely(uint32_prop == NULL)) {
110591 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110592 + ("of_get_property(%s, cell-index) failed",
110593 + port_node->full_name));
110594 + return NULL;
110595 + }
110596 + tmp_prop = be32_to_cpu(*uint32_prop);
110597 + if (WARN_ON(lenp != sizeof(uint32_t)))
110598 + return NULL;
110599 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) {
110600 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110601 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110602 + ("of_get_property(%s, cell-index) failed",
110603 + port_node->full_name));
110604 + return NULL;
110605 + }
110606 +
110607 +#ifdef CONFIG_FMAN_P1023
110608 + /* Beware, this can be done when there is only
110609 + one FMan to be initialized */
110610 + if (!have_oh_port) {
110611 + have_oh_port = 1; /* first OP/HC port
110612 + is used for host command */
110613 +#else
110614 + /* Here it is hardcoded the use of the OH port 1
110615 + (with cell-index 0) */
110616 + if (tmp_prop == 0) {
110617 +#endif
110618 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110619 + p_LnxWrpFmPortDev->id = 0;
110620 + /*
110621 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110622 + p_LnxWrpFmPortDev->id = *uint32_prop;
110623 + */
110624 + p_LnxWrpFmPortDev->settings.param.portType =
110625 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110626 + } else {
110627 + p_LnxWrpFmPortDev =
110628 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110629 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110630 + p_LnxWrpFmPortDev->settings.param.portType =
110631 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110632 + }
110633 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110634 +
110635 + uint32_prop =
110636 + (uint32_t *) of_get_property(port_node,
110637 + "fsl,qman-channel-id",
110638 + &lenp);
110639 + if (uint32_prop == NULL) {
110640 + /*
110641 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110642 + */
110643 + XX_Print("FM warning: missing fsl,qman-channel-id"
110644 + " for OH port.\n");
110645 + return NULL;
110646 + }
110647 + tmp_prop = be32_to_cpu(*uint32_prop);
110648 + if (WARN_ON(lenp != sizeof(uint32_t)))
110649 + return NULL;
110650 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110651 +
110652 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110653 + qmChannel = p_LnxWrpFmPortDev->txCh;
110654 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110655 + tmp_prop -= 0x28;
110656 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110657 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110658 + ("of_get_property(%s, cell-index) failed",
110659 + port_node->full_name));
110660 + return NULL;
110661 + }
110662 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110663 +
110664 + p_LnxWrpFmPortDev->id = tmp_prop;
110665 + p_LnxWrpFmPortDev->settings.param.portId =
110666 + p_LnxWrpFmPortDev->id;
110667 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110668 +
110669 + uint32_prop = (uint32_t *) of_get_property(port_node,
110670 + "fsl,qman-channel-id", &lenp);
110671 + if (uint32_prop == NULL) {
110672 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110673 + ("missing fsl,qman-channel-id"));
110674 + return NULL;
110675 + }
110676 + tmp_prop = be32_to_cpu(*uint32_prop);
110677 + if (WARN_ON(lenp != sizeof(uint32_t)))
110678 + return NULL;
110679 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110680 + p_LnxWrpFmPortDev->
110681 + settings.param.specificParams.nonRxParams.qmChannel =
110682 + p_LnxWrpFmPortDev->txCh;
110683 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110684 + tmp_prop -= 0x30;
110685 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110686 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110687 + ("of_get_property(%s, cell-index) failed",
110688 + port_node->full_name));
110689 + return NULL;
110690 + }
110691 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110692 + FM_MAX_NUM_OF_1G_TX_PORTS];
110693 +#ifndef CONFIG_FMAN_ARM
110694 + if (IS_T1023_T1024)
110695 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop];
110696 +#endif
110697 +
110698 + p_LnxWrpFmPortDev->id = tmp_prop;
110699 + p_LnxWrpFmPortDev->settings.param.portId =
110700 + p_LnxWrpFmPortDev->id;
110701 + p_LnxWrpFmPortDev->settings.param.portType =
110702 + e_FM_PORT_TYPE_TX_10G;
110703 + uint32_prop = (uint32_t *) of_get_property(port_node,
110704 + "fsl,qman-channel-id", &lenp);
110705 + if (uint32_prop == NULL) {
110706 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110707 + ("missing fsl,qman-channel-id"));
110708 + return NULL;
110709 + }
110710 + tmp_prop = be32_to_cpu(*uint32_prop);
110711 + if (WARN_ON(lenp != sizeof(uint32_t)))
110712 + return NULL;
110713 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110714 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110715 + qmChannel = p_LnxWrpFmPortDev->txCh;
110716 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110717 + tmp_prop -= 0x08;
110718 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110719 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110720 + ("of_get_property(%s, cell-index) failed",
110721 + port_node->full_name));
110722 + return NULL;
110723 + }
110724 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110725 +
110726 + p_LnxWrpFmPortDev->id = tmp_prop;
110727 + p_LnxWrpFmPortDev->settings.param.portId =
110728 + p_LnxWrpFmPortDev->id;
110729 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110730 + if (p_LnxWrpFmDev->pcdActive)
110731 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110732 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110733 + tmp_prop -= 0x10;
110734 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110735 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110736 + ("of_get_property(%s, cell-index) failed",
110737 + port_node->full_name));
110738 + return NULL;
110739 + }
110740 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110741 + FM_MAX_NUM_OF_1G_RX_PORTS];
110742 +
110743 +#ifndef CONFIG_FMAN_ARM
110744 + if (IS_T1023_T1024)
110745 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop];
110746 +#endif
110747 +
110748 + p_LnxWrpFmPortDev->id = tmp_prop;
110749 + p_LnxWrpFmPortDev->settings.param.portId =
110750 + p_LnxWrpFmPortDev->id;
110751 + p_LnxWrpFmPortDev->settings.param.portType =
110752 + e_FM_PORT_TYPE_RX_10G;
110753 + if (p_LnxWrpFmDev->pcdActive)
110754 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110755 + } else {
110756 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110757 + return NULL;
110758 + }
110759 +
110760 + _errno = of_address_to_resource(port_node, 0, &res);
110761 + if (unlikely(_errno < 0)) {
110762 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110763 + ("of_address_to_resource() = %d", _errno));
110764 + return NULL;
110765 + }
110766 +
110767 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110768 + p_LnxWrpFmPortDev->baseAddr = 0;
110769 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110770 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110771 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110772 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110773 +
110774 + of_node_put(port_node);
110775 +
110776 + p_LnxWrpFmPortDev->active = TRUE;
110777 +
110778 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110779 + /* for performance mode no OH port available. */
110780 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110781 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110782 + p_LnxWrpFmPortDev->active = FALSE;
110783 +#endif
110784 +
110785 + return p_LnxWrpFmPortDev;
110786 +}
110787 +
110788 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110789 + e_FmPortType portType,
110790 + uint8_t portId)
110791 +{
110792 + struct device_node *port_node;
110793 + const uint32_t *uint32_prop;
110794 + int lenp;
110795 + char *portTypeString;
110796 + uint32_t tmp_prop;
110797 +
110798 + switch(portType) {
110799 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110800 + portTypeString = "fsl,fman-port-op-extended-args";
110801 + break;
110802 + case e_FM_PORT_TYPE_TX:
110803 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110804 + break;
110805 + case e_FM_PORT_TYPE_TX_10G:
110806 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110807 + break;
110808 + case e_FM_PORT_TYPE_RX:
110809 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110810 + break;
110811 + case e_FM_PORT_TYPE_RX_10G:
110812 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110813 + break;
110814 + default:
110815 + return NULL;
110816 + }
110817 +
110818 + for_each_child_of_node(fm_node, port_node) {
110819 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110820 + if (unlikely(uint32_prop == NULL)) {
110821 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110822 + ("of_get_property(%s, cell-index) failed",
110823 + port_node->full_name));
110824 + return NULL;
110825 + }
110826 + tmp_prop = be32_to_cpu(*uint32_prop);
110827 + if (WARN_ON(lenp != sizeof(uint32_t)))
110828 + return NULL;
110829 + if ((portId == tmp_prop) &&
110830 + (of_device_is_compatible(port_node, portTypeString))) {
110831 + return port_node;
110832 + }
110833 + }
110834 +
110835 + return NULL;
110836 +}
110837 +
110838 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110839 +{
110840 + struct device_node *fm_node, *port_node;
110841 + t_Error err;
110842 + t_FmPortRsrc portRsrc;
110843 + const uint32_t *uint32_prop;
110844 + /*const char *str_prop;*/
110845 + int lenp;
110846 +#ifdef CONFIG_FMAN_PFC
110847 + uint8_t i, id, num_pools;
110848 + t_FmBufPoolDepletion poolDepletion;
110849 +
110850 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
110851 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
110852 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
110853 + poolDepletion.singlePoolModeEnable = true;
110854 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110855 + extBufPools.numOfPoolsUsed;
110856 + for (i = 0; i < num_pools; i++) {
110857 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110858 + extBufPools.extBufPool[i].id;
110859 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
110860 + }
110861 +
110862 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
110863 + poolDepletion.pfcPrioritiesEn[i] = true;
110864 +
110865 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
110866 + &poolDepletion);
110867 + if (err != E_OK)
110868 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
110869 + }
110870 +#endif
110871 +
110872 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110873 + if (!fm_node) /* no advance parameters for FMan */
110874 + return E_OK;
110875 +
110876 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110877 + p_LnxWrpFmPortDev->settings.param.portType,
110878 + p_LnxWrpFmPortDev->settings.param.portId);
110879 + if (!port_node) /* no advance parameters for FMan-Port */
110880 + return E_OK;
110881 +
110882 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
110883 + if (uint32_prop) {
110884 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110885 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110886 +
110887 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110888 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110889 +
110890 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
110891 + &portRsrc)) != E_OK)
110892 + RETURN_ERROR(MINOR, err, NO_MSG);
110893 + }
110894 +
110895 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
110896 + if (uint32_prop) {
110897 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110898 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110899 +
110900 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110901 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110902 +
110903 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
110904 + &portRsrc)) != E_OK)
110905 + RETURN_ERROR(MINOR, err, NO_MSG);
110906 + }
110907 +
110908 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
110909 + if (uint32_prop) {
110910 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110911 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110912 +
110913 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110914 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110915 +
110916 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
110917 + &portRsrc)) != E_OK)
110918 + RETURN_ERROR(MINOR, err, NO_MSG);
110919 + }
110920 +
110921 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
110922 + if (uint32_prop) {
110923 + if (WARN_ON(lenp != sizeof(uint32_t)))
110924 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110925 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
110926 + be32_to_cpu(uint32_prop[0]))) != E_OK)
110927 + RETURN_ERROR(MINOR, err, NO_MSG);
110928 + }
110929 +
110930 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
110931 + &lenp);
110932 + if (uint32_prop) {
110933 +
110934 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
110935 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110936 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
110937 + e_FM_PORT_TYPE_RX) &&
110938 + (p_LnxWrpFmPortDev->settings.param.portType !=
110939 + e_FM_PORT_TYPE_RX_10G))
110940 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
110941 + ("Auto Response is an Rx port atribute."));
110942 +
110943 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
110944 +
110945 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
110946 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110947 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
110948 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110949 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
110950 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110951 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
110952 + (uint16_t)be32_to_cpu(uint32_prop[3]);
110953 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
110954 + (uint16_t)be32_to_cpu(uint32_prop[4]);
110955 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
110956 + (uint16_t)be32_to_cpu(uint32_prop[5]);
110957 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
110958 + (uint16_t)be32_to_cpu(uint32_prop[6]);
110959 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
110960 + (uint16_t)be32_to_cpu(uint32_prop[7]);
110961 +
110962 + uint32_prop = (uint32_t *)of_get_property(port_node,
110963 + "ar-filters-sizes", &lenp);
110964 + if (uint32_prop) {
110965 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
110966 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110967 +
110968 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
110969 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110970 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
110971 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110972 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
110973 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110974 + }
110975 +
110976 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
110977 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
110978 + RETURN_ERROR(MINOR, err, NO_MSG);
110979 + }
110980 +
110981 + of_node_put(port_node);
110982 + of_node_put(fm_node);
110983 +
110984 + return E_OK;
110985 +}
110986 +
110987 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110988 +{
110989 + struct device_node *fm_node, *port_node;
110990 + t_Error err;
110991 + const uint32_t *uint32_prop;
110992 + /*const char *str_prop;*/
110993 + int lenp;
110994 +
110995 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110996 + if (!fm_node) /* no advance parameters for FMan */
110997 + return E_OK;
110998 +
110999 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
111000 + p_LnxWrpFmPortDev->settings.param.portType,
111001 + p_LnxWrpFmPortDev->settings.param.portId);
111002 + if (!port_node) /* no advance parameters for FMan-Port */
111003 + return E_OK;
111004 +
111005 +#if (DPAA_VERSION >= 11)
111006 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
111007 + if (uint32_prop) {
111008 + t_FmPortVSPAllocParams portVSPAllocParams;
111009 + t_FmVspParams fmVspParams;
111010 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111011 + uint8_t portId;
111012 +
111013 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111014 +
111015 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
111016 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111017 +
111018 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
111019 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
111020 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111021 + p_LnxWrpFmPortDev->settings.frag_enabled))
111022 + return E_OK;
111023 +
111024 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
111025 + memset(&fmVspParams, 0, sizeof(fmVspParams));
111026 +
111027 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
111028 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
111029 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111030 +
111031 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
111032 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
111033 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
111034 +
111035 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
111036 + {
111037 + portId = fmVspParams.portParams.portId;
111038 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
111039 +#ifndef CONFIG_FMAN_ARM
111040 + if (!(IS_T1023_T1024))
111041 +#endif
111042 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
111043 + }
111044 + portVSPAllocParams.h_FmTxPort =
111045 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
111046 + fmVspParams.liodnOffset =
111047 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
111048 + memcpy(&fmVspParams.extBufPools,
111049 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
111050 + sizeof(t_FmExtPools));
111051 + }
111052 + else
111053 + {
111054 + memcpy(&fmVspParams.extBufPools,
111055 + &p_LnxWrpFmPortDev->opExtPools,
111056 + sizeof(t_FmExtPools));
111057 + }
111058 +
111059 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
111060 + &portVSPAllocParams)) != E_OK)
111061 + RETURN_ERROR(MINOR, err, NO_MSG);
111062 +
111063 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
111064 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111065 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
111066 + return E_OK;
111067 +
111068 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
111069 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
111070 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
111071 +
111072 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
111073 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
111074 + RETURN_ERROR(MINOR, err, NO_MSG);
111075 +
111076 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
111077 + RETURN_ERROR(MINOR, err, NO_MSG);
111078 + }
111079 +#else
111080 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
111081 +#endif /* (DPAA_VERSION >= 11) */
111082 +
111083 + of_node_put(port_node);
111084 + of_node_put(fm_node);
111085 +
111086 + return E_OK;
111087 +}
111088 +
111089 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111090 +{
111091 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111092 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111093 + struct resource *dev_res;
111094 +
111095 + if (!p_LnxWrpFmPortDev->active)
111096 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
111097 + ("FM port not configured!!!"));
111098 +
111099 + dev_res =
111100 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111101 + p_LnxWrpFmPortDev->phys_baseAddr,
111102 + p_LnxWrpFmPortDev->memSize,
111103 + "fman-port-hc");
111104 + if (unlikely(dev_res == NULL))
111105 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
111106 + ("__devm_request_region() failed"));
111107 + p_LnxWrpFmPortDev->baseAddr =
111108 + PTR_TO_UINT(devm_ioremap
111109 + (p_LnxWrpFmDev->dev,
111110 + p_LnxWrpFmPortDev->phys_baseAddr,
111111 + p_LnxWrpFmPortDev->memSize));
111112 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
111113 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111114 + ("devm_ioremap() failed"));
111115 +
111116 + p_LnxWrpFmPortDev->settings.param.baseAddr =
111117 + p_LnxWrpFmPortDev->baseAddr;
111118 +
111119 + return E_OK;
111120 +}
111121 +
111122 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111123 +{
111124 +#define MY_ADV_CONFIG_CHECK_END \
111125 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
111126 + ("Advanced configuration routine"));\
111127 + if (errCode != E_OK)\
111128 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
111129 + }
111130 +
111131 + int i = 0;
111132 +
111133 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
111134 + return E_INVALID_STATE;
111135 +
111136 + p_LnxWrpFmPortDev->h_Dev =
111137 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
111138 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
111139 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
111140 +
111141 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
111142 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111143 + e_FM_PORT_TYPE_TX_10G)
111144 + || (p_LnxWrpFmPortDev->settings.param.portType ==
111145 + e_FM_PORT_TYPE_TX)) {
111146 + t_Error errCode = E_OK;
111147 + errCode =
111148 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
111149 + TRUE);
111150 + if (errCode != E_OK)
111151 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
111152 + errCode =
111153 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
111154 + e_FM_PORT_DEQ_FULL_PREFETCH);
111155 + if (errCode
111156 + != E_OK)
111157 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
111158 + }
111159 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
111160 +
111161 +#ifndef CONFIG_FMAN_ARM
111162 +#ifdef FM_BCB_ERRATA_BMI_SW001
111163 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
111164 +#define SVR_SECURITY_MASK 0x00080000
111165 +#define SVR_PERSONALITY_MASK 0x0000FF00
111166 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
111167 +#define SVR_B4860_REV1_VALUE 0x86800010
111168 +
111169 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111170 + e_FM_PORT_TYPE_RX_10G) ||
111171 + (p_LnxWrpFmPortDev->settings.param.portType ==
111172 + e_FM_PORT_TYPE_RX)) {
111173 + unsigned int svr;
111174 +
111175 + svr = mfspr(SPRN_SVR);
111176 +
111177 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
111178 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
111179 + }
111180 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
111181 +#endif /* CONFIG_FMAN_ARM */
111182 +/* Call the driver's advanced configuration routines, if requested:
111183 + Compare the function pointer of each entry to the available routines,
111184 + and invoke the matching routine with proper casting of arguments. */
111185 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
111186 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
111187 +
111188 +/* TODO: Change this MACRO */
111189 + ADV_CONFIG_CHECK_START(
111190 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
111191 +
111192 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111193 + FM_PORT_ConfigBufferPrefixContent,
111194 + NCSW_PARAMS(1,
111195 + (t_FmBufferPrefixContent *)))
111196 +
111197 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111198 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111199 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
111200 +
111201 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111202 + FM_PORT_ConfigExtBufPools,
111203 + NCSW_PARAMS(1, (t_FmExtPools *)))
111204 +
111205 + /* this define contains an else */
111206 + MY_ADV_CONFIG_CHECK_END
111207 + }
111208 +
111209 + /* Advance to next advanced configuration entry */
111210 + i++;
111211 + }
111212 +
111213 +
111214 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
111215 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
111216 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
111217 + FM_PORT_FRM_ERR_IPR_NCSP |
111218 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
111219 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111220 + }
111221 +
111222 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111223 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111224 +
111225 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
111226 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111227 +
111228 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111229 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111230 +
111231 +/* FMan Fifo sizes behind the scene":
111232 + * Using the following formulae (*), under a set of simplifying assumptions (.):
111233 + * . all ports are configured in Normal Mode (rather than Independent Mode)
111234 + * . the DPAA Eth driver allocates buffers of size:
111235 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
111236 + * + DPA_HASH_RESULTS_SIZE, i.e.:
111237 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
111238 + * MAXFRM + 66
111239 + * . excessive buffer pools not accounted for
111240 + *
111241 + * * for Rx ports on P4080:
111242 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
111243 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
111244 + * add up to 256 to the above
111245 + *
111246 + * * for Rx ports on P1023:
111247 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
111248 + * if at least 2 bpools are configured
111249 + * . IFSZ = 8 * 256, if only a single bpool is configured
111250 + *
111251 + * * for Tx ports:
111252 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
111253 + * + FMBM_TFP[DPDE] * 256, i.e.:
111254 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
111255 + *
111256 + * * for OH ports on P4080:
111257 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
111258 + * * for OH ports on P1023:
111259 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
111260 + * * for both P4080 and P1023:
111261 + * . (conservative decisions, assuming that BMI must bring the entire
111262 + * frame, not only the frame header)
111263 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
111264 + * add up to 256 to the above
111265 + *
111266 + * . for P4080/P5020/P3041/P2040, DPDE is:
111267 + * > 0 or 1, for 1Gb ports, HW default: 0
111268 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
111269 + * . for P1023, DPDE should be 1
111270 + *
111271 + * . for P1023, MXT is in range (0..31)
111272 + * . for P4080, MXT is in range (0..63)
111273 + *
111274 + */
111275 +#if 0
111276 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
111277 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
111278 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111279 +#endif
111280 + return E_OK;
111281 +}
111282 +
111283 +void fm_set_rx_port_params(struct fm_port *port,
111284 + struct fm_port_params *params)
111285 +{
111286 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111287 + int i;
111288 +
111289 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
111290 + params->errq;
111291 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
111292 + params->defq;
111293 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
111294 + numOfPoolsUsed = params->num_pools;
111295 + for (i = 0; i < params->num_pools; i++) {
111296 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111297 + extBufPools.extBufPool[i].id =
111298 + params->pool_param[i].id;
111299 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111300 + extBufPools.extBufPool[i].size =
111301 + params->pool_param[i].size;
111302 + }
111303 +
111304 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111305 + params->priv_data_size;
111306 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111307 + params->parse_results;
111308 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111309 + params->hash_results;
111310 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111311 + params->time_stamp;
111312 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111313 + params->data_align;
111314 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111315 + params->manip_extra_space;
111316 +
111317 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111318 + FM_MAX_NUM_OF_ADV_SETTINGS)
111319 +
111320 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111321 + ARGS(1,
111322 + (&p_LnxWrpFmPortDev->
111323 + buffPrefixContent)));
111324 +
111325 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111326 +}
111327 +EXPORT_SYMBOL(fm_set_rx_port_params);
111328 +
111329 +/* this function is called from oh_probe as well, thus it contains oh port
111330 + * specific parameters (make sure everything is checked) */
111331 +void fm_set_tx_port_params(struct fm_port *port,
111332 + struct fm_port_params *params)
111333 +{
111334 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111335 +
111336 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
111337 + params->errq;
111338 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
111339 + dfltFqid = params->defq;
111340 +
111341 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111342 + params->priv_data_size;
111343 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111344 + params->parse_results;
111345 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111346 + params->hash_results;
111347 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111348 + params->time_stamp;
111349 + p_LnxWrpFmPortDev->settings.frag_enabled =
111350 + params->frag_enable;
111351 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111352 + params->data_align;
111353 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111354 + params->manip_extra_space;
111355 +
111356 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111357 + FM_MAX_NUM_OF_ADV_SETTINGS)
111358 +
111359 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111360 + ARGS(1,
111361 + (&p_LnxWrpFmPortDev->
111362 + buffPrefixContent)));
111363 +
111364 + /* oh port specific parameter (for fragmentation only) */
111365 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111366 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111367 + params->num_pools) {
111368 + int i;
111369 +
111370 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
111371 + for (i = 0; i < params->num_pools; i++) {
111372 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
111373 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
111374 + }
111375 +
111376 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
111377 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
111378 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
111379 + }
111380 +
111381 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111382 +}
111383 +EXPORT_SYMBOL(fm_set_tx_port_params);
111384 +
111385 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
111386 + t_Handle h_fm_mac,
111387 + int mac_id)
111388 +{
111389 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
111390 +
111391 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
111392 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
111393 +}
111394 +EXPORT_SYMBOL(fm_mac_set_handle);
111395 +
111396 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
111397 + e_FmPcdExceptions exception)
111398 +{
111399 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111400 +
111401 + ASSERT_COND(p_LnxWrpFmDev);
111402 +
111403 + DBG(INFO, ("got fm-pcd exception %d", exception));
111404 +
111405 + /* do nothing */
111406 + UNUSED(exception);
111407 +}
111408 +
111409 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
111410 + e_FmPcdExceptions exception,
111411 + uint16_t index)
111412 +{
111413 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111414 +
111415 + ASSERT_COND(p_LnxWrpFmDev);
111416 +
111417 + DBG(INFO,
111418 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
111419 +
111420 + /* do nothing */
111421 + UNUSED(exception);
111422 + UNUSED(index);
111423 +}
111424 +
111425 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111426 +{
111427 + spin_lock_init(&lock);
111428 +
111429 + if (p_LnxWrpFmDev->pcdActive) {
111430 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111431 + t_FmPcdParams fmPcdParams;
111432 + t_Error err;
111433 +
111434 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
111435 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111436 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
111437 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
111438 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
111439 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
111440 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
111441 +
111442 +#ifndef CONFIG_GUEST_PARTITION
111443 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
111444 + if (fmPcdParams.kgSupport)
111445 + fmPcdParams.f_ExceptionId =
111446 + LnxwrpFmPcdDevIndexedExceptionsCb;
111447 + fmPcdParams.h_App = p_LnxWrpFmDev;
111448 +#endif /* !CONFIG_GUEST_PARTITION */
111449 +
111450 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
111451 + fmPcdParams.numOfSchemes = 0;
111452 + fmPcdParams.numOfClsPlanEntries = 0;
111453 + fmPcdParams.partitionId = 0;
111454 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
111455 + fmPcdParams.useHostCommand = TRUE;
111456 +
111457 + p_LnxWrpFmDev->hc_tx_fq =
111458 + FqAlloc(p_LnxWrpFmDev,
111459 + 0,
111460 + QMAN_FQ_FLAG_TO_DCPORTAL,
111461 + p_LnxWrpFmPortDev->txCh, 0);
111462 + if (!p_LnxWrpFmDev->hc_tx_fq)
111463 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111464 + ("Frame queue allocation failed..."));
111465 +
111466 + p_LnxWrpFmDev->hc_tx_conf_fq =
111467 + FqAlloc(p_LnxWrpFmDev,
111468 + 0,
111469 + QMAN_FQ_FLAG_NO_ENQUEUE,
111470 + p_LnxWrpFmDev->hcCh, 1);
111471 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
111472 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111473 + ("Frame queue allocation failed..."));
111474 +
111475 + p_LnxWrpFmDev->hc_tx_err_fq =
111476 + FqAlloc(p_LnxWrpFmDev,
111477 + 0,
111478 + QMAN_FQ_FLAG_NO_ENQUEUE,
111479 + p_LnxWrpFmDev->hcCh, 2);
111480 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
111481 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111482 + ("Frame queue allocation failed..."));
111483 +
111484 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
111485 + fmPcdParams.hc.portId =
111486 + p_LnxWrpFmPortDev->settings.param.portId;
111487 + fmPcdParams.hc.liodnBase =
111488 + p_LnxWrpFmPortDev->settings.param.liodnBase;
111489 + fmPcdParams.hc.errFqid =
111490 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
111491 + fmPcdParams.hc.confFqid =
111492 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
111493 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
111494 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
111495 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
111496 +
111497 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
111498 + if (!p_LnxWrpFmDev->h_PcdDev)
111499 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
111500 +
111501 + err =
111502 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
111503 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
111504 + if (err != E_OK)
111505 + RETURN_ERROR(MAJOR, err, NO_MSG);
111506 +
111507 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
111508 + if (err != E_OK)
111509 + RETURN_ERROR(MAJOR, err, NO_MSG);
111510 +
111511 + if (p_LnxWrpFmDev->err_irq == 0) {
111512 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111513 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
111514 + FALSE);
111515 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111516 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
111517 + FALSE);
111518 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111519 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
111520 + FALSE);
111521 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111522 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
111523 + FALSE);
111524 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111525 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
111526 + FALSE);
111527 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111528 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
111529 + FALSE);
111530 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111531 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
111532 + FALSE);
111533 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111534 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
111535 + FALSE);
111536 + }
111537 + }
111538 +
111539 + return E_OK;
111540 +}
111541 +
111542 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111543 +{
111544 +
111545 + if (p_LnxWrpFmDev->h_PcdDev)
111546 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
111547 +
111548 + if (p_LnxWrpFmDev->hc_tx_err_fq)
111549 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
111550 +
111551 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
111552 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
111553 +
111554 + if (p_LnxWrpFmDev->hc_tx_fq)
111555 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
111556 +}
111557 +
111558 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111559 +{
111560 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111561 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111562 +
111563 + if (!p_LnxWrpFmPortDev->active)
111564 + return;
111565 +
111566 + if (p_LnxWrpFmPortDev->h_Dev)
111567 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
111568 +
111569 + devm_iounmap(p_LnxWrpFmDev->dev,
111570 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
111571 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111572 + p_LnxWrpFmPortDev->phys_baseAddr,
111573 + p_LnxWrpFmPortDev->memSize);
111574 +}
111575 +
111576 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
111577 +{
111578 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111579 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111580 + struct device *dev;
111581 +
111582 + dev = &of_dev->dev;
111583 +
111584 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111585 + if (p_LnxWrpFmPortDev == NULL)
111586 + return -EIO;
111587 + /* Port can be inactive, thus will not be probed:
111588 + - in performance mode, OH ports are disabled
111589 + ...
111590 + */
111591 + if (!p_LnxWrpFmPortDev->active)
111592 + return 0;
111593 +
111594 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111595 + return -EIO;
111596 +
111597 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111598 +
111599 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111600 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111601 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111602 +
111603 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111604 +
111605 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111606 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111607 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111608 + p_LnxWrpFmPortDev->minor =
111609 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111610 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111611 + e_FM_PORT_TYPE_RX_10G) {
111612 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111613 + p_LnxWrpFmDev->name,
111614 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111615 + p_LnxWrpFmPortDev->minor =
111616 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111617 + DEV_FM_RX_PORTS_MINOR_BASE;
111618 +#ifndef CONFIG_FMAN_ARM
111619 + if (IS_T1023_T1024) {
111620 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111621 + p_LnxWrpFmDev->name,
111622 + p_LnxWrpFmPortDev->id);
111623 + p_LnxWrpFmPortDev->minor =
111624 + p_LnxWrpFmPortDev->id +
111625 + DEV_FM_RX_PORTS_MINOR_BASE;
111626 + }
111627 +#endif
111628 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111629 + e_FM_PORT_TYPE_TX) {
111630 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111631 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111632 + p_LnxWrpFmPortDev->minor =
111633 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111634 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111635 + e_FM_PORT_TYPE_TX_10G) {
111636 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111637 + p_LnxWrpFmDev->name,
111638 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111639 + p_LnxWrpFmPortDev->minor =
111640 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111641 + DEV_FM_TX_PORTS_MINOR_BASE;
111642 +#ifndef CONFIG_FMAN_ARM
111643 + if (IS_T1023_T1024) {
111644 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111645 + p_LnxWrpFmDev->name,
111646 + p_LnxWrpFmPortDev->id);
111647 + p_LnxWrpFmPortDev->minor =
111648 + p_LnxWrpFmPortDev->id +
111649 + DEV_FM_TX_PORTS_MINOR_BASE;
111650 + }
111651 +#endif
111652 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111653 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111654 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111655 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111656 + p_LnxWrpFmPortDev->minor =
111657 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111658 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111659 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111660 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111661 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111662 + p_LnxWrpFmPortDev->minor =
111663 + p_LnxWrpFmPortDev->id + 1 +
111664 + DEV_FM_OH_PORTS_MINOR_BASE;
111665 + }
111666 +
111667 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111668 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111669 + NULL, p_LnxWrpFmPortDev->name);
111670 +
111671 + /* create sysfs entries for stats and regs */
111672 +
111673 + if (fm_port_sysfs_create(dev) != 0) {
111674 + FreeFmPortDev(p_LnxWrpFmPortDev);
111675 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111676 + ("Unable to create sys entry - fm port!!!"));
111677 + return -EIO;
111678 + }
111679 +
111680 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111681 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111682 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111683 +
111684 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111685 +
111686 + return 0;
111687 +}
111688 +
111689 +static int fm_port_remove(struct platform_device *of_dev)
111690 +{
111691 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111692 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111693 + struct device *dev;
111694 +
111695 + dev = &of_dev->dev;
111696 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111697 +
111698 + fm_port_sysfs_destroy(dev);
111699 +
111700 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111701 + device_destroy(p_LnxWrpFmDev->fm_class,
111702 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111703 +
111704 + FreeFmPortDev(p_LnxWrpFmPortDev);
111705 +
111706 + dev_set_drvdata(dev, NULL);
111707 +
111708 + return 0;
111709 +}
111710 +
111711 +static const struct of_device_id fm_port_match[] = {
111712 + {
111713 + .compatible = "fsl,fman-port-oh"},
111714 + {
111715 + .compatible = "fsl,fman-port-1g-rx"},
111716 + {
111717 + .compatible = "fsl,fman-port-10g-rx"},
111718 + {
111719 + .compatible = "fsl,fman-port-1g-tx"},
111720 + {
111721 + .compatible = "fsl,fman-port-10g-tx"},
111722 + {}
111723 +};
111724 +
111725 +#ifndef MODULE
111726 +MODULE_DEVICE_TABLE(of, fm_port_match);
111727 +#endif /* !MODULE */
111728 +
111729 +static struct platform_driver fm_port_driver = {
111730 +
111731 + .driver = {
111732 + .name = "fsl-fman-port",
111733 + .of_match_table = fm_port_match,
111734 + .owner = THIS_MODULE,
111735 + },
111736 + .probe = fm_port_probe,
111737 + .remove = fm_port_remove
111738 +};
111739 +
111740 +
111741 +t_Error LNXWRP_FM_Port_Init(void)
111742 +{
111743 + /* Register to the DTB for basic FM port API */
111744 + if (platform_driver_register(&fm_port_driver))
111745 + return E_NO_DEVICE;
111746 +
111747 + return E_OK;
111748 +}
111749 +
111750 +void LNXWRP_FM_Port_Free(void)
111751 +{
111752 + platform_driver_unregister(&fm_port_driver);
111753 +}
111754 +
111755 +static int __init __cold fm_port_load(void)
111756 +{
111757 + if (LNXWRP_FM_Port_Init() != E_OK) {
111758 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111759 + return -ENODEV;
111760 + }
111761 +
111762 + printk(KERN_CRIT "Freescale FM Ports module\n");
111763 +
111764 + return 0;
111765 +}
111766 +
111767 +static void __exit __cold fm_port_unload(void)
111768 +{
111769 + LNXWRP_FM_Port_Free();
111770 +}
111771 +
111772 +module_init(fm_port_load);
111773 +module_exit(fm_port_unload);
111774 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111775 new file mode 100644
111776 index 00000000..1ddde856
111777 --- /dev/null
111778 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111779 @@ -0,0 +1,4813 @@
111780 +/*
111781 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111782 + *
111783 + * Redistribution and use in source and binary forms, with or without
111784 + * modification, are permitted provided that the following conditions are met:
111785 + * * Redistributions of source code must retain the above copyright
111786 + * notice, this list of conditions and the following disclaimer.
111787 + * * Redistributions in binary form must reproduce the above copyright
111788 + * notice, this list of conditions and the following disclaimer in the
111789 + * documentation and/or other materials provided with the distribution.
111790 + * * Neither the name of Freescale Semiconductor nor the
111791 + * names of its contributors may be used to endorse or promote products
111792 + * derived from this software without specific prior written permission.
111793 + *
111794 + *
111795 + * ALTERNATIVELY, this software may be distributed under the terms of the
111796 + * GNU General Public License ("GPL") as published by the Free Software
111797 + * Foundation, either version 2 of that License or (at your option) any
111798 + * later version.
111799 + *
111800 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111801 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111802 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111803 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111804 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111805 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111806 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111807 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111808 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111809 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111810 + */
111811 +
111812 +/*
111813 + @File lnxwrp_ioctls_fm.c
111814 + @Author Shlomi Gridish
111815 + @Description FM Linux wrapper functions.
111816 +*/
111817 +
111818 +/* Linux Headers ------------------- */
111819 +#include <linux/version.h>
111820 +
111821 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111822 +#define MODVERSIONS
111823 +#endif
111824 +#ifdef MODVERSIONS
111825 +#include <config/modversions.h>
111826 +#endif /* MODVERSIONS */
111827 +
111828 +#include <linux/kernel.h>
111829 +#include <linux/module.h>
111830 +#include <linux/slab.h>
111831 +#include <linux/fs.h>
111832 +#include <linux/cdev.h>
111833 +#include <linux/device.h>
111834 +#include <linux/irq.h>
111835 +#include <linux/interrupt.h>
111836 +#include <linux/io.h>
111837 +#include <linux/ioport.h>
111838 +#include <linux/of_platform.h>
111839 +#include <linux/uaccess.h>
111840 +#include <asm/errno.h>
111841 +#ifndef CONFIG_FMAN_ARM
111842 +#include <sysdev/fsl_soc.h>
111843 +#include <linux/fsl/svr.h>
111844 +#endif
111845 +
111846 +#if defined(CONFIG_COMPAT)
111847 +#include <linux/compat.h>
111848 +#endif
111849 +
111850 +#include "part_ext.h"
111851 +#include "fm_ioctls.h"
111852 +#include "fm_pcd_ioctls.h"
111853 +#include "fm_port_ioctls.h"
111854 +#include "fm_vsp_ext.h"
111855 +
111856 +#ifndef CONFIG_FMAN_ARM
111857 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111858 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111859 +#endif
111860 +
111861 +#define __ERR_MODULE__ MODULE_FM
111862 +
111863 +#if defined(CONFIG_COMPAT)
111864 +#include "lnxwrp_ioctls_fm_compat.h"
111865 +#endif
111866 +
111867 +#include "lnxwrp_fm.h"
111868 +
111869 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
111870 +
111871 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
111872 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
111873 +#error Error: please synchronize IOC_ defines!
111874 +#endif
111875 +
111876 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
111877 +#error Error: please synchronize IOC_ defines!
111878 +#endif
111879 +
111880 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
111881 +#error Error: please synchronize IOC_ defines!
111882 +#endif
111883 +
111884 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
111885 +#error Error: please synchronize IOC_ defines!
111886 +#endif
111887 +
111888 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
111889 +#error Error: please synchronize IOC_ defines!
111890 +#endif
111891 +
111892 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
111893 +#error Error: please synchronize IOC_ defines!
111894 +#endif
111895 +
111896 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
111897 +#error Error: please synchronize IOC_ defines!
111898 +#endif
111899 +
111900 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
111901 +#error Error: please synchronize IOC_ defines!
111902 +#endif
111903 +
111904 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
111905 +#error Error: please synchronize IOC_ defines!
111906 +#endif
111907 +
111908 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
111909 +#error Error: please synchronize IOC_ defines!
111910 +#endif
111911 +
111912 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
111913 +#error Error: please synchronize IOC_ defines!
111914 +#endif
111915 +
111916 +#if DPAA_VERSION >= 11
111917 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
111918 +#error Error: please synchronize IOC_ defines!
111919 +#endif
111920 +#endif
111921 +
111922 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
111923 +#error Error: please synchronize IOC_ defines!
111924 +#endif
111925 +
111926 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
111927 +#error Error: please synchronize IOC_ defines!
111928 +#endif
111929 +
111930 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
111931 +#error Error: please synchronize IOC_ defines!
111932 +#endif
111933 +
111934 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
111935 +#error Error: please synchronize IOC_ defines!
111936 +#endif
111937 +
111938 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
111939 +#error Error: please synchronize IOC_ defines!
111940 +#endif
111941 +
111942 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
111943 +#error Error: please synchronize IOC_ defines!
111944 +#endif
111945 +
111946 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
111947 +#error Error: please synchronize IOC_ defines!
111948 +#endif
111949 +
111950 +/* net_ioctls.h === net_ext.h assertions */
111951 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
111952 +#error Error: please synchronize IOC_ defines!
111953 +#endif
111954 +
111955 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
111956 +#error Error: please synchronize IOC_ defines!
111957 +#endif
111958 +
111959 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
111960 +#error Error: please synchronize IOC_ defines!
111961 +#endif
111962 +
111963 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
111964 +#error Error: please synchronize IOC_ defines!
111965 +#endif
111966 +
111967 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
111968 +#error Error: please synchronize IOC_ defines!
111969 +#endif
111970 +
111971 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
111972 +#error Error: please synchronize IOC_ defines!
111973 +#endif
111974 +
111975 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
111976 +#error Error: please synchronize IOC_ defines!
111977 +#endif
111978 +
111979 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
111980 +#error Error: please synchronize IOC_ defines!
111981 +#endif
111982 +
111983 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
111984 +#error Error: please synchronize IOC_ defines!
111985 +#endif
111986 +
111987 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
111988 +#error Error: please synchronize IOC_ defines!
111989 +#endif
111990 +
111991 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
111992 +#error Error: please synchronize IOC_ defines!
111993 +#endif
111994 +
111995 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
111996 +#error Error: please synchronize IOC_ defines!
111997 +#endif
111998 +
111999 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
112000 +#error Error: please synchronize IOC_ defines!
112001 +#endif
112002 +
112003 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
112004 +#error Error: please synchronize IOC_ defines!
112005 +#endif
112006 +
112007 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
112008 +#error Error: please synchronize IOC_ defines!
112009 +#endif
112010 +
112011 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
112012 +#error Error: please synchronize IOC_ defines!
112013 +#endif
112014 +
112015 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
112016 +#error Error: please synchronize IOC_ defines!
112017 +#endif
112018 +
112019 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
112020 +#error Error: please synchronize IOC_ defines!
112021 +#endif
112022 +
112023 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
112024 +#error Error: please synchronize IOC_ defines!
112025 +#endif
112026 +
112027 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
112028 +#error Error: please synchronize IOC_ defines!
112029 +#endif
112030 +
112031 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
112032 +#error Error: please synchronize IOC_ defines!
112033 +#endif
112034 +
112035 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
112036 +#error Error: please synchronize IOC_ defines!
112037 +#endif
112038 +
112039 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
112040 +#error Error: please synchronize IOC_ defines!
112041 +#endif
112042 +
112043 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
112044 +#error Error: please synchronize IOC_ defines!
112045 +#endif
112046 +
112047 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
112048 +#error Error: please synchronize IOC_ defines!
112049 +#endif
112050 +
112051 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
112052 +#warning Error: please synchronize IOC_ defines!
112053 +#endif
112054 +
112055 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
112056 +#error Error: please synchronize IOC_ defines!
112057 +#endif
112058 +
112059 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
112060 +#error Error: please synchronize IOC_ defines!
112061 +#endif
112062 +
112063 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
112064 +#error Error: please synchronize IOC_ defines!
112065 +#endif
112066 +
112067 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
112068 +#error Error: please synchronize IOC_ defines!
112069 +#endif
112070 +
112071 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
112072 +#error Error: please synchronize IOC_ defines!
112073 +#endif
112074 +
112075 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
112076 +#error Error: please synchronize IOC_ defines!
112077 +#endif
112078 +
112079 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
112080 +#error Error: please synchronize IOC_ defines!
112081 +#endif
112082 +
112083 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
112084 +#error Error: please synchronize IOC_ defines!
112085 +#endif
112086 +
112087 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
112088 +#error Error: please synchronize IOC_ defines!
112089 +#endif
112090 +
112091 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
112092 +#error Error: please synchronize IOC_ defines!
112093 +#endif
112094 +
112095 +/* fm_ioctls.h === fm_ext.h assertions */
112096 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
112097 +#error Error: please synchronize IOC_ defines!
112098 +#endif
112099 +
112100 +void LnxWrpPCDIOCTLTypeChecking(void)
112101 +{
112102 + /* fm_ext.h == fm_ioctls.h */
112103 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
112104 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
112105 +
112106 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
112107 + /*ioc_fm_pcd_counters_params_t : NOT USED */
112108 + /*ioc_fm_pcd_exception_params_t : private */
112109 +#if (DPAA_VERSION >= 11)
112110 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
112111 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
112112 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
112113 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
112114 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
112115 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
112116 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
112117 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
112118 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
112119 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
112120 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
112121 +#endif /* (DPAA_VERSION >= 11) */
112122 +
112123 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
112124 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
112125 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
112126 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
112127 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
112128 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
112129 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
112130 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
112131 +
112132 +#if defined(CONFIG_ARM64)
112133 + /* different alignment */
112134 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
112135 +#else
112136 +#if !defined(CONFIG_COMPAT)
112137 + /* different alignment */
112138 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
112139 +#endif
112140 +#endif
112141 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
112142 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
112143 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
112144 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
112145 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
112146 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
112147 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
112148 +#if (DPAA_VERSION >= 11)
112149 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
112150 +#endif
112151 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
112152 +#if !defined(CONFIG_COMPAT)
112153 + /* different alignment */
112154 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
112155 +#endif
112156 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
112157 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
112158 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
112159 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
112160 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
112161 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
112162 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
112163 +#if !defined(CONFIG_COMPAT)
112164 + /* different alignment */
112165 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
112166 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
112167 +#endif
112168 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
112169 +#if !defined(CONFIG_COMPAT)
112170 + /* different alignment */
112171 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
112172 +#endif
112173 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
112174 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
112175 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
112176 + /*ioc_fm_pcd_port_params_t : private */
112177 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
112178 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
112179 +
112180 +#ifdef FM_CAPWAP_SUPPORT
112181 +#error TODO: unsupported feature
112182 +/*
112183 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
112184 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
112185 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
112186 +*/
112187 +#endif
112188 +
112189 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
112190 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
112191 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
112192 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
112193 + /*ioc_fm_manip_hdr_info_t : private */
112194 + /*ioc_fm_pcd_hash_table_set_t : private */
112195 +
112196 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
112197 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
112198 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
112199 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
112200 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
112201 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
112202 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
112203 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
112204 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
112205 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
112206 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
112207 +#if !defined(CONFIG_COMPAT)
112208 + /* different alignment */
112209 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
112210 +#endif
112211 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
112212 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
112213 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
112214 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
112215 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
112216 +#if DPAA_VERSION >= 11
112217 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
112218 +#endif
112219 +
112220 + /* fm_port_ext.h == fm_port_ioctls.h */
112221 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
112222 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
112223 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
112224 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
112225 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
112226 +
112227 + return;
112228 +}
112229 +
112230 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
112231 +
112232 +void LnxWrpPCDIOCTLEnumChecking(void)
112233 +{
112234 + /* net_ext.h == net_ioctls.h : sampling checks */
112235 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
112236 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
112237 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
112238 +
112239 + /* fm_ext.h == fm_ioctls.h */
112240 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
112241 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
112242 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
112243 +
112244 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
112245 + 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);
112246 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
112247 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
112248 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
112249 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
112250 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
112251 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
112252 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
112253 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
112254 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
112255 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
112256 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
112257 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
112258 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
112259 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
112260 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
112261 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
112262 + 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);
112263 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
112264 + 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);
112265 +#if !defined(FM_CAPWAP_SUPPORT)
112266 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
112267 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
112268 +#else
112269 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
112270 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
112271 + 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);
112272 +#endif
112273 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
112274 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
112275 +
112276 +#ifdef FM_CAPWAP_SUPPORT
112277 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
112278 +#endif
112279 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
112280 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
112281 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
112282 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
112283 +
112284 + /* fm_port_ext.h == fm_port_ioctls.h */
112285 +#if !defined(FM_CAPWAP_SUPPORT)
112286 + 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);
112287 +#else
112288 + 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);
112289 +#endif
112290 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
112291 + 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);
112292 +
112293 + return;
112294 +}
112295 +
112296 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
112297 +{
112298 + t_Error err = E_OK;
112299 +
112300 +/*
112301 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
112302 +
112303 + FM_PCD_PrsLoadSw
112304 + FM_PCD_SetAdvancedOffloadSupport
112305 + FM_PCD_Enable
112306 + FM_PCD_Disable
112307 + FM_PCD_ForceIntr
112308 + FM_PCD_SetException
112309 + FM_PCD_KgSetAdditionalDataAfterParsing
112310 + FM_PCD_KgSetDfltValue
112311 + FM_PCD_NetEnvCharacteristicsSet
112312 + FM_PCD_NetEnvCharacteristicsDelete
112313 + FM_PCD_KgSchemeSet
112314 + FM_PCD_KgSchemeDelete
112315 + FM_PCD_MatchTableSet
112316 + FM_PCD_MatchTableDelete
112317 + FM_PCD_CcRootBuild
112318 + FM_PCD_CcRootDelete
112319 + FM_PCD_PlcrProfileSet
112320 + FM_PCD_PlcrProfileDelete
112321 + FM_PCD_CcRootModifyNextEngine
112322 + FM_PCD_MatchTableModifyNextEngine
112323 + FM_PCD_MatchTableModifyMissNextEngine
112324 + FM_PCD_MatchTableRemoveKey
112325 + FM_PCD_MatchTableAddKey
112326 + FM_PCD_MatchTableModifyKeyAndNextEngine
112327 + FM_PCD_HashTableSet
112328 + FM_PCD_HashTableDelete
112329 + FM_PCD_HashTableAddKey
112330 + FM_PCD_HashTableRemoveKey
112331 + FM_PCD_MatchTableModifyKey
112332 + FM_PCD_ManipNodeReplace
112333 + FM_PCD_ManipNodeSet
112334 + FM_PCD_ManipNodeDelete
112335 +
112336 +Status: not exported, should be thru sysfs
112337 + FM_PCD_KgSchemeGetCounter
112338 + FM_PCD_KgSchemeSetCounter
112339 + FM_PCD_PlcrProfileGetCounter
112340 + FM_PCD_PlcrProfileSetCounter
112341 +
112342 +Status: not exported
112343 + FM_PCD_MatchTableFindNRemoveKey
112344 + FM_PCD_MatchTableFindNModifyNextEngine
112345 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
112346 + FM_PCD_MatchTableFindNModifyKey
112347 + FM_PCD_MatchTableGetIndexedHashBucket
112348 + FM_PCD_MatchTableGetNextEngine
112349 + FM_PCD_MatchTableGetKeyCounter
112350 +
112351 +Status: not exported, would be nice to have
112352 + FM_PCD_HashTableModifyNextEngine
112353 + FM_PCD_HashTableModifyMissNextEngine
112354 + FM_PCD_HashTableGetMissNextEngine
112355 + FM_PCD_ManipGetStatistics
112356 +
112357 +Status: not exported
112358 +#if DPAA_VERSION >= 11
112359 +
112360 + FM_VSP_GetStatistics -- it's not available yet
112361 +#endif
112362 +
112363 +Status: feature not supported
112364 +#ifdef FM_CAPWAP_SUPPORT
112365 +#error unsupported feature
112366 + FM_PCD_StatisticsSetNode
112367 +#endif
112368 +
112369 + */
112370 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
112371 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
112372 +
112373 + switch (cmd)
112374 + {
112375 +#if defined(CONFIG_COMPAT)
112376 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
112377 +#endif
112378 + case FM_PCD_IOC_PRS_LOAD_SW:
112379 + {
112380 + ioc_fm_pcd_prs_sw_params_t *param;
112381 + uint8_t *p_code;
112382 +
112383 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
112384 + if (!param)
112385 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112386 +
112387 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
112388 +
112389 +#if defined(CONFIG_COMPAT)
112390 + if (compat)
112391 + {
112392 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
112393 +
112394 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
112395 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112396 + if (!compat_param)
112397 + {
112398 + XX_Free(param);
112399 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112400 + }
112401 +
112402 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112403 + if (copy_from_user(compat_param,
112404 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
112405 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
112406 + {
112407 + XX_Free(compat_param);
112408 + XX_Free(param);
112409 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112410 + }
112411 +
112412 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
112413 +
112414 + XX_Free(compat_param);
112415 + }
112416 + else
112417 +#endif
112418 + {
112419 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
112420 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
112421 + {
112422 + XX_Free(param);
112423 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112424 + }
112425 + }
112426 +
112427 + if (!param->p_code || !param->size)
112428 + {
112429 + XX_Free(param);
112430 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112431 + }
112432 +
112433 + p_code = (uint8_t *) XX_Malloc(param->size);
112434 + if (!p_code)
112435 + {
112436 + XX_Free(param);
112437 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112438 + }
112439 +
112440 + memset(p_code, 0, param->size);
112441 + if (copy_from_user(p_code, param->p_code, param->size))
112442 + {
112443 + XX_Free(p_code);
112444 + XX_Free(param);
112445 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112446 + }
112447 +
112448 + param->p_code = p_code;
112449 +
112450 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
112451 +
112452 + XX_Free(p_code);
112453 + XX_Free(param);
112454 + break;
112455 + }
112456 +
112457 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
112458 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
112459 + break;
112460 +
112461 + case FM_PCD_IOC_ENABLE:
112462 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
112463 + break;
112464 +
112465 + case FM_PCD_IOC_DISABLE:
112466 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
112467 + break;
112468 +
112469 + case FM_PCD_IOC_FORCE_INTR:
112470 + {
112471 + int exception;
112472 +
112473 +#if defined(CONFIG_COMPAT)
112474 + if (compat)
112475 + {
112476 + if (get_user(exception, (int *) compat_ptr(arg)))
112477 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112478 + }
112479 + else
112480 +#endif
112481 + {
112482 + if (get_user(exception, (int *)arg))
112483 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112484 + }
112485 +
112486 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
112487 + break;
112488 + }
112489 +
112490 + case FM_PCD_IOC_SET_EXCEPTION:
112491 + {
112492 + ioc_fm_pcd_exception_params_t *param;
112493 +
112494 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
112495 + sizeof(ioc_fm_pcd_exception_params_t));
112496 + if (!param)
112497 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112498 +
112499 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
112500 +
112501 +#if defined(CONFIG_COMPAT)
112502 + if (compat)
112503 + {
112504 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
112505 + sizeof(ioc_fm_pcd_exception_params_t)))
112506 + {
112507 + XX_Free(param);
112508 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112509 + }
112510 + }
112511 + else
112512 +#endif
112513 + {
112514 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
112515 + sizeof(ioc_fm_pcd_exception_params_t)))
112516 + {
112517 + XX_Free(param);
112518 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112519 + }
112520 + }
112521 +
112522 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
112523 +
112524 + XX_Free(param);
112525 + break;
112526 + }
112527 +
112528 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
112529 + {
112530 + uint8_t payloadOffset;
112531 +
112532 +#if defined(CONFIG_COMPAT)
112533 + if (compat)
112534 + {
112535 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
112536 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112537 + }
112538 + else
112539 +#endif
112540 + {
112541 + if (get_user(payloadOffset, (uint8_t*) arg))
112542 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112543 + }
112544 +
112545 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
112546 + break;
112547 + }
112548 +
112549 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
112550 + {
112551 + ioc_fm_pcd_kg_dflt_value_params_t *param;
112552 +
112553 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
112554 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112555 + if (!param)
112556 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112557 +
112558 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112559 +
112560 +#if defined(CONFIG_COMPAT)
112561 + if (compat)
112562 + {
112563 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
112564 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112565 + {
112566 + XX_Free(param);
112567 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112568 + }
112569 + }
112570 + else
112571 +#endif
112572 + {
112573 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
112574 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112575 + {
112576 + XX_Free(param);
112577 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112578 + }
112579 + }
112580 +
112581 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
112582 +
112583 + XX_Free(param);
112584 + break;
112585 + }
112586 +
112587 +#if defined(CONFIG_COMPAT)
112588 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112589 +#endif
112590 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112591 + {
112592 + ioc_fm_pcd_net_env_params_t *param;
112593 +
112594 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112595 + if (!param)
112596 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112597 +
112598 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112599 +
112600 +#if defined(CONFIG_COMPAT)
112601 + if (compat)
112602 + {
112603 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112604 +
112605 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112606 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112607 + if (!compat_param)
112608 + {
112609 + XX_Free(param);
112610 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112611 + }
112612 +
112613 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112614 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112615 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112616 + {
112617 + XX_Free(compat_param);
112618 + XX_Free(param);
112619 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112620 + }
112621 +
112622 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112623 + XX_Free(compat_param);
112624 + }
112625 + else
112626 +#endif
112627 + {
112628 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112629 + sizeof(ioc_fm_pcd_net_env_params_t)))
112630 + {
112631 + XX_Free(param);
112632 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112633 + }
112634 + }
112635 +
112636 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112637 +
112638 + if (!param->id)
112639 + {
112640 + XX_Free(param);
112641 + err = E_INVALID_VALUE;
112642 + /* Since the LLD has no errno-style error reporting,
112643 + we're left here with no other option than to report
112644 + a generic E_INVALID_VALUE */
112645 + break;
112646 + }
112647 +
112648 +#if defined(CONFIG_COMPAT)
112649 + if (compat)
112650 + {
112651 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112652 +
112653 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112654 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112655 + if (!compat_param)
112656 + {
112657 + XX_Free(param);
112658 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112659 + }
112660 +
112661 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112662 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112663 +
112664 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112665 + compat_param,
112666 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112667 + err = E_READ_FAILED;
112668 +
112669 + XX_Free(compat_param);
112670 + }
112671 + else
112672 +#endif
112673 + {
112674 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112675 + param,
112676 + sizeof(ioc_fm_pcd_net_env_params_t)))
112677 + err = E_READ_FAILED;
112678 + }
112679 +
112680 + XX_Free(param);
112681 + break;
112682 + }
112683 +
112684 +#if defined(CONFIG_COMPAT)
112685 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112686 +#endif
112687 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112688 + {
112689 + ioc_fm_obj_t id;
112690 +
112691 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112692 +
112693 +#if defined(CONFIG_COMPAT)
112694 + if (compat)
112695 + {
112696 + ioc_compat_fm_obj_t compat_id;
112697 +
112698 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112699 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112700 +
112701 + compat_obj_delete(&compat_id, &id);
112702 + }
112703 + else
112704 +#endif
112705 + {
112706 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112707 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112708 + }
112709 +
112710 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112711 + break;
112712 + }
112713 +
112714 +#if defined(CONFIG_COMPAT)
112715 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112716 +#endif
112717 + case FM_PCD_IOC_KG_SCHEME_SET:
112718 + {
112719 + ioc_fm_pcd_kg_scheme_params_t *param;
112720 +
112721 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112722 + if (!param)
112723 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112724 +
112725 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112726 +
112727 +#if defined(CONFIG_COMPAT)
112728 + if (compat)
112729 + {
112730 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112731 +
112732 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112733 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112734 + if (!compat_param)
112735 + {
112736 + XX_Free(param);
112737 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112738 + }
112739 +
112740 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112741 +
112742 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112743 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112744 + {
112745 + XX_Free(compat_param);
112746 + XX_Free(param);
112747 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112748 + }
112749 +
112750 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112751 +
112752 + XX_Free(compat_param);
112753 + }
112754 + else
112755 +#endif
112756 + {
112757 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112758 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112759 + {
112760 + XX_Free(param);
112761 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112762 + }
112763 + }
112764 +
112765 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112766 +
112767 + if (!param->id)
112768 + {
112769 + XX_Free(param);
112770 + err = E_INVALID_VALUE;
112771 + /* Since the LLD has no errno-style error reporting,
112772 + we're left here with no other option than to report
112773 + a generic E_INVALID_VALUE */
112774 + break;
112775 + }
112776 +
112777 +#if defined(CONFIG_COMPAT)
112778 + if (compat)
112779 + {
112780 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112781 +
112782 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112783 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112784 + if (!compat_param)
112785 + {
112786 + XX_Free(param);
112787 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112788 + }
112789 +
112790 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112791 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112792 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112793 + compat_param,
112794 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112795 + err = E_READ_FAILED;
112796 +
112797 + XX_Free(compat_param);
112798 + }
112799 + else
112800 +#endif
112801 + {
112802 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112803 + param,
112804 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112805 + err = E_READ_FAILED;
112806 + }
112807 +
112808 + XX_Free(param);
112809 + break;
112810 + }
112811 +
112812 +#if defined(CONFIG_COMPAT)
112813 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112814 +#endif
112815 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112816 + {
112817 + ioc_fm_pcd_kg_scheme_spc_t *param;
112818 +
112819 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112820 + if (!param)
112821 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112822 +
112823 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112824 +
112825 +#if defined(CONFIG_COMPAT)
112826 + if (compat)
112827 + {
112828 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112829 +
112830 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112831 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112832 + if (!compat_param)
112833 + {
112834 + XX_Free(param);
112835 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112836 + }
112837 +
112838 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112839 +
112840 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
112841 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112842 + {
112843 + XX_Free(compat_param);
112844 + XX_Free(param);
112845 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112846 + }
112847 +
112848 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
112849 +
112850 + XX_Free(compat_param);
112851 + }
112852 + else
112853 +#endif
112854 + {
112855 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
112856 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112857 + {
112858 + XX_Free(param);
112859 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112860 + }
112861 + }
112862 +
112863 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
112864 +
112865 +#if defined(CONFIG_COMPAT)
112866 + if (compat)
112867 + {
112868 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
112869 +
112870 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112871 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112872 + if (!compat_param)
112873 + {
112874 + XX_Free(param);
112875 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112876 + }
112877 +
112878 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112879 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
112880 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
112881 + compat_param,
112882 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112883 + err = E_READ_FAILED;
112884 +
112885 + XX_Free(compat_param);
112886 + }
112887 + else
112888 +#endif
112889 + {
112890 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
112891 + param,
112892 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112893 + err = E_READ_FAILED;
112894 + }
112895 +
112896 + XX_Free(param);
112897 + break;
112898 + }
112899 +
112900 +#if defined(CONFIG_COMPAT)
112901 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
112902 +#endif
112903 + case FM_PCD_IOC_KG_SCHEME_DELETE:
112904 + {
112905 + ioc_fm_obj_t id;
112906 +
112907 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112908 +
112909 +#if defined(CONFIG_COMPAT)
112910 + if (compat)
112911 + {
112912 + ioc_compat_fm_obj_t compat_id;
112913 +
112914 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112915 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112916 +
112917 + compat_obj_delete(&compat_id, &id);
112918 + }
112919 + else
112920 +#endif
112921 + {
112922 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112923 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112924 + }
112925 +
112926 + err = FM_PCD_KgSchemeDelete(id.obj);
112927 + break;
112928 + }
112929 +
112930 +#if defined(CONFIG_COMPAT)
112931 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
112932 +#endif
112933 + case FM_PCD_IOC_MATCH_TABLE_SET:
112934 + {
112935 + ioc_fm_pcd_cc_node_params_t *param;
112936 + uint8_t *keys;
112937 + uint8_t *masks;
112938 + int i,k;
112939 +
112940 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
112941 + sizeof(ioc_fm_pcd_cc_node_params_t) +
112942 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112943 + if (!param)
112944 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112945 +
112946 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
112947 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112948 +
112949 + keys = (uint8_t *) (param + 1);
112950 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
112951 +
112952 +#if defined(CONFIG_COMPAT)
112953 + if (compat)
112954 + {
112955 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112956 +
112957 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112958 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112959 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112960 + if (!compat_param)
112961 + {
112962 + XX_Free(param);
112963 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112964 + }
112965 +
112966 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112967 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112968 +
112969 + if (copy_from_user(compat_param,
112970 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112971 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112972 + {
112973 + XX_Free(compat_param);
112974 + XX_Free(param);
112975 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112976 + }
112977 +
112978 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
112979 +
112980 + XX_Free(compat_param);
112981 + }
112982 + else
112983 +#endif
112984 + {
112985 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
112986 + {
112987 + XX_Free(param);
112988 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112989 + }
112990 + }
112991 +
112992 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
112993 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
112994 +
112995 + /* support for indexed lookup */
112996 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
112997 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
112998 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
112999 + {
113000 + for (i=0, k=0;
113001 + i < param->keys_params.num_of_keys;
113002 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
113003 + {
113004 + if (param->keys_params.key_params[i].p_key &&
113005 + param->keys_params.key_size)
113006 + {
113007 + if (copy_from_user(&keys[k],
113008 + param->keys_params.key_params[i].p_key,
113009 + param->keys_params.key_size))
113010 + {
113011 + XX_Free(param);
113012 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113013 + }
113014 +
113015 + param->keys_params.key_params[i].p_key = &keys[k];
113016 + }
113017 +
113018 + if (param->keys_params.key_params[i].p_mask)
113019 + {
113020 + if (copy_from_user(&masks[k],
113021 + param->keys_params.key_params[i].p_mask,
113022 + param->keys_params.key_size))
113023 + {
113024 + XX_Free(param);
113025 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113026 + }
113027 +
113028 + param->keys_params.key_params[i].p_mask = &masks[k];
113029 + }
113030 + }
113031 + }
113032 +
113033 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
113034 +
113035 + if (!param->id) {
113036 + XX_Free(param);
113037 + err = E_INVALID_VALUE;
113038 + /* Since the LLD has no errno-style error reporting,
113039 + we're left here with no other option than to report
113040 + a generic E_INVALID_VALUE */
113041 + break;
113042 + }
113043 +
113044 +#if defined(CONFIG_COMPAT)
113045 + if (compat)
113046 + {
113047 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
113048 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
113049 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113050 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113051 + if (!compat_param)
113052 + {
113053 + XX_Free(param);
113054 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113055 + }
113056 +
113057 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113058 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113059 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
113060 +
113061 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
113062 + compat_param,
113063 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
113064 + err = E_READ_FAILED;
113065 +
113066 + XX_Free(compat_param);
113067 + }
113068 + else
113069 +#endif
113070 + {
113071 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
113072 + param,
113073 + sizeof(ioc_fm_pcd_cc_node_params_t)))
113074 + err = E_READ_FAILED;
113075 + }
113076 +
113077 + XX_Free(param);
113078 + break;
113079 + }
113080 +
113081 +#if defined(CONFIG_COMPAT)
113082 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
113083 +#endif
113084 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
113085 + {
113086 + ioc_fm_obj_t id;
113087 +
113088 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113089 +
113090 +#if defined(CONFIG_COMPAT)
113091 + if (compat)
113092 + {
113093 + ioc_compat_fm_obj_t compat_id;
113094 +
113095 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113096 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113097 +
113098 + compat_obj_delete(&compat_id, &id);
113099 + }
113100 + else
113101 +#endif
113102 + {
113103 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113104 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113105 + }
113106 +
113107 + err = FM_PCD_MatchTableDelete(id.obj);
113108 + break;
113109 + }
113110 +
113111 +#if defined(CONFIG_COMPAT)
113112 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
113113 +#endif
113114 + case FM_PCD_IOC_CC_ROOT_BUILD:
113115 + {
113116 + ioc_fm_pcd_cc_tree_params_t *param;
113117 +
113118 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
113119 + if (!param)
113120 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113121 +
113122 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
113123 +
113124 +#if defined(CONFIG_COMPAT)
113125 + if (compat)
113126 + {
113127 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
113128 +
113129 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
113130 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113131 + if (!compat_param)
113132 + {
113133 + XX_Free(param);
113134 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113135 + }
113136 +
113137 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113138 + if (copy_from_user(compat_param,
113139 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
113140 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
113141 + {
113142 + XX_Free(compat_param);
113143 + XX_Free(param);
113144 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113145 + }
113146 +
113147 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
113148 +
113149 + XX_Free(compat_param);
113150 + }
113151 + else
113152 +#endif
113153 + {
113154 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
113155 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
113156 + {
113157 + XX_Free(param);
113158 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113159 + }
113160 + }
113161 +
113162 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
113163 +
113164 + if (!param->id) {
113165 + XX_Free(param);
113166 + err = E_INVALID_VALUE;
113167 + /* Since the LLD has no errno-style error reporting,
113168 + we're left here with no other option than to report
113169 + a generic E_INVALID_VALUE */
113170 + break;
113171 + }
113172 +
113173 +#if defined(CONFIG_COMPAT)
113174 + if (compat)
113175 + {
113176 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
113177 +
113178 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113179 + if (!compat_param)
113180 + {
113181 + XX_Free(param);
113182 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113183 + }
113184 +
113185 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113186 +
113187 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
113188 +
113189 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
113190 + compat_param,
113191 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
113192 + err = E_READ_FAILED;
113193 +
113194 + XX_Free(compat_param);
113195 + }
113196 + else
113197 +#endif
113198 + {
113199 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
113200 + param,
113201 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
113202 + err = E_READ_FAILED;
113203 + }
113204 +
113205 + XX_Free(param);
113206 + break;
113207 + }
113208 +
113209 +#if defined(CONFIG_COMPAT)
113210 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
113211 +#endif
113212 + case FM_PCD_IOC_CC_ROOT_DELETE:
113213 + {
113214 + ioc_fm_obj_t id;
113215 +
113216 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113217 +
113218 +#if defined(CONFIG_COMPAT)
113219 + if (compat)
113220 + {
113221 + ioc_compat_fm_obj_t compat_id;
113222 +
113223 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113224 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113225 +
113226 + compat_obj_delete(&compat_id, &id);
113227 + }
113228 + else
113229 +#endif
113230 + {
113231 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113232 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113233 + }
113234 +
113235 + err = FM_PCD_CcRootDelete(id.obj);
113236 + break;
113237 + }
113238 +
113239 +#if defined(CONFIG_COMPAT)
113240 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
113241 +#endif
113242 + case FM_PCD_IOC_PLCR_PROFILE_SET:
113243 + {
113244 + ioc_fm_pcd_plcr_profile_params_t *param;
113245 +
113246 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113247 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
113248 + if (!param)
113249 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113250 +
113251 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
113252 +
113253 +#if defined(CONFIG_COMPAT)
113254 + if (compat)
113255 + {
113256 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113257 +
113258 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113259 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113260 + if (!compat_param)
113261 + {
113262 + XX_Free(param);
113263 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113264 + }
113265 +
113266 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113267 + if (copy_from_user(compat_param, (
113268 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
113269 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113270 + {
113271 + XX_Free(compat_param);
113272 + XX_Free(param);
113273 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113274 + }
113275 +
113276 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
113277 +
113278 + XX_Free(compat_param);
113279 + }
113280 + else
113281 +#endif
113282 + {
113283 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
113284 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113285 + {
113286 + XX_Free(param);
113287 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113288 + }
113289 + }
113290 +
113291 + if (!param->modify &&
113292 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
113293 + {
113294 + t_Handle h_Port;
113295 + ioc_fm_pcd_port_params_t *port_params;
113296 +
113297 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
113298 + if (!port_params)
113299 + {
113300 + XX_Free(param);
113301 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113302 + }
113303 +
113304 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
113305 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
113306 + sizeof(ioc_fm_pcd_port_params_t)))
113307 + {
113308 + XX_Free(port_params);
113309 + XX_Free(param);
113310 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113311 + }
113312 +
113313 + switch(port_params->port_type)
113314 + {
113315 + case (e_IOC_FM_PORT_TYPE_RX):
113316 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
113317 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113318 + break;
113319 + }
113320 + goto invalid_port_id;
113321 +
113322 + case (e_IOC_FM_PORT_TYPE_RX_10G):
113323 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
113324 +#ifndef CONFIG_FMAN_ARM
113325 + if (IS_T1023_T1024) {
113326 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113327 + } else {
113328 +#else
113329 + {
113330 +#endif
113331 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
113332 + }
113333 + break;
113334 + }
113335 + goto invalid_port_id;
113336 +
113337 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
113338 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
113339 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
113340 + break;
113341 + }
113342 + goto invalid_port_id;
113343 +
113344 + default:
113345 +invalid_port_id:
113346 + XX_Free(port_params);
113347 + XX_Free(param);
113348 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
113349 + }
113350 +
113351 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
113352 + XX_Free(port_params);
113353 + }
113354 +
113355 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
113356 +
113357 + if (!param->id) {
113358 + XX_Free(param);
113359 + err = E_INVALID_VALUE;
113360 + /* Since the LLD has no errno-style error reporting,
113361 + we're left here with no other option than to report
113362 + a generic E_INVALID_VALUE */
113363 + break;
113364 + }
113365 +
113366 +#if defined(CONFIG_COMPAT)
113367 + if (compat)
113368 + {
113369 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113370 +
113371 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113372 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113373 + if (!compat_param)
113374 + {
113375 + XX_Free(param);
113376 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113377 + }
113378 +
113379 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113380 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
113381 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
113382 + compat_param,
113383 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113384 + err = E_READ_FAILED;
113385 +
113386 + XX_Free(compat_param);
113387 + }
113388 + else
113389 +#endif
113390 + {
113391 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
113392 + param,
113393 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113394 + err = E_READ_FAILED;
113395 + }
113396 +
113397 + XX_Free(param);
113398 + break;
113399 + }
113400 +
113401 +#if defined(CONFIG_COMPAT)
113402 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
113403 +#endif
113404 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
113405 + {
113406 + ioc_fm_obj_t id;
113407 +
113408 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113409 +
113410 +#if defined(CONFIG_COMPAT)
113411 + if (compat)
113412 + {
113413 + ioc_compat_fm_obj_t compat_id;
113414 +
113415 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113416 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113417 +
113418 + compat_obj_delete(&compat_id, &id);
113419 + }
113420 + else
113421 +#endif
113422 + {
113423 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113424 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113425 + }
113426 +
113427 + err = FM_PCD_PlcrProfileDelete(id.obj);
113428 + break;
113429 + }
113430 +
113431 +#if defined(CONFIG_COMPAT)
113432 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
113433 +#endif
113434 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
113435 + {
113436 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
113437 +
113438 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113439 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113440 + if (!param)
113441 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113442 +
113443 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113444 +
113445 +#if defined(CONFIG_COMPAT)
113446 + if (compat)
113447 + {
113448 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
113449 +
113450 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113451 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113452 + if (!compat_param)
113453 + {
113454 + XX_Free(param);
113455 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113456 + }
113457 +
113458 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113459 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
113460 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
113461 + {
113462 + XX_Free(compat_param);
113463 + XX_Free(param);
113464 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113465 + }
113466 +
113467 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113468 +
113469 + XX_Free(compat_param);
113470 + }
113471 + else
113472 +#endif
113473 + {
113474 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
113475 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
113476 + {
113477 + XX_Free(param);
113478 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113479 + }
113480 + }
113481 +
113482 + err = FM_PCD_CcRootModifyNextEngine(param->id,
113483 + param->grp_indx,
113484 + param->indx,
113485 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113486 +
113487 + XX_Free(param);
113488 + break;
113489 + }
113490 +
113491 +#if defined(CONFIG_COMPAT)
113492 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
113493 +#endif
113494 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
113495 + {
113496 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113497 +
113498 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113499 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113500 + if (!param)
113501 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113502 +
113503 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113504 +
113505 +#if defined(CONFIG_COMPAT)
113506 + if (compat)
113507 + {
113508 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113509 +
113510 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113511 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113512 + if (!compat_param)
113513 + {
113514 + XX_Free(param);
113515 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113516 + }
113517 +
113518 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113519 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113520 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113521 + {
113522 + XX_Free(compat_param);
113523 + XX_Free(param);
113524 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113525 + }
113526 +
113527 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113528 +
113529 + XX_Free(compat_param);
113530 + }
113531 + else
113532 +#endif
113533 + {
113534 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
113535 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113536 + {
113537 + XX_Free(param);
113538 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113539 + }
113540 + }
113541 +
113542 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
113543 + param->key_indx,
113544 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113545 +
113546 + XX_Free(param);
113547 + break;
113548 + }
113549 +
113550 +#if defined(CONFIG_COMPAT)
113551 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
113552 +#endif
113553 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
113554 + {
113555 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113556 +
113557 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113558 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113559 + if (!param)
113560 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113561 +
113562 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113563 +
113564 +#if defined(CONFIG_COMPAT)
113565 + if (compat)
113566 + {
113567 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113568 +
113569 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113570 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113571 + if (!compat_param)
113572 + {
113573 + XX_Free(param);
113574 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113575 + }
113576 +
113577 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113578 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113579 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113580 + {
113581 + XX_Free(compat_param);
113582 + XX_Free(param);
113583 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113584 + }
113585 +
113586 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113587 +
113588 + XX_Free(compat_param);
113589 + }
113590 + else
113591 +#endif
113592 + {
113593 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113594 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113595 + {
113596 + XX_Free(param);
113597 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113598 + }
113599 + }
113600 +
113601 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113602 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113603 +
113604 + XX_Free(param);
113605 + break;
113606 + }
113607 +
113608 +#if defined(CONFIG_COMPAT)
113609 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113610 +#endif
113611 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113612 + {
113613 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113614 +
113615 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113616 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113617 + if (!param)
113618 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113619 +
113620 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113621 +
113622 +#if defined(CONFIG_COMPAT)
113623 + if (compat)
113624 + {
113625 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113626 +
113627 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113628 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113629 + if (!compat_param)
113630 + {
113631 + XX_Free(param);
113632 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113633 + }
113634 +
113635 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113636 + if (copy_from_user(compat_param,
113637 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113638 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113639 + {
113640 + XX_Free(compat_param);
113641 + XX_Free(param);
113642 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113643 + }
113644 +
113645 + param->id = compat_ptr(compat_param->id);
113646 + param->key_indx = compat_param->key_indx;
113647 +
113648 + XX_Free(compat_param);
113649 + }
113650 + else
113651 +#endif
113652 + {
113653 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113654 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113655 + {
113656 + XX_Free(param);
113657 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113658 + }
113659 + }
113660 +
113661 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113662 +
113663 + XX_Free(param);
113664 + break;
113665 + }
113666 +#if defined(CONFIG_COMPAT)
113667 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113668 +#endif
113669 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113670 + {
113671 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113672 +
113673 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113674 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113675 + if (!param)
113676 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113677 +
113678 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113679 +
113680 +#if defined(CONFIG_COMPAT)
113681 + if (compat)
113682 + {
113683 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113684 +
113685 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113686 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113687 + if (!compat_param)
113688 + {
113689 + XX_Free(param);
113690 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113691 + }
113692 +
113693 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113694 + if (copy_from_user(compat_param,
113695 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113696 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113697 + {
113698 + XX_Free(compat_param);
113699 + XX_Free(param);
113700 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113701 + }
113702 +
113703 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113704 +
113705 + XX_Free(compat_param);
113706 + }
113707 + else
113708 +#endif
113709 + {
113710 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113711 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113712 + {
113713 + XX_Free(param);
113714 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113715 + }
113716 + }
113717 +
113718 + if (param->key_size)
113719 + {
113720 + int size = 0;
113721 +
113722 + if (param->key_params.p_key) size += param->key_size;
113723 + if (param->key_params.p_mask) size += param->key_size;
113724 +
113725 + if (size)
113726 + {
113727 + uint8_t *p_tmp;
113728 +
113729 + p_tmp = (uint8_t*) XX_Malloc(size);
113730 + if (!p_tmp)
113731 + {
113732 + XX_Free(param);
113733 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113734 + }
113735 +
113736 + if (param->key_params.p_key)
113737 + {
113738 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113739 + {
113740 + XX_Free(p_tmp);
113741 + XX_Free(param);
113742 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113743 + }
113744 +
113745 + param->key_params.p_key = p_tmp;
113746 + }
113747 +
113748 + if (param->key_params.p_mask)
113749 + {
113750 + p_tmp += param->key_size;
113751 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113752 + {
113753 + XX_Free(p_tmp - param->key_size);
113754 + XX_Free(param);
113755 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113756 + }
113757 +
113758 + param->key_params.p_mask = p_tmp;
113759 + }
113760 + }
113761 + }
113762 +
113763 + err = FM_PCD_MatchTableAddKey(
113764 + param->id,
113765 + param->key_indx,
113766 + param->key_size,
113767 + (t_FmPcdCcKeyParams*)&param->key_params);
113768 +
113769 + if (param->key_params.p_key)
113770 + XX_Free(param->key_params.p_key);
113771 + XX_Free(param);
113772 + break;
113773 + }
113774 +
113775 +#if defined(CONFIG_COMPAT)
113776 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113777 +#endif
113778 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113779 + {
113780 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113781 +
113782 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113783 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113784 + if (!param)
113785 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113786 +
113787 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113788 +
113789 +#if defined(CONFIG_COMPAT)
113790 + if (compat)
113791 + {
113792 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113793 +
113794 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113795 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113796 + if (!compat_param)
113797 + {
113798 + XX_Free(param);
113799 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113800 + }
113801 +
113802 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113803 + if (copy_from_user(compat_param,
113804 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113805 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113806 + {
113807 + XX_Free(compat_param);
113808 + XX_Free(param);
113809 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113810 + }
113811 +
113812 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113813 +
113814 + XX_Free(compat_param);
113815 + }
113816 + else
113817 +#endif
113818 + {
113819 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113820 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113821 + {
113822 + XX_Free(param);
113823 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113824 + }
113825 + }
113826 +
113827 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113828 + param->key_indx,
113829 + param->key_size,
113830 + (t_FmPcdCcKeyParams*)(&param->key_params));
113831 +
113832 + XX_Free(param);
113833 + break;
113834 + }
113835 +
113836 +
113837 +#if defined(CONFIG_COMPAT)
113838 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
113839 +#endif
113840 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
113841 + {
113842 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113843 +
113844 +#if defined(CONFIG_COMPAT)
113845 + if (compat)
113846 + {
113847 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113848 +
113849 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113850 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113851 + if (!compat_param)
113852 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113853 +
113854 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113855 + if (copy_from_user(compat_param,
113856 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113857 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113858 + {
113859 + XX_Free(compat_param);
113860 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113861 + }
113862 +
113863 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113864 +
113865 + XX_Free(compat_param);
113866 + }
113867 + else
113868 +#endif
113869 + {
113870 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113871 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113872 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113873 + }
113874 +
113875 +
113876 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
113877 + param.key_index,
113878 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113879 +
113880 +#if defined(CONFIG_COMPAT)
113881 + if (compat)
113882 + {
113883 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113884 +
113885 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113886 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113887 + if (!compat_param)
113888 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113889 +
113890 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113891 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113892 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113893 + compat_param,
113894 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113895 + XX_Free(compat_param);
113896 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113897 + }
113898 + XX_Free(compat_param);
113899 + }
113900 + else
113901 +#endif
113902 + {
113903 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113904 + &param,
113905 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113906 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113907 + }
113908 +
113909 + break;
113910 + }
113911 +
113912 +
113913 +#if defined(CONFIG_COMPAT)
113914 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
113915 +#endif
113916 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
113917 + {
113918 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113919 +
113920 +#if defined(CONFIG_COMPAT)
113921 + if (compat)
113922 + {
113923 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113924 +
113925 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113926 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113927 + if (!compat_param)
113928 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113929 +
113930 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113931 + if (copy_from_user(compat_param,
113932 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113933 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113934 + {
113935 + XX_Free(compat_param);
113936 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113937 + }
113938 +
113939 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113940 +
113941 + XX_Free(compat_param);
113942 + }
113943 + else
113944 +#endif
113945 + {
113946 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113947 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113948 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113949 + }
113950 +
113951 +
113952 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
113953 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113954 +
113955 +#if defined(CONFIG_COMPAT)
113956 + if (compat)
113957 + {
113958 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113959 +
113960 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113961 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113962 + if (!compat_param)
113963 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113964 +
113965 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113966 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113967 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113968 + compat_param,
113969 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113970 + XX_Free(compat_param);
113971 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113972 + }
113973 + XX_Free(compat_param);
113974 + }
113975 + else
113976 +#endif
113977 + {
113978 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113979 + &param,
113980 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113981 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113982 + }
113983 +
113984 + break;
113985 + }
113986 +
113987 +
113988 +#if defined(CONFIG_COMPAT)
113989 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
113990 +#endif
113991 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
113992 + {
113993 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113994 +
113995 +#if defined(CONFIG_COMPAT)
113996 + if (compat)
113997 + {
113998 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113999 +
114000 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
114001 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114002 + if (!compat_param)
114003 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114004 +
114005 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114006 + if (copy_from_user(compat_param,
114007 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
114008 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
114009 + {
114010 + XX_Free(compat_param);
114011 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114012 + }
114013 +
114014 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
114015 +
114016 + XX_Free(compat_param);
114017 + }
114018 + else
114019 +#endif
114020 + {
114021 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114022 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114023 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114024 + }
114025 +
114026 +
114027 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
114028 + (t_FmPcdCcKeyStatistics *) &param.statistics);
114029 +
114030 +#if defined(CONFIG_COMPAT)
114031 + if (compat)
114032 + {
114033 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114034 +
114035 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
114036 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114037 + if (!compat_param)
114038 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114039 +
114040 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114041 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
114042 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
114043 + compat_param,
114044 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
114045 + XX_Free(compat_param);
114046 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114047 + }
114048 + XX_Free(compat_param);
114049 + }
114050 + else
114051 +#endif
114052 + {
114053 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114054 + &param,
114055 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114056 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114057 + }
114058 +
114059 + break;
114060 + }
114061 +
114062 +#if defined(CONFIG_COMPAT)
114063 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
114064 +#endif
114065 + case FM_PCD_IOC_HASH_TABLE_SET:
114066 + {
114067 + ioc_fm_pcd_hash_table_params_t *param;
114068 +
114069 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
114070 + sizeof(ioc_fm_pcd_hash_table_params_t));
114071 + if (!param)
114072 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114073 +
114074 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
114075 +
114076 +#if defined(CONFIG_COMPAT)
114077 + if (compat)
114078 + {
114079 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
114080 +
114081 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
114082 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114083 + if (!compat_param)
114084 + {
114085 + XX_Free(param);
114086 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114087 + }
114088 +
114089 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114090 + if (copy_from_user(compat_param,
114091 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
114092 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
114093 + {
114094 + XX_Free(compat_param);
114095 + XX_Free(param);
114096 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114097 + }
114098 +
114099 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
114100 +
114101 + XX_Free(compat_param);
114102 + }
114103 + else
114104 +#endif
114105 + {
114106 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
114107 + sizeof(ioc_fm_pcd_hash_table_params_t)))
114108 + {
114109 + XX_Free(param);
114110 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114111 + }
114112 + }
114113 +
114114 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
114115 +
114116 + if (!param->id)
114117 + {
114118 + XX_Free(param);
114119 + err = E_INVALID_VALUE;
114120 + /* Since the LLD has no errno-style error reporting,
114121 + we're left here with no other option than to report
114122 + a generic E_INVALID_VALUE */
114123 + break;
114124 + }
114125 +
114126 +#if defined(CONFIG_COMPAT)
114127 + if (compat)
114128 + {
114129 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
114130 +
114131 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
114132 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114133 + if (!compat_param)
114134 + {
114135 + XX_Free(param);
114136 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114137 + }
114138 +
114139 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114140 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
114141 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
114142 + compat_param,
114143 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
114144 + err = E_READ_FAILED;
114145 +
114146 + XX_Free(compat_param);
114147 + }
114148 + else
114149 +#endif
114150 + {
114151 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
114152 + param,
114153 + sizeof(ioc_fm_pcd_hash_table_params_t)))
114154 + err = E_READ_FAILED;
114155 + }
114156 +
114157 + XX_Free(param);
114158 + break;
114159 + }
114160 +
114161 +#if defined(CONFIG_COMPAT)
114162 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
114163 +#endif
114164 + case FM_PCD_IOC_HASH_TABLE_DELETE:
114165 + {
114166 + ioc_fm_obj_t id;
114167 +
114168 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114169 +
114170 +#if defined(CONFIG_COMPAT)
114171 + if (compat)
114172 + {
114173 + ioc_compat_fm_obj_t compat_id;
114174 +
114175 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114176 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114177 +
114178 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114179 + }
114180 + else
114181 +#endif
114182 + {
114183 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114184 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114185 + }
114186 +
114187 + err = FM_PCD_HashTableDelete(id.obj);
114188 + break;
114189 + }
114190 +
114191 +#if defined(CONFIG_COMPAT)
114192 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
114193 +#endif
114194 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
114195 + {
114196 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
114197 +
114198 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114199 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114200 + if (!param)
114201 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114202 +
114203 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114204 +
114205 +#if defined(CONFIG_COMPAT)
114206 + if (compat)
114207 + {
114208 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
114209 +
114210 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114211 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114212 + if (!compat_param)
114213 + {
114214 + XX_Free(param);
114215 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114216 + }
114217 +
114218 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114219 + if (copy_from_user(compat_param,
114220 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
114221 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
114222 + {
114223 + XX_Free(compat_param);
114224 + XX_Free(param);
114225 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114226 + }
114227 +
114228 + if (compat_param->key_size)
114229 + {
114230 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114231 + param->key_size = compat_param->key_size;
114232 +
114233 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
114234 + }
114235 + else
114236 + {
114237 + XX_Free(compat_param);
114238 + XX_Free(param);
114239 + err = E_INVALID_VALUE;
114240 + break;
114241 + }
114242 +
114243 + XX_Free(compat_param);
114244 + }
114245 + else
114246 +#endif
114247 + {
114248 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
114249 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
114250 + {
114251 + XX_Free(param);
114252 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114253 + }
114254 + }
114255 +
114256 + if (param->key_size)
114257 + {
114258 + int size = 0;
114259 +
114260 + if (param->key_params.p_key) size += param->key_size;
114261 + if (param->key_params.p_mask) size += param->key_size;
114262 +
114263 + if (size)
114264 + {
114265 + uint8_t *p_tmp;
114266 +
114267 + p_tmp = (uint8_t*) XX_Malloc(size);
114268 + if (!p_tmp)
114269 + {
114270 + XX_Free(param);
114271 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114272 + }
114273 +
114274 + if (param->key_params.p_key)
114275 + {
114276 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
114277 + {
114278 + XX_Free(p_tmp);
114279 + XX_Free(param);
114280 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114281 + }
114282 +
114283 + param->key_params.p_key = p_tmp;
114284 + }
114285 +
114286 + if (param->key_params.p_mask)
114287 + {
114288 + p_tmp += param->key_size;
114289 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
114290 + {
114291 + XX_Free(p_tmp - param->key_size);
114292 + XX_Free(param);
114293 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114294 + }
114295 +
114296 + param->key_params.p_mask = p_tmp;
114297 + }
114298 + }
114299 + }
114300 +
114301 + err = FM_PCD_HashTableAddKey(
114302 + param->p_hash_tbl,
114303 + param->key_size,
114304 + (t_FmPcdCcKeyParams*)&param->key_params);
114305 +
114306 + if (param->key_params.p_key)
114307 + XX_Free(param->key_params.p_key);
114308 + XX_Free(param);
114309 + break;
114310 + }
114311 +
114312 +#if defined(CONFIG_COMPAT)
114313 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
114314 +#endif
114315 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
114316 + {
114317 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
114318 +
114319 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114320 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114321 + if (!param)
114322 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114323 +
114324 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114325 +
114326 +#if defined(CONFIG_COMPAT)
114327 + if (compat)
114328 + {
114329 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
114330 +
114331 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114332 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114333 + if (!compat_param)
114334 + {
114335 + XX_Free(param);
114336 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114337 + }
114338 +
114339 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114340 + if (copy_from_user(compat_param,
114341 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
114342 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
114343 + {
114344 + XX_Free(compat_param);
114345 + XX_Free(param);
114346 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114347 + }
114348 +
114349 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114350 + param->key_size = compat_param->key_size;
114351 +
114352 + XX_Free(compat_param);
114353 + }
114354 + else
114355 +#endif
114356 + {
114357 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
114358 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
114359 + {
114360 + XX_Free(param);
114361 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114362 + }
114363 + }
114364 +
114365 + if (param->key_size)
114366 + {
114367 + uint8_t *p_key;
114368 +
114369 + p_key = (uint8_t*) XX_Malloc(param->key_size);
114370 + if (!p_key)
114371 + {
114372 + XX_Free(param);
114373 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114374 + }
114375 +
114376 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
114377 + {
114378 + XX_Free(p_key);
114379 + XX_Free(param);
114380 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114381 + }
114382 + param->p_key = p_key;
114383 + }
114384 +
114385 + err = FM_PCD_HashTableRemoveKey(
114386 + param->p_hash_tbl,
114387 + param->key_size,
114388 + param->p_key);
114389 +
114390 + if (param->p_key)
114391 + XX_Free(param->p_key);
114392 + XX_Free(param);
114393 + break;
114394 + }
114395 +
114396 +#if defined(CONFIG_COMPAT)
114397 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
114398 +#endif
114399 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
114400 + {
114401 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
114402 +
114403 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114404 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114405 + if (!param)
114406 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114407 +
114408 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114409 +
114410 +#if defined(CONFIG_COMPAT)
114411 + if (compat)
114412 + {
114413 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
114414 +
114415 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114416 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114417 + if (!compat_param)
114418 + {
114419 + XX_Free(param);
114420 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114421 + }
114422 +
114423 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114424 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
114425 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
114426 + {
114427 + XX_Free(compat_param);
114428 + XX_Free(param);
114429 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114430 + }
114431 +
114432 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
114433 +
114434 + XX_Free(compat_param);
114435 + }
114436 + else
114437 +#endif
114438 + {
114439 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
114440 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
114441 + {
114442 + XX_Free(param);
114443 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114444 + }
114445 + }
114446 +
114447 + if (param->key_size)
114448 + {
114449 + int size = 0;
114450 +
114451 + if (param->p_key) size += param->key_size;
114452 + if (param->p_mask) size += param->key_size;
114453 +
114454 + if (size)
114455 + {
114456 + uint8_t *p_tmp;
114457 +
114458 + p_tmp = (uint8_t*) XX_Malloc(size);
114459 + if (!p_tmp)
114460 + {
114461 + XX_Free(param);
114462 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114463 + }
114464 +
114465 + if (param->p_key)
114466 + {
114467 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
114468 + {
114469 + XX_Free(p_tmp);
114470 + XX_Free(param);
114471 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114472 + }
114473 +
114474 + param->p_key = p_tmp;
114475 + }
114476 +
114477 + if (param->p_mask)
114478 + {
114479 + p_tmp += param->key_size;
114480 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
114481 + {
114482 + XX_Free(p_tmp - param->key_size);
114483 + XX_Free(param);
114484 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114485 + }
114486 +
114487 + param->p_mask = p_tmp;
114488 + }
114489 + }
114490 + }
114491 +
114492 + err = FM_PCD_MatchTableModifyKey(param->id,
114493 + param->key_indx,
114494 + param->key_size,
114495 + param->p_key,
114496 + param->p_mask);
114497 +
114498 + if (param->p_key)
114499 + XX_Free(param->p_key);
114500 + else if (param->p_mask)
114501 + XX_Free(param->p_mask);
114502 + XX_Free(param);
114503 + break;
114504 + }
114505 +
114506 +#if defined(CONFIG_COMPAT)
114507 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
114508 +#endif
114509 + case FM_PCD_IOC_MANIP_NODE_SET:
114510 + {
114511 + ioc_fm_pcd_manip_params_t *param;
114512 + uint8_t *p_data = NULL;
114513 + uint8_t size;
114514 +
114515 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
114516 + sizeof(ioc_fm_pcd_manip_params_t));
114517 +
114518 + if (!param)
114519 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114520 +
114521 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
114522 +
114523 +#if defined(CONFIG_COMPAT)
114524 + if (compat)
114525 + {
114526 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114527 +
114528 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114529 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114530 + if (!compat_param)
114531 + {
114532 + XX_Free(param);
114533 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114534 + }
114535 +
114536 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114537 + if (copy_from_user(compat_param,
114538 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114539 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114540 + {
114541 + XX_Free(compat_param);
114542 + XX_Free(param);
114543 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114544 + }
114545 +
114546 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
114547 +
114548 + XX_Free(compat_param);
114549 + }
114550 + else
114551 +#endif
114552 + {
114553 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
114554 + sizeof(ioc_fm_pcd_manip_params_t)))
114555 + {
114556 + XX_Free(param);
114557 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114558 + }
114559 + }
114560 +
114561 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
114562 + {
114563 + size = param->u.hdr.insrt_params.u.generic.size;
114564 + p_data = (uint8_t *) XX_Malloc(size);
114565 + if (!p_data )
114566 + {
114567 + XX_Free(param);
114568 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
114569 + }
114570 +
114571 + if (param->u.hdr.insrt_params.u.generic.p_data &&
114572 + copy_from_user(p_data,
114573 + param->u.hdr.insrt_params.u.generic.p_data, size))
114574 + {
114575 + XX_Free(p_data);
114576 + XX_Free(param);
114577 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114578 + }
114579 +
114580 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
114581 + }
114582 +
114583 + if (param->id)
114584 + {
114585 + /* Security Hole: the user can pass any piece of garbage
114586 + in 'param->id', and that will go straight through to the LLD,
114587 + no checks being done by the wrapper! */
114588 + err = FM_PCD_ManipNodeReplace(
114589 + (t_Handle) param->id,
114590 + (t_FmPcdManipParams*) param);
114591 + if (err)
114592 + {
114593 + if (p_data)
114594 + XX_Free(p_data);
114595 + XX_Free(param);
114596 + break;
114597 + }
114598 + }
114599 + else
114600 + {
114601 + param->id = FM_PCD_ManipNodeSet(
114602 + p_LnxWrpFmDev->h_PcdDev,
114603 + (t_FmPcdManipParams*) param);
114604 + if (!param->id)
114605 + {
114606 + if (p_data)
114607 + XX_Free(p_data);
114608 + XX_Free(param);
114609 + err = E_INVALID_VALUE;
114610 + /* Since the LLD has no errno-style error reporting,
114611 + we're left here with no other option than to report
114612 + a generic E_INVALID_VALUE */
114613 + break;
114614 + }
114615 + }
114616 +
114617 +#if defined(CONFIG_COMPAT)
114618 + if (compat)
114619 + {
114620 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114621 +
114622 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114623 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114624 + if (!compat_param)
114625 + {
114626 + if (p_data)
114627 + XX_Free(p_data);
114628 + XX_Free(param);
114629 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114630 + }
114631 +
114632 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114633 +
114634 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114635 +
114636 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114637 + compat_param,
114638 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114639 + err = E_READ_FAILED;
114640 +
114641 + XX_Free(compat_param);
114642 + }
114643 + else
114644 +#endif
114645 + {
114646 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114647 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114648 + err = E_READ_FAILED;
114649 + }
114650 +
114651 + if (p_data)
114652 + XX_Free(p_data);
114653 + XX_Free(param);
114654 + break;
114655 + }
114656 +
114657 +#if defined(CONFIG_COMPAT)
114658 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114659 +#endif
114660 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114661 + {
114662 + ioc_fm_obj_t id;
114663 +
114664 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114665 +#if defined(CONFIG_COMPAT)
114666 + if (compat)
114667 + {
114668 + ioc_compat_fm_obj_t compat_id;
114669 +
114670 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114671 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114672 +
114673 + compat_obj_delete(&compat_id, &id);
114674 + }
114675 + else
114676 +#endif
114677 + {
114678 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114679 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114680 + }
114681 +
114682 + err = FM_PCD_ManipNodeDelete(id.obj);
114683 + break;
114684 + }
114685 +
114686 +#if defined(CONFIG_COMPAT)
114687 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114688 +#endif
114689 + case FM_PCD_IOC_MANIP_GET_STATS:
114690 + {
114691 + ioc_fm_pcd_manip_get_stats_t param;
114692 +
114693 +#if defined(CONFIG_COMPAT)
114694 + if (compat)
114695 + {
114696 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114697 +
114698 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114699 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114700 + if (!compat_param)
114701 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114702 +
114703 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114704 + if (copy_from_user(compat_param,
114705 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114706 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114707 + {
114708 + XX_Free(compat_param);
114709 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114710 + }
114711 +
114712 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114713 +
114714 + XX_Free(compat_param);
114715 + }
114716 + else
114717 +#endif
114718 + {
114719 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114720 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114721 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114722 + }
114723 +
114724 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114725 + (t_FmPcdManipStats*) &param.stats);
114726 +
114727 +#if defined(CONFIG_COMPAT)
114728 + if (compat)
114729 + {
114730 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114731 +
114732 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114733 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114734 + if (!compat_param)
114735 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114736 +
114737 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114738 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114739 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114740 + compat_param,
114741 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114742 + XX_Free(compat_param);
114743 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114744 + }
114745 + XX_Free(compat_param);
114746 + }
114747 + else
114748 +#endif
114749 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114750 + &param,
114751 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114752 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114753 +
114754 + break;
114755 + }
114756 +
114757 +#if (DPAA_VERSION >= 11)
114758 +#if defined(CONFIG_COMPAT)
114759 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114760 +#endif
114761 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114762 + {
114763 + ioc_fm_pcd_frm_replic_group_params_t *param;
114764 +
114765 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114766 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114767 + if (!param)
114768 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114769 +
114770 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114771 +
114772 +#if defined(CONFIG_COMPAT)
114773 + if (compat)
114774 + {
114775 + ioc_compat_fm_pcd_frm_replic_group_params_t
114776 + *compat_param;
114777 +
114778 + compat_param =
114779 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114780 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114781 + if (!compat_param)
114782 + {
114783 + XX_Free(param);
114784 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114785 + ("IOCTL FM PCD"));
114786 + }
114787 +
114788 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114789 + if (copy_from_user(compat_param,
114790 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114791 + compat_ptr(arg),
114792 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114793 + XX_Free(compat_param);
114794 + XX_Free(param);
114795 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114796 + }
114797 +
114798 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114799 + param, COMPAT_US_TO_K);
114800 +
114801 + XX_Free(compat_param);
114802 + }
114803 + else
114804 +#endif
114805 + {
114806 + if (copy_from_user(param,
114807 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114808 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114809 + {
114810 + XX_Free(param);
114811 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114812 + }
114813 + }
114814 +
114815 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114816 + (t_FmPcdFrmReplicGroupParams*)param);
114817 +
114818 + if (!param->id) {
114819 + XX_Free(param);
114820 + err = E_INVALID_VALUE;
114821 + /*
114822 + * Since the LLD has no errno-style error reporting,
114823 + * we're left here with no other option than to report
114824 + * a generic E_INVALID_VALUE
114825 + */
114826 + break;
114827 + }
114828 +
114829 +#if defined(CONFIG_COMPAT)
114830 + if (compat)
114831 + {
114832 + ioc_compat_fm_pcd_frm_replic_group_params_t
114833 + *compat_param;
114834 +
114835 + compat_param =
114836 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114837 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114838 + if (!compat_param)
114839 + {
114840 + XX_Free(param);
114841 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114842 + ("IOCTL FM PCD"));
114843 + }
114844 +
114845 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114846 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114847 + param, COMPAT_K_TO_US);
114848 + if (copy_to_user(
114849 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114850 + compat_ptr(arg),
114851 + compat_param,
114852 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
114853 + err = E_WRITE_FAILED;
114854 +
114855 + XX_Free(compat_param);
114856 + }
114857 + else
114858 +#endif
114859 + {
114860 + if (copy_to_user(
114861 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114862 + param,
114863 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114864 + err = E_WRITE_FAILED;
114865 + }
114866 +
114867 + XX_Free(param);
114868 + break;
114869 + }
114870 + break;
114871 +
114872 +#if defined(CONFIG_COMPAT)
114873 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
114874 +#endif
114875 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
114876 + {
114877 + ioc_fm_obj_t id;
114878 +
114879 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114880 +#if defined(CONFIG_COMPAT)
114881 + if (compat)
114882 + {
114883 + ioc_compat_fm_obj_t compat_id;
114884 +
114885 + if (copy_from_user(&compat_id,
114886 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114887 + sizeof(ioc_compat_fm_obj_t)))
114888 + break;
114889 + compat_obj_delete(&compat_id, &id);
114890 + }
114891 + else
114892 +#endif
114893 + {
114894 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114895 + sizeof(ioc_fm_obj_t)))
114896 + break;
114897 + }
114898 +
114899 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
114900 + }
114901 + break;
114902 +
114903 +#if defined(CONFIG_COMPAT)
114904 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
114905 +#endif
114906 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
114907 + {
114908 + ioc_fm_pcd_frm_replic_member_params_t param;
114909 +
114910 +#if defined(CONFIG_COMPAT)
114911 + if (compat)
114912 + {
114913 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
114914 +
114915 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114916 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114917 +
114918 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
114919 + }
114920 + else
114921 +#endif
114922 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114923 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114924 +
114925 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
114926 + param.member.member_index,
114927 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
114928 + }
114929 + break;
114930 +
114931 +#if defined(CONFIG_COMPAT)
114932 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
114933 +#endif
114934 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
114935 + {
114936 + ioc_fm_pcd_frm_replic_member_t param;
114937 +
114938 +#if defined(CONFIG_COMPAT)
114939 + if (compat)
114940 + {
114941 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
114942 +
114943 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114944 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114945 +
114946 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
114947 + }
114948 + else
114949 +#endif
114950 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114951 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114952 +
114953 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
114954 + }
114955 + break;
114956 +
114957 +#if defined(CONFIG_COMPAT)
114958 + case FM_IOC_VSP_CONFIG_COMPAT:
114959 +#endif
114960 + case FM_IOC_VSP_CONFIG:
114961 + {
114962 + ioc_fm_vsp_params_t param;
114963 +
114964 +#if defined(CONFIG_COMPAT)
114965 + if (compat)
114966 + {
114967 + ioc_compat_fm_vsp_params_t compat_param;
114968 +
114969 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114970 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114971 +
114972 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
114973 + }
114974 + else
114975 +#endif
114976 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114977 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114978 + {
114979 + uint8_t portId = param.port_params.port_id;
114980 + param.liodn_offset =
114981 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
114982 + }
114983 + param.p_fm = p_LnxWrpFmDev->h_Dev;
114984 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
114985 +
114986 +#if defined(CONFIG_COMPAT)
114987 + if (compat)
114988 + {
114989 + ioc_compat_fm_vsp_params_t compat_param;
114990 +
114991 + memset(&compat_param, 0, sizeof(compat_param));
114992 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
114993 +
114994 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114995 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114996 + }
114997 + else
114998 +#endif
114999 + if (copy_to_user((void *)arg, &param, sizeof(param)))
115000 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115001 + break;
115002 + }
115003 +
115004 +#if defined(CONFIG_COMPAT)
115005 + case FM_IOC_VSP_INIT_COMPAT:
115006 +#endif
115007 + case FM_IOC_VSP_INIT:
115008 + {
115009 + ioc_fm_obj_t id;
115010 +
115011 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115012 +#if defined(CONFIG_COMPAT)
115013 + if (compat)
115014 + {
115015 + ioc_compat_fm_obj_t compat_id;
115016 +
115017 + if (copy_from_user(&compat_id,
115018 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
115019 + sizeof(ioc_compat_fm_obj_t)))
115020 + break;
115021 + id.obj = compat_pcd_id2ptr(compat_id.obj);
115022 + }
115023 + else
115024 +#endif
115025 + {
115026 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
115027 + sizeof(ioc_fm_obj_t)))
115028 + break;
115029 + }
115030 +
115031 + return FM_VSP_Init(id.obj);
115032 + }
115033 +
115034 +#if defined(CONFIG_COMPAT)
115035 + case FM_IOC_VSP_FREE_COMPAT:
115036 +#endif
115037 + case FM_IOC_VSP_FREE:
115038 + {
115039 + ioc_fm_obj_t id;
115040 +
115041 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115042 +#if defined(CONFIG_COMPAT)
115043 + if (compat)
115044 + {
115045 + ioc_compat_fm_obj_t compat_id;
115046 +
115047 + if (copy_from_user(&compat_id,
115048 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
115049 + sizeof(ioc_compat_fm_obj_t)))
115050 + break;
115051 + compat_obj_delete(&compat_id, &id);
115052 + }
115053 + else
115054 +#endif
115055 + {
115056 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
115057 + sizeof(ioc_fm_obj_t)))
115058 + break;
115059 + }
115060 +
115061 + return FM_VSP_Free(id.obj);
115062 + }
115063 +
115064 +#if defined(CONFIG_COMPAT)
115065 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
115066 +#endif
115067 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
115068 + {
115069 + ioc_fm_buf_pool_depletion_params_t param;
115070 +
115071 +#if defined(CONFIG_COMPAT)
115072 + if (compat)
115073 + {
115074 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
115075 +
115076 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115077 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115078 +
115079 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
115080 + }
115081 + else
115082 +#endif
115083 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115084 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115085 +
115086 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
115087 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
115088 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115089 +
115090 + break;
115091 + }
115092 +
115093 +
115094 +#if defined(CONFIG_COMPAT)
115095 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
115096 +#endif
115097 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
115098 + {
115099 + ioc_fm_buffer_prefix_content_params_t param;
115100 +
115101 +#if defined(CONFIG_COMPAT)
115102 + if (compat)
115103 + {
115104 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
115105 +
115106 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115107 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115108 +
115109 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
115110 + }
115111 + else
115112 +#endif
115113 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115114 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115115 +
115116 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
115117 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
115118 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115119 +
115120 + break;
115121 + }
115122 +
115123 +#if defined(CONFIG_COMPAT)
115124 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
115125 +#endif
115126 + case FM_IOC_VSP_CONFIG_NO_SG:
115127 + {
115128 + ioc_fm_vsp_config_no_sg_params_t param;
115129 +
115130 +#if defined(CONFIG_COMPAT)
115131 + if (compat)
115132 + {
115133 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
115134 +
115135 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115136 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115137 +
115138 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
115139 + }
115140 + else
115141 +#endif
115142 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115143 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115144 +
115145 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
115146 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115147 +
115148 + break;
115149 + }
115150 +
115151 +#if defined(CONFIG_COMPAT)
115152 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
115153 +#endif
115154 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
115155 + {
115156 + ioc_fm_vsp_prs_result_params_t param;
115157 +
115158 +#if defined(CONFIG_COMPAT)
115159 + if (compat)
115160 + {
115161 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
115162 +
115163 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115164 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115165 +
115166 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
115167 + }
115168 + else
115169 +#endif
115170 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115171 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115172 +
115173 + /* this call just adds the parse results offset to p_data */
115174 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
115175 +
115176 + if (!param.p_data)
115177 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115178 +
115179 +#if defined(CONFIG_COMPAT)
115180 + if (compat)
115181 + {
115182 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
115183 +
115184 + memset(&compat_param, 0, sizeof(compat_param));
115185 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
115186 +
115187 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
115188 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115189 + }
115190 + else
115191 +#endif
115192 + if (copy_to_user((void *)arg, &param, sizeof(param)))
115193 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115194 +
115195 + break;
115196 + }
115197 +#endif /* (DPAA_VERSION >= 11) */
115198 +
115199 +#ifdef FM_CAPWAP_SUPPORT
115200 +#warning "feature not supported!"
115201 +#if defined(CONFIG_COMPAT)
115202 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
115203 +#endif
115204 + case FM_PCD_IOC_STATISTICS_SET_NODE:
115205 + {
115206 +/* ioc_fm_pcd_stats_params_t param;
115207 + ...
115208 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
115209 + (t_FmPcdStatsParams *)&param);
115210 +*/
115211 + err = E_NOT_SUPPORTED;
115212 + break;
115213 + }
115214 +#endif /* FM_CAPWAP_SUPPORT */
115215 +
115216 + default:
115217 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
115218 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
115219 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
115220 + }
115221 +
115222 + if (err)
115223 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
115224 +
115225 + return E_OK;
115226 +}
115227 +
115228 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
115229 +{
115230 + p_version->version.major = FMD_API_VERSION_MAJOR;
115231 + p_version->version.minor = FMD_API_VERSION_MINOR;
115232 + p_version->version.respin = FMD_API_VERSION_RESPIN;
115233 + p_version->version.reserved = 0;
115234 +}
115235 +
115236 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
115237 +{
115238 + t_Error err = E_OK;
115239 +
115240 + switch (cmd)
115241 + {
115242 + case FM_IOC_SET_PORTS_BANDWIDTH:
115243 + {
115244 + ioc_fm_port_bandwidth_params *param;
115245 +
115246 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
115247 + if (!param)
115248 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115249 +
115250 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
115251 +
115252 +#if defined(CONFIG_COMPAT)
115253 + if (compat)
115254 + {
115255 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
115256 + {
115257 + XX_Free(param);
115258 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115259 + }
115260 + }
115261 + else
115262 +#endif
115263 + {
115264 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
115265 + {
115266 + XX_Free(param);
115267 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115268 + }
115269 + }
115270 +
115271 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
115272 +
115273 + XX_Free(param);
115274 + break;
115275 + }
115276 +
115277 + case FM_IOC_GET_REVISION:
115278 + {
115279 + ioc_fm_revision_info_t *param;
115280 +
115281 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
115282 + if (!param)
115283 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115284 +
115285 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
115286 + /* This one never returns anything other than E_OK */
115287 +
115288 +#if defined(CONFIG_COMPAT)
115289 + if (compat)
115290 + {
115291 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
115292 + param,
115293 + sizeof(ioc_fm_revision_info_t))){
115294 + XX_Free(param);
115295 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115296 + }
115297 + }
115298 + else
115299 +#endif
115300 + {
115301 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
115302 + param,
115303 + sizeof(ioc_fm_revision_info_t))){
115304 + XX_Free(param);
115305 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115306 + }
115307 + }
115308 + XX_Free(param);
115309 + break;
115310 + }
115311 +
115312 + case FM_IOC_SET_COUNTER:
115313 + {
115314 + ioc_fm_counters_params_t *param;
115315 +
115316 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115317 + if (!param)
115318 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115319 +
115320 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115321 +
115322 +#if defined(CONFIG_COMPAT)
115323 + if (compat)
115324 + {
115325 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115326 + {
115327 + XX_Free(param);
115328 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115329 + }
115330 + }
115331 + else
115332 +#endif
115333 + {
115334 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115335 + {
115336 + XX_Free(param);
115337 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115338 + }
115339 + }
115340 +
115341 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
115342 +
115343 + XX_Free(param);
115344 + break;
115345 + }
115346 +
115347 + case FM_IOC_GET_COUNTER:
115348 + {
115349 + ioc_fm_counters_params_t *param;
115350 +
115351 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115352 + if (!param)
115353 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115354 +
115355 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115356 +
115357 +#if defined(CONFIG_COMPAT)
115358 + if (compat)
115359 + {
115360 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115361 + {
115362 + XX_Free(param);
115363 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115364 + }
115365 + }
115366 + else
115367 +#endif
115368 + {
115369 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115370 + {
115371 + XX_Free(param);
115372 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115373 + }
115374 + }
115375 +
115376 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
115377 +
115378 +#if defined(CONFIG_COMPAT)
115379 + if (compat)
115380 + {
115381 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
115382 + err = E_READ_FAILED;
115383 + }
115384 + else
115385 +#endif
115386 + {
115387 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
115388 + err = E_READ_FAILED;
115389 + }
115390 +
115391 + XX_Free(param);
115392 + break;
115393 + }
115394 +
115395 + case FM_IOC_FORCE_INTR:
115396 + {
115397 + ioc_fm_exceptions param;
115398 +
115399 +#if defined(CONFIG_COMPAT)
115400 + if (compat)
115401 + {
115402 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
115403 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115404 + }
115405 + else
115406 +#endif
115407 + {
115408 + if (get_user(param, (ioc_fm_exceptions*)arg))
115409 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115410 + }
115411 +
115412 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
115413 + break;
115414 + }
115415 +
115416 + case FM_IOC_GET_API_VERSION:
115417 + {
115418 + ioc_fm_api_version_t version;
115419 +
115420 + FM_Get_Api_Version(&version);
115421 +
115422 +#if defined(CONFIG_COMPAT)
115423 + if (compat)
115424 + {
115425 + if (copy_to_user(
115426 + (ioc_fm_api_version_t *)compat_ptr(arg),
115427 + &version, sizeof(version)))
115428 + err = E_READ_FAILED;
115429 + }
115430 + else
115431 +#endif
115432 + {
115433 + if (copy_to_user((ioc_fm_api_version_t *)arg,
115434 + &version, sizeof(version)))
115435 + err = E_READ_FAILED;
115436 + }
115437 + }
115438 + break;
115439 +
115440 + case FM_IOC_CTRL_MON_START:
115441 + {
115442 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
115443 + }
115444 + break;
115445 +
115446 + case FM_IOC_CTRL_MON_STOP:
115447 + {
115448 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
115449 + }
115450 + break;
115451 +
115452 +#if defined(CONFIG_COMPAT)
115453 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
115454 +#endif
115455 + case FM_IOC_CTRL_MON_GET_COUNTERS:
115456 + {
115457 + ioc_fm_ctrl_mon_counters_params_t param;
115458 + t_FmCtrlMon mon;
115459 +
115460 +#if defined(CONFIG_COMPAT)
115461 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
115462 +
115463 + if (compat)
115464 + {
115465 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
115466 + sizeof(compat_param)))
115467 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115468 +
115469 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
115470 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
115471 + }
115472 + else
115473 +#endif
115474 + {
115475 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
115476 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115477 + }
115478 +
115479 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
115480 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115481 +
115482 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
115483 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115484 + }
115485 + break;
115486 +
115487 + default:
115488 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
115489 + }
115490 +
115491 + if (err)
115492 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
115493 +
115494 + return E_OK;
115495 +}
115496 +
115497 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
115498 +{
115499 + t_Error err = E_OK;
115500 +
115501 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
115502 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
115503 +
115504 + switch (cmd)
115505 + {
115506 + case FM_PORT_IOC_DISABLE:
115507 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
115508 + /* deliberately ignoring error codes here */
115509 + return E_OK;
115510 +
115511 + case FM_PORT_IOC_ENABLE:
115512 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
115513 + /* deliberately ignoring error codes here */
115514 + return E_OK;
115515 +
115516 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
115517 + {
115518 + ioc_fm_port_frame_err_select_t errs;
115519 +
115520 +#if defined(CONFIG_COMPAT)
115521 + if (compat)
115522 + {
115523 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
115524 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115525 + }
115526 + else
115527 +#endif
115528 + {
115529 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
115530 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115531 + }
115532 +
115533 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
115534 + break;
115535 + }
115536 +
115537 + case FM_PORT_IOC_SET_RATE_LIMIT:
115538 + {
115539 + ioc_fm_port_rate_limit_t *param;
115540 +
115541 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
115542 + if (!param)
115543 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115544 +
115545 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
115546 +
115547 +#if defined(CONFIG_COMPAT)
115548 + if (compat)
115549 + {
115550 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
115551 + {
115552 + XX_Free(param);
115553 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115554 + }
115555 + }
115556 + else
115557 +#endif
115558 + {
115559 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
115560 + {
115561 + XX_Free(param);
115562 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115563 + }
115564 + }
115565 +
115566 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
115567 +
115568 + XX_Free(param);
115569 + break;
115570 + }
115571 +
115572 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
115573 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
115574 + /* deliberately ignoring error codes here */
115575 + return E_OK;
115576 +
115577 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
115578 + {
115579 + ioc_fm_port_pcd_fqids_params_t *param;
115580 +
115581 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
115582 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115583 +
115584 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
115585 + if (!param)
115586 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115587 +
115588 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115589 +
115590 +#if defined(CONFIG_COMPAT)
115591 + if (compat)
115592 + {
115593 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115594 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115595 + {
115596 + XX_Free(param);
115597 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115598 + }
115599 + }
115600 + else
115601 +#endif
115602 + {
115603 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115604 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115605 + {
115606 + XX_Free(param);
115607 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115608 + }
115609 + }
115610 +
115611 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115612 + param->num_fqids,
115613 + param->alignment,
115614 + &param->base_fqid))
115615 + {
115616 + XX_Free(param);
115617 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115618 + }
115619 +
115620 +#if defined(CONFIG_COMPAT)
115621 + if (compat)
115622 + {
115623 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115624 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115625 + err = E_READ_FAILED;
115626 + }
115627 + else
115628 +#endif
115629 + {
115630 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115631 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115632 + err = E_READ_FAILED;
115633 + }
115634 +
115635 + XX_Free(param);
115636 + break;
115637 + }
115638 +
115639 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115640 + {
115641 + uint32_t base_fqid;
115642 +
115643 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115644 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115645 +
115646 +#if defined(CONFIG_COMPAT)
115647 + if (compat)
115648 + {
115649 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115650 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115651 + }
115652 + else
115653 +#endif
115654 + {
115655 + if (get_user(base_fqid, (uint32_t*)arg))
115656 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115657 + }
115658 +
115659 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115660 + err = E_WRITE_FAILED;
115661 +
115662 + break;
115663 + }
115664 +
115665 +#if defined(CONFIG_COMPAT)
115666 + case FM_PORT_IOC_SET_PCD_COMPAT:
115667 +#endif
115668 + case FM_PORT_IOC_SET_PCD:
115669 + {
115670 + ioc_fm_port_pcd_params_t *port_pcd_params;
115671 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115672 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115673 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115674 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115675 +
115676 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115677 + sizeof(ioc_fm_port_pcd_params_t) +
115678 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115679 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115680 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115681 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115682 + if (!port_pcd_params)
115683 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115684 +
115685 + memset(port_pcd_params, 0,
115686 + sizeof(ioc_fm_port_pcd_params_t) +
115687 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115688 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115689 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115690 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115691 +
115692 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115693 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115694 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115695 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115696 +
115697 +#if defined(CONFIG_COMPAT)
115698 + if (compat)
115699 + {
115700 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115701 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115702 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115703 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115704 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115705 +
115706 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115707 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115708 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115709 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115710 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115711 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115712 + if (!compat_port_pcd_params)
115713 + {
115714 + XX_Free(port_pcd_params);
115715 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115716 + }
115717 +
115718 + memset(compat_port_pcd_params, 0,
115719 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115720 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115721 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115722 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115723 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115724 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115725 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115726 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115727 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115728 +
115729 + if (copy_from_user(compat_port_pcd_params,
115730 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115731 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115732 + err = E_WRITE_FAILED;
115733 +
115734 + while (!err) /* pseudo-while */
115735 + {
115736 + /* set pointers from where to copy from: */
115737 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115738 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115739 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115740 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115741 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115742 +#if (DPAA_VERSION >= 11)
115743 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115744 +#endif
115745 + /* the prs member is the same, no compat structure...memcpy only */
115746 + if (port_pcd_params->p_prs_params)
115747 + {
115748 + if (copy_from_user(same_port_pcd_prs_params,
115749 + port_pcd_params->p_prs_params,
115750 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115751 + {
115752 + err = E_WRITE_FAILED;
115753 + break; /* from pseudo-while */
115754 + }
115755 +
115756 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115757 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115758 + }
115759 +
115760 + if (port_pcd_params->p_cc_params)
115761 + {
115762 + if (copy_from_user(compat_port_pcd_cc_params,
115763 + port_pcd_params->p_cc_params,
115764 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115765 + {
115766 + err = E_WRITE_FAILED;
115767 + break; /* from pseudo-while */
115768 + }
115769 +
115770 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115771 + }
115772 +
115773 + if (port_pcd_params->p_kg_params)
115774 + {
115775 + if (copy_from_user(compat_port_pcd_kg_params,
115776 + port_pcd_params->p_kg_params,
115777 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115778 + {
115779 + err = E_WRITE_FAILED;
115780 + break; /* from pseudo-while */
115781 + }
115782 +
115783 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115784 + }
115785 +
115786 + if (port_pcd_params->p_plcr_params)
115787 + {
115788 + if (copy_from_user(compat_port_pcd_plcr_params,
115789 + port_pcd_params->p_plcr_params,
115790 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115791 + {
115792 + err = E_WRITE_FAILED;
115793 + break; /* from pseudo-while */
115794 + }
115795 +
115796 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115797 + }
115798 +
115799 + break; /* pseudo-while: always run once! */
115800 + }
115801 +
115802 + if (!err)
115803 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115804 +
115805 + XX_Free(compat_port_pcd_params);
115806 + }
115807 + else
115808 +#endif
115809 + {
115810 + if (copy_from_user(port_pcd_params,
115811 + (ioc_fm_port_pcd_params_t*) arg,
115812 + sizeof(ioc_fm_port_pcd_params_t)))
115813 + err = E_WRITE_FAILED;
115814 +
115815 + while (!err) /* pseudo-while */
115816 + {
115817 + if (port_pcd_params->p_prs_params)
115818 + {
115819 + if (copy_from_user(port_pcd_prs_params,
115820 + port_pcd_params->p_prs_params,
115821 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115822 + {
115823 + err = E_WRITE_FAILED;
115824 + break; /* from pseudo-while */
115825 + }
115826 +
115827 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115828 + }
115829 +
115830 + if (port_pcd_params->p_cc_params)
115831 + {
115832 + if (copy_from_user(port_pcd_cc_params,
115833 + port_pcd_params->p_cc_params,
115834 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115835 + {
115836 + err = E_WRITE_FAILED;
115837 + break; /* from pseudo-while */
115838 + }
115839 +
115840 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115841 + }
115842 +
115843 + if (port_pcd_params->p_kg_params)
115844 + {
115845 + if (copy_from_user(port_pcd_kg_params,
115846 + port_pcd_params->p_kg_params,
115847 + sizeof(ioc_fm_port_pcd_kg_params_t)))
115848 + {
115849 + err = E_WRITE_FAILED;
115850 + break; /* from pseudo-while */
115851 + }
115852 +
115853 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115854 + }
115855 +
115856 + if (port_pcd_params->p_plcr_params)
115857 + {
115858 + if (copy_from_user(port_pcd_plcr_params,
115859 + port_pcd_params->p_plcr_params,
115860 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
115861 + {
115862 + err = E_WRITE_FAILED;
115863 + break; /* from pseudo-while */
115864 + }
115865 +
115866 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115867 + }
115868 +
115869 + break; /* pseudo-while: always run once! */
115870 + }
115871 + }
115872 +
115873 + if (!err)
115874 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
115875 +
115876 + XX_Free(port_pcd_params);
115877 + break;
115878 + }
115879 +
115880 + case FM_PORT_IOC_DELETE_PCD:
115881 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
115882 + break;
115883 +
115884 +#if defined(CONFIG_COMPAT)
115885 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
115886 +#endif
115887 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
115888 + {
115889 + ioc_fm_pcd_kg_scheme_select_t *param;
115890 +
115891 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115892 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
115893 + if (!param)
115894 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115895 +
115896 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
115897 +
115898 +#if defined(CONFIG_COMPAT)
115899 + if (compat)
115900 + {
115901 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
115902 +
115903 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115904 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115905 + if (!compat_param)
115906 + {
115907 + XX_Free(param);
115908 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115909 + }
115910 +
115911 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115912 + if (copy_from_user(compat_param,
115913 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
115914 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
115915 + {
115916 + XX_Free(compat_param);
115917 + XX_Free(param);
115918 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115919 + }
115920 +
115921 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
115922 +
115923 + XX_Free(compat_param);
115924 + }
115925 + else
115926 +#endif
115927 + {
115928 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
115929 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
115930 + {
115931 + XX_Free(param);
115932 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115933 + }
115934 + }
115935 +
115936 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
115937 +
115938 + XX_Free(param);
115939 + break;
115940 + }
115941 +
115942 +#if defined(CONFIG_COMPAT)
115943 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
115944 +#endif
115945 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
115946 + {
115947 + ioc_fm_obj_t id;
115948 +
115949 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115950 +
115951 +#if defined(CONFIG_COMPAT)
115952 + if (compat)
115953 + {
115954 + ioc_compat_fm_obj_t compat_id;
115955 +
115956 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115957 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115958 +
115959 + id.obj = compat_ptr(compat_id.obj);
115960 + }
115961 + else
115962 +#endif
115963 + {
115964 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115965 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115966 + }
115967 +
115968 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
115969 + break;
115970 + }
115971 +
115972 +#if defined(CONFIG_COMPAT)
115973 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
115974 +#endif
115975 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
115976 + {
115977 + ioc_fm_pcd_port_schemes_params_t *param;
115978 +
115979 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115980 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115981 + if (!param)
115982 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115983 +
115984 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115985 +
115986 +#if defined(CONFIG_COMPAT)
115987 + if (compat)
115988 + {
115989 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115990 +
115991 + if (copy_from_user(&compat_param,
115992 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115993 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115994 + {
115995 + XX_Free(param);
115996 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115997 + }
115998 +
115999 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
116000 + }
116001 + else
116002 +#endif
116003 + {
116004 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
116005 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
116006 + {
116007 + XX_Free(param);
116008 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116009 + }
116010 + }
116011 +
116012 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
116013 +
116014 + XX_Free(param);
116015 + break;
116016 + }
116017 +
116018 +#if defined(CONFIG_COMPAT)
116019 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
116020 +#endif
116021 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
116022 + {
116023 + ioc_fm_pcd_port_schemes_params_t *param;
116024 +
116025 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
116026 + sizeof(ioc_fm_pcd_port_schemes_params_t));
116027 + if (!param)
116028 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116029 +
116030 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
116031 +
116032 +#if defined(CONFIG_COMPAT)
116033 + if (compat)
116034 + {
116035 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
116036 +
116037 + if (copy_from_user(&compat_param,
116038 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
116039 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
116040 + {
116041 + XX_Free(param);
116042 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116043 + }
116044 +
116045 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
116046 + }
116047 + else
116048 +#endif
116049 + {
116050 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
116051 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
116052 + {
116053 + XX_Free(param);
116054 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116055 + }
116056 + }
116057 +
116058 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
116059 +
116060 + XX_Free(param);
116061 + break;
116062 + }
116063 +
116064 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
116065 + {
116066 + uint16_t num;
116067 + if (get_user(num, (uint16_t*) arg))
116068 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116069 +
116070 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
116071 + break;
116072 + }
116073 +
116074 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
116075 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
116076 + break;
116077 +
116078 + case FM_PORT_IOC_DETACH_PCD:
116079 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
116080 + break;
116081 +
116082 + case FM_PORT_IOC_ATTACH_PCD:
116083 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
116084 + break;
116085 +
116086 +#if defined(CONFIG_COMPAT)
116087 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
116088 +#endif
116089 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
116090 + {
116091 + ioc_fm_obj_t id;
116092 +
116093 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
116094 +
116095 +#if defined(CONFIG_COMPAT)
116096 + if (compat)
116097 + {
116098 + ioc_compat_fm_obj_t compat_id;
116099 +
116100 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
116101 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116102 +
116103 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
116104 + }
116105 + else
116106 +#endif
116107 + {
116108 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
116109 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116110 + }
116111 +
116112 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
116113 + break;
116114 + }
116115 +
116116 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
116117 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
116118 + {
116119 + ioc_fm_port_congestion_groups_t *param;
116120 +
116121 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
116122 + if (!param)
116123 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116124 +
116125 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
116126 +
116127 +#if defined(CONFIG_COMPAT)
116128 + if (compat)
116129 + {
116130 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
116131 + sizeof(t_FmPortCongestionGrps)))
116132 + {
116133 + XX_Free(param);
116134 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116135 + }
116136 + }
116137 + else
116138 +#endif /* CONFIG_COMPAT */
116139 + {
116140 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
116141 + sizeof(t_FmPortCongestionGrps)))
116142 + {
116143 + XX_Free(param);
116144 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116145 + }
116146 + }
116147 +
116148 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
116149 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
116150 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
116151 + ;
116152 +
116153 + XX_Free(param);
116154 + break;
116155 + }
116156 +
116157 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
116158 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
116159 + {
116160 + ioc_fm_port_mac_addr_params_t *param;
116161 +
116162 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
116163 + sizeof(ioc_fm_port_mac_addr_params_t));
116164 + if (!param)
116165 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116166 +
116167 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
116168 +
116169 +#if defined(CONFIG_COMPAT)
116170 + if (compat)
116171 + {
116172 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
116173 + sizeof(ioc_fm_port_mac_addr_params_t)))
116174 + {
116175 + XX_Free(param);
116176 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116177 + }
116178 + }
116179 + else
116180 +#endif /* CONFIG_COMPAT */
116181 + {
116182 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
116183 + sizeof(ioc_fm_port_mac_addr_params_t)))
116184 + {
116185 + XX_Free(param);
116186 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116187 + }
116188 + }
116189 +
116190 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
116191 + {
116192 + int id = -1;
116193 +
116194 + switch(p_LnxWrpFmPortDev->settings.param.portType)
116195 + {
116196 + case e_FM_PORT_TYPE_RX:
116197 + case e_FM_PORT_TYPE_TX:
116198 + id = p_LnxWrpFmPortDev->id;
116199 + break;
116200 + case e_FM_PORT_TYPE_RX_10G:
116201 + case e_FM_PORT_TYPE_TX_10G:
116202 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
116203 + break;
116204 + default:
116205 + err = E_NOT_AVAILABLE;
116206 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
116207 + }
116208 + if (id >= 0)
116209 + {
116210 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116211 + t_Handle mac_handle = fm->macs[id].h_Dev;
116212 +
116213 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
116214 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
116215 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
116216 + }
116217 + }
116218 + else
116219 + {
116220 + err = E_NOT_AVAILABLE;
116221 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
116222 + }
116223 +
116224 + XX_Free(param);
116225 + break;
116226 + }
116227 +
116228 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
116229 + {
116230 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116231 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116232 + ioc_fm_port_tx_pause_frames_params_t param;
116233 + int mac_id = p_LnxWrpFmPortDev->id;
116234 +
116235 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
116236 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116237 +
116238 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
116239 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
116240 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116241 +
116242 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
116243 + {
116244 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116245 + param.priority,
116246 + param.pause_time,
116247 + param.thresh_time);
116248 + }
116249 + else
116250 + {
116251 + err = E_NOT_AVAILABLE;
116252 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
116253 + }
116254 +
116255 + break;
116256 + }
116257 +
116258 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
116259 + {
116260 + ioc_fm_buffer_prefix_content_t *param;
116261 +
116262 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
116263 + if (!param)
116264 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116265 +
116266 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
116267 +
116268 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
116269 + sizeof(ioc_fm_buffer_prefix_content_t)))
116270 + {
116271 + XX_Free(param);
116272 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116273 + }
116274 +
116275 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
116276 + (t_FmBufferPrefixContent *)param))
116277 + {
116278 + XX_Free(param);
116279 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116280 + }
116281 +
116282 + XX_Free(param);
116283 + break;
116284 + }
116285 +
116286 +#if (DPAA_VERSION >= 11)
116287 +#if defined(CONFIG_COMPAT)
116288 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
116289 +#endif
116290 + case FM_PORT_IOC_VSP_ALLOC:
116291 + {
116292 + ioc_fm_port_vsp_alloc_params_t *param;
116293 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116294 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
116295 +
116296 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
116297 + sizeof(ioc_fm_port_vsp_alloc_params_t));
116298 + if (!param)
116299 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116300 +
116301 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
116302 +
116303 +#if defined(CONFIG_COMPAT)
116304 + if (compat)
116305 + {
116306 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
116307 +
116308 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
116309 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116310 + if (!compat_param)
116311 + {
116312 + XX_Free(param);
116313 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116314 + }
116315 +
116316 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116317 + if (copy_from_user(compat_param,
116318 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
116319 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
116320 + {
116321 + XX_Free(compat_param);
116322 + XX_Free(param);
116323 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116324 + }
116325 +
116326 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
116327 +
116328 + XX_Free(compat_param);
116329 + }
116330 + else
116331 +#endif
116332 + {
116333 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
116334 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
116335 + {
116336 + XX_Free(param);
116337 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116338 + }
116339 + }
116340 +
116341 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
116342 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
116343 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
116344 + {
116345 + /* Determine the Tx port t_Handle from the Rx port id */
116346 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116347 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
116348 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
116349 + }
116350 +
116351 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
116352 + {
116353 + XX_Free(param);
116354 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116355 + }
116356 +
116357 + XX_Free(param);
116358 + break;
116359 + }
116360 +#endif /* (DPAA_VERSION >= 11) */
116361 +
116362 + case FM_PORT_IOC_GET_MAC_STATISTICS:
116363 + {
116364 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116365 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116366 + ioc_fm_port_mac_statistics_t param;
116367 + int mac_id = p_LnxWrpFmPortDev->id;
116368 +
116369 + if (!p_LnxWrpFmDev)
116370 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116371 +
116372 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116373 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116374 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116375 +
116376 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116377 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116378 +
116379 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116380 + (t_FmMacStatistics *)&param))
116381 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116382 +
116383 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
116384 + sizeof(ioc_fm_port_mac_statistics_t)))
116385 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116386 +
116387 + break;
116388 + }
116389 +
116390 + case FM_PORT_IOC_GET_BMI_COUNTERS:
116391 + {
116392 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116393 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116394 + ioc_fm_port_bmi_stats_t param;
116395 +
116396 + if (!p_LnxWrpFmDev)
116397 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116398 +
116399 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
116400 + (t_FmPortBmiStats *)&param))
116401 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116402 +
116403 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
116404 + sizeof(ioc_fm_port_bmi_stats_t)))
116405 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116406 +
116407 + break;
116408 + }
116409 +
116410 + default:
116411 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116412 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
116413 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116414 + }
116415 +
116416 + if (err)
116417 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
116418 +
116419 + return E_OK;
116420 +}
116421 +
116422 +/*****************************************************************************/
116423 +/* API routines for the FM Linux Device */
116424 +/*****************************************************************************/
116425 +
116426 +static int fm_open(struct inode *inode, struct file *file)
116427 +{
116428 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
116429 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
116430 + unsigned int major = imajor(inode);
116431 + unsigned int minor = iminor(inode);
116432 + struct device_node *fm_node;
116433 + static struct of_device_id fm_node_of_match[] = {
116434 + { .compatible = "fsl,fman", },
116435 + { /* end of list */ },
116436 + };
116437 +
116438 + DBG(TRACE, ("Opening minor - %d - ", minor));
116439 +
116440 + if (file->private_data != NULL)
116441 + return 0;
116442 +
116443 + /* Get all the FM nodes */
116444 + for_each_matching_node(fm_node, fm_node_of_match) {
116445 + struct platform_device *of_dev;
116446 +
116447 + of_dev = of_find_device_by_node(fm_node);
116448 + if (unlikely(of_dev == NULL)) {
116449 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
116450 + return -ENXIO;
116451 + }
116452 +
116453 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
116454 + if (p_LnxWrpFmDev->major == major)
116455 + break;
116456 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116457 + p_LnxWrpFmDev = NULL;
116458 + }
116459 +
116460 + if (!p_LnxWrpFmDev)
116461 + return -ENODEV;
116462 +
116463 + if (minor == DEV_FM_MINOR_BASE)
116464 + file->private_data = p_LnxWrpFmDev;
116465 + else if (minor == DEV_FM_PCD_MINOR_BASE)
116466 + file->private_data = p_LnxWrpFmDev;
116467 + else {
116468 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
116469 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
116470 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
116471 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
116472 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
116473 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
116474 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
116475 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
116476 + else
116477 + return -EINVAL;
116478 +
116479 + /* if trying to open port, check if it initialized */
116480 + if (!p_LnxWrpFmPortDev->h_Dev)
116481 + return -ENODEV;
116482 +
116483 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
116484 + file->private_data = p_LnxWrpFmPortDev;
116485 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116486 + }
116487 +
116488 + if (file->private_data == NULL)
116489 + return -ENXIO;
116490 +
116491 + return 0;
116492 +}
116493 +
116494 +static int fm_close(struct inode *inode, struct file *file)
116495 +{
116496 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116497 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
116498 + unsigned int minor = iminor(inode);
116499 + int err = 0;
116500 +
116501 + DBG(TRACE, ("Closing minor - %d - ", minor));
116502 +
116503 + if ((minor == DEV_FM_MINOR_BASE) ||
116504 + (minor == DEV_FM_PCD_MINOR_BASE))
116505 + {
116506 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
116507 + if (!p_LnxWrpFmDev)
116508 + return -ENODEV;
116509 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116510 + }
116511 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116512 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116513 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116514 + {
116515 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
116516 + if (!p_LnxWrpFmPortDev)
116517 + return -ENODEV;
116518 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
116519 + }
116520 +
116521 + return err;
116522 +}
116523 +
116524 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
116525 +{
116526 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
116527 +
116528 + if ((minor == DEV_FM_MINOR_BASE) ||
116529 + (minor == DEV_FM_PCD_MINOR_BASE))
116530 + {
116531 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
116532 + if (!p_LnxWrpFmDev)
116533 + return -ENODEV;
116534 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
116535 + return -EFAULT;
116536 + }
116537 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116538 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116539 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116540 + {
116541 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
116542 + if (!p_LnxWrpFmPortDev)
116543 + return -ENODEV;
116544 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
116545 + return -EFAULT;
116546 + }
116547 + else
116548 + {
116549 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
116550 + return -ENODEV;
116551 + }
116552 +
116553 + return 0;
116554 +}
116555 +
116556 +#ifdef CONFIG_COMPAT
116557 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116558 +{
116559 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116560 + long res;
116561 +
116562 + fm_mutex_lock();
116563 + res = fm_ioctls(minor, file, cmd, arg, true);
116564 + fm_mutex_unlock();
116565 +
116566 + return res;
116567 +}
116568 +#endif
116569 +
116570 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116571 +{
116572 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116573 + long res;
116574 +
116575 + fm_mutex_lock();
116576 + res = fm_ioctls(minor, file, cmd, arg, false);
116577 + fm_mutex_unlock();
116578 +
116579 + return res;
116580 +}
116581 +
116582 +/* Globals for FM character device */
116583 +struct file_operations fm_fops =
116584 +{
116585 + .owner = THIS_MODULE,
116586 + .unlocked_ioctl = fm_ioctl,
116587 +#ifdef CONFIG_COMPAT
116588 + .compat_ioctl = fm_compat_ioctl,
116589 +#endif
116590 + .open = fm_open,
116591 + .release = fm_close,
116592 +};
116593 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116594 new file mode 100644
116595 index 00000000..322ae9ef
116596 --- /dev/null
116597 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116598 @@ -0,0 +1,1297 @@
116599 +/*
116600 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116601 + *
116602 + * Redistribution and use in source and binary forms, with or without
116603 + * modification, are permitted provided that the following conditions are met:
116604 + * * Redistributions of source code must retain the above copyright
116605 + * notice, this list of conditions and the following disclaimer.
116606 + * * Redistributions in binary form must reproduce the above copyright
116607 + * notice, this list of conditions and the following disclaimer in the
116608 + * documentation and/or other materials provided with the distribution.
116609 + * * Neither the name of Freescale Semiconductor nor the
116610 + * names of its contributors may be used to endorse or promote products
116611 + * derived from this software without specific prior written permission.
116612 + *
116613 + *
116614 + * ALTERNATIVELY, this software may be distributed under the terms of the
116615 + * GNU General Public License ("GPL") as published by the Free Software
116616 + * Foundation, either version 2 of that License or (at your option) any
116617 + * later version.
116618 + *
116619 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116620 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116621 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116622 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116623 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116624 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116625 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116626 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116627 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116628 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116629 + */
116630 +
116631 +/*
116632 + @File lnxwrp_fm_compat_ioctls.c
116633 +
116634 + @Description FM PCD compat functions
116635 +
116636 +*/
116637 +
116638 +#if !defined(CONFIG_COMPAT)
116639 +#error "missing COMPAT layer..."
116640 +#endif
116641 +
116642 +
116643 +#include <linux/kernel.h>
116644 +#include <linux/module.h>
116645 +#include <linux/fs.h>
116646 +#include <linux/cdev.h>
116647 +#include <linux/device.h>
116648 +#include <linux/irq.h>
116649 +#include <linux/interrupt.h>
116650 +#include <linux/io.h>
116651 +#include <linux/ioport.h>
116652 +#include <asm/uaccess.h>
116653 +#include <asm/errno.h>
116654 +#ifndef CONFIG_FMAN_ARM
116655 +#include <sysdev/fsl_soc.h>
116656 +#endif
116657 +
116658 +#include "part_ext.h"
116659 +#include "fm_ioctls.h"
116660 +#include "fm_pcd_ioctls.h"
116661 +#include "fm_port_ioctls.h"
116662 +#include "lnxwrp_ioctls_fm_compat.h"
116663 +
116664 +#if defined(FM_COMPAT_DBG)
116665 +static void hex_dump(void * p_addr, unsigned int size)
116666 +{
116667 + int i;
116668 +
116669 + for(i=0; i<size; i+=16)
116670 + {
116671 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116672 + *(unsigned int *)(p_addr + i),
116673 + *(unsigned int *)(p_addr + i + 4),
116674 + *(unsigned int *)(p_addr + i + 8),
116675 + *(unsigned int *)(p_addr + i +12)
116676 + );
116677 + }
116678 +}
116679 +#endif
116680 +
116681 +/* maping kernel pointers w/ UserSpace id's { */
116682 +struct map_node {
116683 + void *ptr;
116684 + u8 node_type;
116685 +};
116686 +
116687 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116688 +
116689 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116690 +{
116691 + compat_uptr_t k;
116692 +
116693 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116694 +
116695 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116696 + if(compat_ptr2id_array[k].ptr == p){
116697 + compat_ptr2id_array[k].ptr = NULL;
116698 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116699 + }
116700 +}
116701 +EXPORT_SYMBOL(compat_del_ptr2id);
116702 +
116703 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116704 +{
116705 + compat_uptr_t k;
116706 +
116707 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116708 +
116709 + if(!p)
116710 + return 0;
116711 +
116712 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116713 + if(compat_ptr2id_array[k].ptr == NULL)
116714 + {
116715 + compat_ptr2id_array[k].ptr = p;
116716 + compat_ptr2id_array[k].node_type = node_type;
116717 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116718 + return k | COMPAT_PTR2ID_WATERMARK;
116719 + }
116720 +
116721 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116722 + return 0;
116723 +}
116724 +EXPORT_SYMBOL(compat_add_ptr2id);
116725 +
116726 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116727 +{
116728 + compat_uptr_t k;
116729 +
116730 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116731 +
116732 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116733 + if(compat_ptr2id_array[k].ptr == p &&
116734 + compat_ptr2id_array[k].node_type == node_type) {
116735 +
116736 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116737 + return k | COMPAT_PTR2ID_WATERMARK;
116738 + }
116739 +
116740 + return 0;
116741 +}
116742 +EXPORT_SYMBOL(compat_get_ptr2id);
116743 +
116744 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116745 +{
116746 +
116747 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116748 +
116749 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116750 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116751 + dump_stack();
116752 + return compat_ptr(comp);
116753 + }
116754 +
116755 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116756 +
116757 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116758 + && compat_ptr2id_array[comp].node_type == node_type)) {
116759 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116760 + return compat_ptr2id_array[comp].ptr;
116761 + }
116762 + return NULL;
116763 +}
116764 +EXPORT_SYMBOL(compat_get_id2ptr);
116765 +/* } maping kernel pointers w/ UserSpace id's */
116766 +
116767 +void compat_obj_delete(
116768 + ioc_compat_fm_obj_t *compat_id,
116769 + ioc_fm_obj_t *id)
116770 +{
116771 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116772 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116773 +}
116774 +
116775 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116776 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116777 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116778 + ioc_fm_pcd_engine next_engine,
116779 + uint8_t compat)
116780 +{
116781 + _fm_cpt_dbg (compat, " {->...\n");
116782 +
116783 + switch (next_engine)
116784 + {
116785 + case e_IOC_FM_PCD_PLCR:
116786 + if (compat == COMPAT_US_TO_K)
116787 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116788 + else
116789 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116790 + break;
116791 + case e_IOC_FM_PCD_KG:
116792 + if (compat == COMPAT_US_TO_K)
116793 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116794 + else
116795 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116796 + break;
116797 + default:
116798 + if (compat == COMPAT_US_TO_K)
116799 + param->action = compat_param->action;
116800 + else
116801 + compat_param->action = param->action;
116802 + break;
116803 + }
116804 +
116805 + _fm_cpt_dbg (compat, " ...->}\n");
116806 +}
116807 +
116808 +void compat_copy_fm_pcd_plcr_profile(
116809 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
116810 + ioc_fm_pcd_plcr_profile_params_t *param,
116811 + uint8_t compat)
116812 +{
116813 + _fm_cpt_dbg (compat, " {->...\n");
116814 +
116815 + if (compat == COMPAT_US_TO_K)
116816 + {
116817 + param->modify = compat_param->modify;
116818 +
116819 + /* profile_select */
116820 + if (!compat_param->modify)
116821 + {
116822 + param->profile_select.new_params.profile_type =
116823 + compat_param->profile_select.new_params.profile_type;
116824 + param->profile_select.new_params.p_fm_port =
116825 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
116826 + param->profile_select.new_params.relative_profile_id =
116827 + compat_param->profile_select.new_params.relative_profile_id;
116828 + }
116829 + else
116830 + param->profile_select.p_profile =
116831 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
116832 +
116833 + param->alg_selection = compat_param->alg_selection;
116834 + param->color_mode = compat_param->color_mode;
116835 +
116836 + /* both parameters in the union has the same size, so memcpy works */
116837 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
116838 +
116839 + memcpy(&param->non_passthrough_alg_param,
116840 + &compat_param->non_passthrough_alg_param,
116841 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116842 +
116843 + param->next_engine_on_green = compat_param->next_engine_on_green;
116844 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
116845 + param->next_engine_on_red = compat_param->next_engine_on_red;
116846 +
116847 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
116848 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
116849 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
116850 + }
116851 + else
116852 + {
116853 + compat_param->modify = param->modify;
116854 +
116855 + /* profile_select */
116856 + if (!param->modify)
116857 + {
116858 + compat_param->profile_select.new_params.profile_type =
116859 + param->profile_select.new_params.profile_type;
116860 + compat_param->profile_select.new_params.p_fm_port =
116861 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
116862 + compat_param->profile_select.new_params.relative_profile_id =
116863 + param->profile_select.new_params.relative_profile_id;
116864 + }
116865 + else
116866 + compat_param->profile_select.p_profile =
116867 + compat_pcd_ptr2id(param->profile_select.p_profile);
116868 +
116869 + compat_param->alg_selection = param->alg_selection;
116870 + compat_param->color_mode = param->color_mode;
116871 +
116872 + /* both parameters in the union has the same size, so memcpy works */
116873 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
116874 +
116875 + memcpy(&compat_param->non_passthrough_alg_param,
116876 + &param->non_passthrough_alg_param,
116877 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116878 +
116879 + compat_param->next_engine_on_green = param->next_engine_on_green;
116880 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
116881 + compat_param->next_engine_on_red = param->next_engine_on_red;
116882 +
116883 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
116884 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
116885 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
116886 +
116887 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116888 + }
116889 +
116890 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
116891 + &param->params_on_green, param->next_engine_on_green, compat);
116892 +
116893 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
116894 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
116895 +
116896 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
116897 + &param->params_on_red, param->next_engine_on_red, compat);
116898 +
116899 + _fm_cpt_dbg (compat, " ...->}\n");
116900 +}
116901 +
116902 +static inline void compat_copy_fm_pcd_cc_next_kg(
116903 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
116904 + ioc_fm_pcd_cc_next_kg_params_t *param,
116905 + uint8_t compat)
116906 +{
116907 + _fm_cpt_dbg (compat, " {->...\n");
116908 +
116909 + if (compat == COMPAT_US_TO_K)
116910 + {
116911 + param->new_fqid = compat_param->new_fqid;
116912 + param->override_fqid = compat_param->override_fqid;
116913 +#if DPAA_VERSION >= 11
116914 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
116915 +#endif
116916 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116917 + }
116918 + else
116919 + {
116920 + compat_param->new_fqid = param->new_fqid;
116921 + compat_param->override_fqid = param->override_fqid;
116922 +#if DPAA_VERSION >= 11
116923 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
116924 +#endif
116925 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116926 + }
116927 +
116928 + _fm_cpt_dbg (compat, " ...->}\n");
116929 +}
116930 +
116931 +static inline void compat_copy_fm_pcd_cc_next_cc(
116932 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
116933 + ioc_fm_pcd_cc_next_cc_params_t *param,
116934 + uint8_t compat)
116935 +{
116936 + _fm_cpt_dbg (compat, " {->...\n");
116937 +
116938 + if (compat == COMPAT_US_TO_K)
116939 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
116940 + else
116941 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
116942 +
116943 + _fm_cpt_dbg (compat, " ...->}\n");
116944 +}
116945 +
116946 +static inline void compat_copy_fm_pcd_cc_next_engine(
116947 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
116948 + ioc_fm_pcd_cc_next_engine_params_t *param,
116949 + uint8_t compat)
116950 +{
116951 + _fm_cpt_dbg (compat, " {->...\n");
116952 +
116953 + if (compat == COMPAT_US_TO_K)
116954 + {
116955 + param->next_engine = compat_param->next_engine;
116956 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
116957 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
116958 +
116959 + switch (param->next_engine)
116960 + {
116961 +#if DPAA_VERSION >= 11
116962 + case e_IOC_FM_PCD_FR:
116963 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
116964 + break;
116965 +#endif /* DPAA_VERSION >= 11 */
116966 + case e_IOC_FM_PCD_CC:
116967 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116968 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116969 + break;
116970 + case e_IOC_FM_PCD_KG:
116971 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116972 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116973 + break;
116974 + case e_IOC_FM_PCD_DONE:
116975 + case e_IOC_FM_PCD_PLCR:
116976 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116977 + default:
116978 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
116979 + }
116980 + param->statistics_en = compat_param->statistics_en;
116981 + }
116982 + else
116983 + {
116984 + compat_param->next_engine = param->next_engine;
116985 +
116986 + switch (compat_param->next_engine)
116987 + {
116988 +#if DPAA_VERSION >= 11
116989 + case e_IOC_FM_PCD_FR:
116990 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
116991 + break;
116992 +#endif /* DPAA_VERSION >= 11 */
116993 + case e_IOC_FM_PCD_CC:
116994 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116995 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116996 + break;
116997 + case e_IOC_FM_PCD_KG:
116998 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116999 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
117000 + break;
117001 + case e_IOC_FM_PCD_DONE:
117002 + case e_IOC_FM_PCD_PLCR:
117003 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
117004 + default:
117005 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
117006 + }
117007 + compat_param->statistics_en = param->statistics_en;
117008 + }
117009 +
117010 + _fm_cpt_dbg (compat, " ...->}\n");
117011 +}
117012 +
117013 +void compat_copy_fm_pcd_cc_key(
117014 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
117015 + ioc_fm_pcd_cc_key_params_t *param,
117016 + uint8_t compat)
117017 +{
117018 + if (compat == COMPAT_US_TO_K)
117019 + {
117020 + param->p_key = compat_ptr(compat_param->p_key);
117021 + param->p_mask = compat_ptr(compat_param->p_mask);
117022 + }
117023 + else
117024 + {
117025 + compat_param->p_key = ptr_to_compat(param->p_key);
117026 + compat_param->p_mask = ptr_to_compat(param->p_mask);
117027 + }
117028 +
117029 + compat_copy_fm_pcd_cc_next_engine(
117030 + &compat_param->cc_next_engine_params,
117031 + &param->cc_next_engine_params,
117032 + compat);
117033 +}
117034 +
117035 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
117036 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
117037 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
117038 + uint8_t compat)
117039 +{
117040 + if (compat == COMPAT_US_TO_K)
117041 + {
117042 + param->id = compat_pcd_id2ptr(compat_param->id);
117043 + param->key_indx = compat_param->key_indx;
117044 + param->key_size = compat_param->key_size;
117045 + compat_copy_fm_pcd_cc_key(
117046 + &compat_param->key_params,
117047 + &param->key_params,
117048 + compat);
117049 + }
117050 + else
117051 + {
117052 + compat_param->id = compat_pcd_ptr2id(param->id);
117053 + compat_param->key_indx = param->key_indx;
117054 + compat_param->key_size = param->key_size;
117055 + compat_copy_fm_pcd_cc_key(
117056 + &compat_param->key_params,
117057 + &param->key_params,
117058 + compat);
117059 + }
117060 +}
117061 +
117062 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
117063 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
117064 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
117065 + uint8_t compat)
117066 +{
117067 + if (compat == COMPAT_US_TO_K)
117068 + {
117069 + param->id = compat_pcd_id2ptr(compat_param->id);
117070 + param->key_indx = compat_param->key_indx;
117071 + param->key_size = compat_param->key_size;
117072 + }
117073 + else
117074 + {
117075 + compat_param->id = compat_pcd_ptr2id(param->id);
117076 + compat_param->key_indx = param->key_indx;
117077 + compat_param->key_size = param->key_size;
117078 + }
117079 +
117080 + compat_copy_fm_pcd_cc_next_engine(
117081 + &compat_param->cc_next_engine_params,
117082 + &param->cc_next_engine_params,
117083 + compat);
117084 +}
117085 +
117086 +void compat_fm_pcd_cc_tree_modify_next_engine(
117087 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
117088 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
117089 + uint8_t compat)
117090 +{
117091 + if (compat == COMPAT_US_TO_K)
117092 + {
117093 + param->id = compat_pcd_id2ptr(compat_param->id);
117094 + param->grp_indx = compat_param->grp_indx;
117095 + param->indx = compat_param->indx;
117096 + }
117097 + else
117098 + {
117099 + compat_param->id = compat_pcd_ptr2id(param->id);
117100 + compat_param->grp_indx = param->grp_indx;
117101 + compat_param->indx = param->indx;
117102 + }
117103 +
117104 + compat_copy_fm_pcd_cc_next_engine(
117105 + &compat_param->cc_next_engine_params,
117106 + &param->cc_next_engine_params,
117107 + compat);
117108 +}
117109 +
117110 +void compat_copy_fm_pcd_hash_table(
117111 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
117112 + ioc_fm_pcd_hash_table_params_t *param,
117113 + uint8_t compat)
117114 +{
117115 + if (compat == COMPAT_US_TO_K)
117116 + {
117117 + param->max_num_of_keys = compat_param->max_num_of_keys;
117118 + param->statistics_mode = compat_param->statistics_mode;
117119 + param->kg_hash_shift = compat_param->kg_hash_shift;
117120 + param->hash_res_mask = compat_param->hash_res_mask;
117121 + param->hash_shift = compat_param->hash_shift;
117122 + param->match_key_size = compat_param->match_key_size;
117123 + param->id = compat_pcd_id2ptr(compat_param->id);
117124 + }
117125 + else
117126 + {
117127 + compat_param->max_num_of_keys = param->max_num_of_keys;
117128 + compat_param->statistics_mode = param->statistics_mode;
117129 + compat_param->kg_hash_shift = param->kg_hash_shift;
117130 + compat_param->hash_res_mask = param->hash_res_mask;
117131 + compat_param->hash_shift = param->hash_shift;
117132 + compat_param->match_key_size = param->match_key_size;
117133 +
117134 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117135 + }
117136 +
117137 + compat_copy_fm_pcd_cc_next_engine(
117138 + &compat_param->cc_next_engine_params_for_miss,
117139 + &param->cc_next_engine_params_for_miss,
117140 + compat);
117141 +}
117142 +
117143 +void compat_copy_fm_pcd_cc_grp(
117144 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
117145 + ioc_fm_pcd_cc_grp_params_t *param,
117146 + uint8_t compat)
117147 +{
117148 + int k;
117149 +
117150 + _fm_cpt_dbg (compat, " {->...\n");
117151 +
117152 + if (compat == COMPAT_US_TO_K)
117153 + {
117154 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117155 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117156 + }
117157 + else
117158 + {
117159 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117160 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117161 + }
117162 +
117163 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
117164 + compat_copy_fm_pcd_cc_next_engine(
117165 + &compat_param->next_engine_per_entries_in_grp[k],
117166 + &param->next_engine_per_entries_in_grp[k],
117167 + compat);
117168 +
117169 + _fm_cpt_dbg (compat, " ...->}\n");
117170 +}
117171 +
117172 +void compat_copy_fm_pcd_cc_tree(
117173 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
117174 + ioc_fm_pcd_cc_tree_params_t *param,
117175 + uint8_t compat)
117176 +{
117177 + int k;
117178 + _fm_cpt_dbg (compat, " {->...\n");
117179 +
117180 + if (compat == COMPAT_US_TO_K)
117181 + {
117182 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117183 + param->num_of_groups = compat_param->num_of_groups;
117184 + }
117185 + else
117186 + {
117187 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
117188 + compat_param->num_of_groups = param->num_of_groups;
117189 +
117190 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117191 + }
117192 +
117193 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
117194 + compat_copy_fm_pcd_cc_grp(
117195 + &compat_param->fm_pcd_cc_group_params[k],
117196 + &param->fm_pcd_cc_group_params[k],
117197 + compat);
117198 +
117199 + _fm_cpt_dbg (compat, " ...->}\n");
117200 +}
117201 +
117202 +void compat_fm_pcd_prs_sw(
117203 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
117204 + ioc_fm_pcd_prs_sw_params_t *param,
117205 + uint8_t compat)
117206 +{
117207 + if (compat == COMPAT_US_TO_K)
117208 + {
117209 + param->override = compat_param->override;
117210 + param->size = compat_param->size;
117211 + param->base = compat_param->base;
117212 + param->p_code = compat_ptr(compat_param->p_code);
117213 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
117214 + param->num_of_labels = compat_param->num_of_labels;
117215 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
117216 + }
117217 +}
117218 +
117219 +void compat_copy_fm_pcd_kg_scheme(
117220 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
117221 + ioc_fm_pcd_kg_scheme_params_t *param,
117222 + uint8_t compat)
117223 +{
117224 + _fm_cpt_dbg(compat," {->...\n");
117225 +
117226 + if (compat == COMPAT_US_TO_K)
117227 + {
117228 + param->modify = compat_param->modify;
117229 +
117230 + /* scm_id */
117231 + if (compat_param->modify)
117232 + {
117233 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
117234 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
117235 + }
117236 + else
117237 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
117238 +
117239 + param->always_direct = compat_param->always_direct;
117240 + /* net_env_params */
117241 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
117242 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
117243 + memcpy(param->net_env_params.unit_ids,
117244 + compat_param->net_env_params.unit_ids,
117245 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117246 +
117247 + param->use_hash = compat_param->use_hash;
117248 + memcpy(&param->key_extract_and_hash_params,
117249 + &compat_param->key_extract_and_hash_params,
117250 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
117251 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
117252 + param->base_fqid = compat_param->base_fqid;
117253 +#if DPAA_VERSION >= 11
117254 + param->override_storage_profile =
117255 + compat_param->override_storage_profile;
117256 + param->storage_profile = compat_param->storage_profile;
117257 +#endif
117258 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
117259 + memcpy(param->extracted_ors,
117260 + compat_param->extracted_ors,
117261 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
117262 + param->next_engine = compat_param->next_engine;
117263 +
117264 + /* kg_next_engine_params */
117265 + if (param->next_engine == e_IOC_FM_PCD_CC)
117266 + {
117267 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
117268 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
117269 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
117270 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117271 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117272 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
117273 + &compat_param->kg_next_engine_params.cc.plcr_profile,
117274 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117275 + }
117276 + else
117277 + memcpy(&param->kg_next_engine_params,
117278 + &compat_param->kg_next_engine_params,
117279 + sizeof(param->kg_next_engine_params));
117280 +
117281 + memcpy(&param->scheme_counter,
117282 + &compat_param->scheme_counter,
117283 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117284 + }
117285 + else
117286 + {
117287 + compat_param->modify = param->modify;
117288 +
117289 + /* scm_id */
117290 + if (param->modify)
117291 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
117292 + else
117293 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
117294 +
117295 + compat_param->always_direct = param->always_direct;
117296 +
117297 + /* net_env_params */
117298 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
117299 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
117300 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117301 +
117302 + compat_param->use_hash = param->use_hash;
117303 + 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));
117304 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
117305 + compat_param->base_fqid = param->base_fqid;
117306 +#if DPAA_VERSION >= 11
117307 + compat_param->override_storage_profile =
117308 + param->override_storage_profile;
117309 + compat_param->storage_profile = param->storage_profile;
117310 +#endif
117311 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
117312 + 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));
117313 + compat_param->next_engine = param->next_engine;
117314 +
117315 + /* kg_next_engine_params */
117316 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
117317 + {
117318 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
117319 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
117320 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
117321 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117322 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117323 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
117324 + &param->kg_next_engine_params.cc.plcr_profile,
117325 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117326 + }
117327 + else
117328 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
117329 +
117330 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117331 +
117332 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117333 + }
117334 +
117335 + _fm_cpt_dbg(compat," ...->}\n");
117336 +}
117337 +
117338 +void compat_copy_fm_pcd_kg_scheme_spc(
117339 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
117340 + ioc_fm_pcd_kg_scheme_spc_t *param,
117341 + uint8_t compat)
117342 +{
117343 + if (compat == COMPAT_US_TO_K)
117344 + {
117345 + param->id = compat_pcd_id2ptr(compat_param->id);
117346 + param->val = compat_param->val;
117347 + } else {
117348 + compat_param->id = compat_pcd_ptr2id(param->id);
117349 + compat_param->val = param->val;
117350 + }
117351 +}
117352 +
117353 +
117354 +void compat_copy_fm_pcd_kg_scheme_select(
117355 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
117356 + ioc_fm_pcd_kg_scheme_select_t *param,
117357 + uint8_t compat)
117358 +{
117359 + if (compat == COMPAT_US_TO_K)
117360 + {
117361 + param->direct = compat_param->direct;
117362 + if (param->direct)
117363 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
117364 + }
117365 +}
117366 +
117367 +void compat_copy_fm_pcd_kg_schemes_params(
117368 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
117369 + ioc_fm_pcd_port_schemes_params_t *param,
117370 + uint8_t compat)
117371 +{
117372 + int k;
117373 +
117374 + if (compat == COMPAT_US_TO_K) {
117375 + param->num_of_schemes = compat_param->num_of_schemes;
117376 + for(k=0; k < compat_param->num_of_schemes; k++)
117377 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117378 + }
117379 +}
117380 +
117381 +void compat_copy_fm_port_pcd_cc(
117382 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
117383 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
117384 + uint8_t compat)
117385 +{
117386 + if (compat == COMPAT_US_TO_K){
117387 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
117388 + }
117389 +}
117390 +
117391 +void compat_copy_fm_port_pcd_kg(
117392 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117393 + ioc_fm_port_pcd_kg_params_t *param,
117394 + uint8_t compat)
117395 +{
117396 + if (compat == COMPAT_US_TO_K){
117397 + uint8_t k;
117398 +
117399 + param->num_of_schemes = compat_param->num_of_schemes;
117400 + for(k=0; k<compat_param->num_of_schemes; k++)
117401 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117402 +
117403 + param->direct_scheme = compat_param->direct_scheme;
117404 + if (param->direct_scheme)
117405 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
117406 + }
117407 +}
117408 +
117409 +void compat_copy_fm_port_pcd(
117410 + ioc_compat_fm_port_pcd_params_t *compat_param,
117411 + ioc_fm_port_pcd_params_t *param,
117412 + uint8_t compat)
117413 +{
117414 + if (compat == COMPAT_US_TO_K)
117415 + {
117416 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117417 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117418 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117419 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117420 +
117421 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
117422 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117423 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117424 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117425 +
117426 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
117427 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
117428 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
117429 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
117430 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
117431 +#if (DPAA_VERSION >= 11)
117432 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
117433 +#endif
117434 + param->pcd_support = compat_param->pcd_support;
117435 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117436 +
117437 + if (param->p_cc_params)
117438 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
117439 + if (param->p_kg_params)
117440 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
117441 + if (param->p_plcr_params)
117442 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
117443 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
117444 +#if (DPAA_VERSION >= 11)
117445 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
117446 +#endif
117447 + }
117448 +}
117449 +
117450 +void compat_copy_fm_port_pcd_modify_tree(
117451 + ioc_compat_fm_obj_t *compat_id,
117452 + ioc_fm_obj_t *id,
117453 + uint8_t compat)
117454 +{
117455 + if (compat == COMPAT_US_TO_K)
117456 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117457 +}
117458 +
117459 +#if (DPAA_VERSION >= 11)
117460 +void compat_copy_fm_port_vsp_alloc_params(
117461 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117462 + ioc_fm_port_vsp_alloc_params_t *param,
117463 + uint8_t compat)
117464 +{
117465 + if (compat == COMPAT_US_TO_K)
117466 + {
117467 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
117468 +
117469 + param->dflt_relative_id = compat_param->dflt_relative_id;
117470 + param->num_of_profiles = compat_param->num_of_profiles;
117471 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
117472 + }
117473 +}
117474 +#endif /* (DPAA_VERSION >= 11) */
117475 +
117476 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117477 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117478 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117479 + uint8_t compat)
117480 +{
117481 + if (compat == COMPAT_US_TO_K)
117482 + {
117483 + param->id = compat_pcd_id2ptr(compat_param->id);
117484 + param->key_index = compat_param->key_index;
117485 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117486 + } else {
117487 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117488 + compat_param->key_index = param->key_index;
117489 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117490 + }
117491 +}
117492 +
117493 +
117494 +void compat_copy_fm_pcd_net_env(
117495 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117496 + ioc_fm_pcd_net_env_params_t *param,
117497 + uint8_t compat)
117498 +{
117499 + if (compat == COMPAT_US_TO_K)
117500 + {
117501 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117502 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117503 + param->id = NULL; /* to avoid passing garbage to the kernel */
117504 + }
117505 + else
117506 + {
117507 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117508 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117509 +
117510 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117511 + }
117512 +}
117513 +
117514 +void compat_copy_fm_pcd_cc_node_modify_key(
117515 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117516 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117517 + uint8_t compat)
117518 +{
117519 + if (compat == COMPAT_US_TO_K)
117520 + {
117521 + param->key_indx = compat_param->key_indx;
117522 + param->key_size = compat_param->key_size;
117523 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
117524 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
117525 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
117526 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
117527 + param->id = compat_pcd_id2ptr(compat_param->id);
117528 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117529 + }
117530 + else
117531 + {
117532 + compat_param->key_indx = param->key_indx;
117533 + compat_param->key_size = param->key_size;
117534 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
117535 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
117536 +
117537 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117538 + }
117539 +}
117540 +
117541 +void compat_copy_keys(
117542 + ioc_compat_keys_params_t *compat_param,
117543 + ioc_keys_params_t *param,
117544 + uint8_t compat)
117545 +{
117546 + int k = 0;
117547 +
117548 + _fm_cpt_dbg(compat," {->...\n");
117549 +
117550 + if (compat == COMPAT_US_TO_K) {
117551 + param->max_num_of_keys = compat_param->max_num_of_keys;
117552 + param->mask_support = compat_param->mask_support;
117553 + param->statistics_mode = compat_param->statistics_mode;
117554 + param->num_of_keys = compat_param->num_of_keys;
117555 + param->key_size = compat_param->key_size;
117556 +#if (DPAA_VERSION >= 11)
117557 + memcpy(&param->frame_length_ranges,
117558 + &compat_param->frame_length_ranges,
117559 + sizeof(param->frame_length_ranges[0]) *
117560 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117561 +#endif /* (DPAA_VERSION >= 11) */
117562 + }
117563 + else {
117564 + compat_param->max_num_of_keys = param->max_num_of_keys;
117565 + compat_param->mask_support = param->mask_support;
117566 + compat_param->statistics_mode = param->statistics_mode;
117567 + compat_param->num_of_keys = param->num_of_keys;
117568 + compat_param->key_size = param->key_size;
117569 +#if (DPAA_VERSION >= 11)
117570 + memcpy(&compat_param->frame_length_ranges,
117571 + &param->frame_length_ranges,
117572 + sizeof(compat_param->frame_length_ranges[0]) *
117573 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117574 +#endif /* (DPAA_VERSION >= 11) */
117575 + }
117576 +
117577 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
117578 + compat_copy_fm_pcd_cc_key(
117579 + &compat_param->key_params[k],
117580 + &param->key_params[k],
117581 + compat);
117582 +
117583 + compat_copy_fm_pcd_cc_next_engine(
117584 + &compat_param->cc_next_engine_params_for_miss,
117585 + &param->cc_next_engine_params_for_miss,
117586 + compat);
117587 +
117588 + _fm_cpt_dbg(compat," ...->}\n");
117589 +}
117590 +
117591 +void compat_copy_fm_pcd_cc_node(
117592 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117593 + ioc_fm_pcd_cc_node_params_t *param,
117594 + uint8_t compat)
117595 +{
117596 + _fm_cpt_dbg(compat," {->...\n");
117597 +
117598 + if (compat == COMPAT_US_TO_K)
117599 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117600 +
117601 + else
117602 + {
117603 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117604 +
117605 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117606 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117607 + }
117608 +
117609 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117610 +
117611 + _fm_cpt_dbg(compat," ...->}\n");
117612 +}
117613 +
117614 +void compat_fm_pcd_manip_set_node(
117615 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117616 + ioc_fm_pcd_manip_params_t *param,
117617 + uint8_t compat)
117618 +{
117619 + if (compat == COMPAT_US_TO_K) {
117620 + param->type = compat_param->type;
117621 + switch (param->type) {
117622 + case e_IOC_FM_PCD_MANIP_HDR:
117623 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117624 + memcpy(&param->u.hdr.rmv_params,
117625 + &compat_param->u.hdr.rmv_params,
117626 + sizeof(param->u.hdr.rmv_params));
117627 +
117628 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117629 + param->u.hdr.insrt_params.type =
117630 + compat_param->u.hdr.insrt_params.type;
117631 + switch (compat_param->u.hdr.insrt_params.type)
117632 + {
117633 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117634 + param->u.hdr.insrt_params.u.generic.offset =
117635 + compat_param->u.hdr.insrt_params.u.generic.offset;
117636 + param->u.hdr.insrt_params.u.generic.size =
117637 + compat_param->u.hdr.insrt_params.u.generic.size;
117638 + param->u.hdr.insrt_params.u.generic.replace =
117639 + compat_param->u.hdr.insrt_params.u.generic.replace;
117640 + param->u.hdr.insrt_params.u.generic.p_data =
117641 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117642 + break;
117643 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117644 + param->u.hdr.insrt_params.u.by_hdr.type =
117645 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117646 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117647 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117648 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117649 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117650 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117651 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117652 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117653 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117654 + break;
117655 + default:
117656 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117657 + }
117658 +
117659 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117660 + memcpy(&param->u.hdr.field_update_params,
117661 + &compat_param->u.hdr.field_update_params,
117662 + sizeof(param->u.hdr.field_update_params));
117663 +
117664 + param->u.hdr.custom = compat_param->u.hdr.custom;
117665 + memcpy(&param->u.hdr.custom_params,
117666 + &compat_param->u.hdr.custom_params,
117667 + sizeof(param->u.hdr.custom_params));
117668 +
117669 + param->u.hdr.dont_parse_after_manip =
117670 + compat_param->u.hdr.dont_parse_after_manip;
117671 + break;
117672 + case e_IOC_FM_PCD_MANIP_REASSEM:
117673 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117674 + break;
117675 + case e_IOC_FM_PCD_MANIP_FRAG:
117676 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117677 + break;
117678 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117679 + memcpy(&param->u.special_offload,
117680 + &compat_param->u.special_offload,
117681 + sizeof(param->u.special_offload));
117682 + break;
117683 + }
117684 +
117685 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117686 + param->id = compat_pcd_id2ptr(compat_param->id);
117687 + }
117688 + else {
117689 + compat_param->type = param->type;
117690 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117691 +
117692 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117693 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117694 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117695 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117696 +
117697 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117698 + /* ... should be one that was added previously by the very call to
117699 + compat_add_ptr2id() below: */
117700 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117701 + }
117702 +}
117703 +
117704 +void compat_copy_fm_pcd_manip_get_stats(
117705 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117706 + ioc_fm_pcd_manip_get_stats_t *param,
117707 + uint8_t compat)
117708 +{
117709 + _fm_cpt_dbg (compat, " {->...\n");
117710 +
117711 + if (compat == COMPAT_US_TO_K)
117712 + {
117713 + param->id = compat_pcd_id2ptr(compat_param->id);
117714 + memcpy(&param->stats, &compat_param->stats,
117715 + sizeof(ioc_fm_pcd_manip_stats_t));
117716 + }
117717 + else
117718 + {
117719 + compat_param->id = compat_add_ptr2id(param->id,
117720 + FM_MAP_TYPE_PCD_NODE);
117721 + memcpy(&compat_param->stats, &param->stats,
117722 + sizeof(ioc_fm_pcd_manip_stats_t));
117723 + }
117724 +
117725 + _fm_cpt_dbg (compat, " ...->}\n");
117726 +}
117727 +
117728 +#if (DPAA_VERSION >= 11)
117729 +void compat_copy_fm_pcd_frm_replic_group_params(
117730 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117731 + ioc_fm_pcd_frm_replic_group_params_t *param,
117732 + uint8_t compat)
117733 +{
117734 + int k;
117735 +
117736 + _fm_cpt_dbg (compat, " {->...\n");
117737 +
117738 + if (compat == COMPAT_US_TO_K)
117739 + {
117740 + param->max_num_of_entries = compat_param->max_num_of_entries;
117741 + param->num_of_entries = compat_param->num_of_entries;
117742 + param->id = compat_pcd_id2ptr(compat_param->id);
117743 + }
117744 + else
117745 + {
117746 + compat_param->max_num_of_entries = param->max_num_of_entries;
117747 + compat_param->num_of_entries = param->num_of_entries;
117748 + compat_param->id = compat_add_ptr2id(param->id,
117749 + FM_MAP_TYPE_PCD_NODE);
117750 + }
117751 +
117752 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117753 + compat_copy_fm_pcd_cc_next_engine(
117754 + &compat_param->next_engine_params[k],
117755 + &param->next_engine_params[k],
117756 + compat);
117757 +
117758 + _fm_cpt_dbg (compat, " ...->}\n");
117759 +}
117760 +
117761 +void compat_copy_fm_pcd_frm_replic_member(
117762 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117763 + ioc_fm_pcd_frm_replic_member_t *param,
117764 + uint8_t compat)
117765 +{
117766 + _fm_cpt_dbg (compat, " {->...\n");
117767 +
117768 + if (compat == COMPAT_US_TO_K)
117769 + {
117770 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117771 + param->member_index = compat_param->member_index;
117772 + }
117773 +
117774 + _fm_cpt_dbg (compat, " ...->}\n");
117775 +}
117776 +
117777 +void compat_copy_fm_pcd_frm_replic_member_params(
117778 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117779 + ioc_fm_pcd_frm_replic_member_params_t *param,
117780 + uint8_t compat)
117781 +{
117782 + _fm_cpt_dbg (compat, " {->...\n");
117783 +
117784 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117785 + &param->member, compat);
117786 +
117787 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117788 + &param->next_engine_params, compat);
117789 +
117790 + _fm_cpt_dbg (compat, " ...->}\n");
117791 +}
117792 +
117793 +void compat_copy_fm_vsp_params(
117794 + ioc_compat_fm_vsp_params_t *compat_param,
117795 + ioc_fm_vsp_params_t *param,
117796 + uint8_t compat)
117797 +{
117798 + _fm_cpt_dbg (compat, " {->...\n");
117799 +
117800 + if (compat == COMPAT_US_TO_K)
117801 + {
117802 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117803 + param->liodn_offset = compat_param->liodn_offset;
117804 + param->port_params.port_id = compat_param->port_params.port_id;
117805 + param->port_params.port_type = compat_param->port_params.port_type;
117806 + param->relative_profile_id = compat_param->relative_profile_id;
117807 + }
117808 + else
117809 + {
117810 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117811 + compat_param->liodn_offset = param->liodn_offset;
117812 + compat_param->port_params.port_id = param->port_params.port_id;
117813 + compat_param->port_params.port_type = param->port_params.port_type;
117814 + compat_param->relative_profile_id = param->relative_profile_id;
117815 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117816 + }
117817 +
117818 + _fm_cpt_dbg (compat, " ...->}\n");
117819 +}
117820 +
117821 +void compat_copy_fm_buf_pool_depletion_params(
117822 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
117823 + ioc_fm_buf_pool_depletion_params_t *param,
117824 + uint8_t compat)
117825 +{
117826 + _fm_cpt_dbg (compat, " {->...\n");
117827 +
117828 + if (compat == COMPAT_US_TO_K)
117829 + {
117830 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117831 + memcpy(&param->fm_buf_pool_depletion,
117832 + &compat_param->fm_buf_pool_depletion,
117833 + sizeof(ioc_fm_buf_pool_depletion_t));
117834 + }
117835 +
117836 + _fm_cpt_dbg (compat, " ...->}\n");
117837 +}
117838 +
117839 +void compat_copy_fm_buffer_prefix_content_params(
117840 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
117841 + ioc_fm_buffer_prefix_content_params_t *param,
117842 + uint8_t compat)
117843 +{
117844 + _fm_cpt_dbg (compat, " {->...\n");
117845 +
117846 + if (compat == COMPAT_US_TO_K)
117847 + {
117848 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117849 + memcpy(&param->fm_buffer_prefix_content,
117850 + &compat_param->fm_buffer_prefix_content,
117851 + sizeof(ioc_fm_buffer_prefix_content_t));
117852 + }
117853 +
117854 + _fm_cpt_dbg (compat, " ...->}\n");
117855 +}
117856 +
117857 +void compat_copy_fm_vsp_config_no_sg_params(
117858 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
117859 + ioc_fm_vsp_config_no_sg_params_t *param,
117860 + uint8_t compat)
117861 +{
117862 + _fm_cpt_dbg (compat, " {->...\n");
117863 +
117864 + if (compat == COMPAT_US_TO_K)
117865 + {
117866 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117867 + param->no_sg = compat_param->no_sg;
117868 + }
117869 +
117870 + _fm_cpt_dbg (compat, " ...->}\n");
117871 +}
117872 +
117873 +void compat_copy_fm_vsp_prs_result_params(
117874 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
117875 + ioc_fm_vsp_prs_result_params_t *param,
117876 + uint8_t compat)
117877 +{
117878 + _fm_cpt_dbg (compat, " {->...\n");
117879 +
117880 + if (compat == COMPAT_US_TO_K)
117881 + {
117882 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117883 + /* p_data is an user-space pointer that needs to remain unmodified */
117884 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
117885 + }
117886 + else
117887 + {
117888 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
117889 + /* p_data is an user-space pointer that needs to remain unmodified */
117890 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
117891 + }
117892 +
117893 + _fm_cpt_dbg (compat, " ...->}\n");
117894 +}
117895 +#endif /* (DPAA_VERSION >= 11) */
117896 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117897 new file mode 100644
117898 index 00000000..187011f7
117899 --- /dev/null
117900 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117901 @@ -0,0 +1,755 @@
117902 +/*
117903 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117904 + *
117905 + * Redistribution and use in source and binary forms, with or without
117906 + * modification, are permitted provided that the following conditions are met:
117907 + * * Redistributions of source code must retain the above copyright
117908 + * notice, this list of conditions and the following disclaimer.
117909 + * * Redistributions in binary form must reproduce the above copyright
117910 + * notice, this list of conditions and the following disclaimer in the
117911 + * documentation and/or other materials provided with the distribution.
117912 + * * Neither the name of Freescale Semiconductor nor the
117913 + * names of its contributors may be used to endorse or promote products
117914 + * derived from this software without specific prior written permission.
117915 + *
117916 + *
117917 + * ALTERNATIVELY, this software may be distributed under the terms of the
117918 + * GNU General Public License ("GPL") as published by the Free Software
117919 + * Foundation, either version 2 of that License or (at your option) any
117920 + * later version.
117921 + *
117922 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117923 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117924 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117925 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117926 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117927 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117928 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117930 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117931 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117932 + */
117933 +
117934 +/*
117935 + @File lnxwrp_ioctls_fm_compat.h
117936 +
117937 + @Description FM PCD compat structures definition.
117938 +
117939 +*/
117940 +
117941 +#ifndef __FM_COMPAT_IOCTLS_H
117942 +#define __FM_COMPAT_IOCTLS_H
117943 +
117944 +#include <linux/compat.h>
117945 +
117946 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
117947 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
117948 +#define COMPAT_GENERIC 2
117949 +
117950 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
117951 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
117952 +
117953 +/* mapping kernel pointers w/ UserSpace id's { */
117954 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
117955 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
117956 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
117957 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
117958 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
117959 +
117960 +/* define it for debug trace */
117961 +/*#define FM_COMPAT_DBG*/
117962 +
117963 +#define _fm_cpt_prk(stage, format, arg...) \
117964 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
117965 +
117966 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
117967 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
117968 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
117969 +
117970 +/* used for compat IOCTL debugging */
117971 +#if defined(FM_COMPAT_DBG)
117972 + #define _fm_cpt_dbg(from, format, arg...) \
117973 + do{ \
117974 + if (from == COMPAT_US_TO_K) \
117975 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
117976 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117977 + else if (from == COMPAT_K_TO_US) \
117978 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
117979 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117980 + else \
117981 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
117982 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117983 + }while(0)
117984 +#else
117985 +# define _fm_cpt_dbg(arg...)
117986 +#endif
117987 +
117988 +/*TODO: per FMan module:
117989 + *
117990 + * Parser: FM_MAP_TYPE_PARSER_NODE,
117991 + * Kg: FM_MAP_TYPE_KG_NODE,
117992 + * Policer: FM_MAP_TYPE_POLICER_NODE
117993 + * Manip: FM_MAP_TYPE_MANIP_NODE
117994 + **/
117995 +enum fm_map_node_type {
117996 + FM_MAP_TYPE_UNSPEC = 0,
117997 + FM_MAP_TYPE_PCD_NODE,
117998 +
117999 + /* add types here, update the policy */
118000 +
118001 + __FM_MAP_TYPE_AFTER_LAST,
118002 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
118003 +};
118004 +
118005 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
118006 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
118007 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
118008 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
118009 +
118010 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
118011 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
118012 + : (compat_uptr_t) 0;
118013 +}
118014 +
118015 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
118016 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
118017 + : NULL;
118018 +}
118019 +
118020 +/* other similar inlines may be added as new nodes are added
118021 + to enum fm_map_node_type above... */
118022 +/* } mapping kernel pointers w/ UserSpace id's */
118023 +
118024 +/* pcd compat structures { */
118025 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
118026 + compat_uptr_t id;
118027 + uint16_t key_indx;
118028 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
118029 +
118030 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
118031 + ioc_fm_pcd_done_action action;
118032 + compat_uptr_t p_profile;
118033 + compat_uptr_t p_direct_scheme;
118034 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
118035 +
118036 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
118037 + bool modify;
118038 + union {
118039 + struct {
118040 + ioc_fm_pcd_profile_type_selection profile_type;
118041 + compat_uptr_t p_fm_port;
118042 + uint16_t relative_profile_id;
118043 + } new_params;
118044 + compat_uptr_t p_profile;
118045 + } profile_select;
118046 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
118047 + ioc_fm_pcd_plcr_color_mode color_mode;
118048 +
118049 + union {
118050 + ioc_fm_pcd_plcr_color dflt_color;
118051 + ioc_fm_pcd_plcr_color override;
118052 + } color;
118053 +
118054 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
118055 +
118056 + ioc_fm_pcd_engine next_engine_on_green;
118057 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
118058 +
118059 + ioc_fm_pcd_engine next_engine_on_yellow;
118060 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
118061 +
118062 + ioc_fm_pcd_engine next_engine_on_red;
118063 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
118064 +
118065 + bool trap_profile_on_flow_A;
118066 + bool trap_profile_on_flow_B;
118067 + bool trap_profile_on_flow_C;
118068 + compat_uptr_t id;
118069 +} ioc_compat_fm_pcd_plcr_profile_params_t;
118070 +
118071 +typedef struct ioc_compat_fm_obj_t {
118072 + compat_uptr_t obj;
118073 +} ioc_compat_fm_obj_t;
118074 +
118075 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
118076 + bool direct;
118077 + compat_uptr_t scheme_id;
118078 +} ioc_compat_fm_pcd_kg_scheme_select_t;
118079 +
118080 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
118081 + uint8_t num_of_schemes;
118082 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
118083 +} ioc_compat_fm_pcd_port_schemes_params_t;
118084 +
118085 +#if (DPAA_VERSION >= 11)
118086 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
118087 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
118088 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
118089 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
118090 + if relevant function called for Rx port */
118091 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
118092 +}ioc_compat_fm_port_vsp_alloc_params_t;
118093 +#endif /* (DPAA_VERSION >= 11) */
118094 +
118095 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
118096 + uint8_t num_of_distinction_units;
118097 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
118098 + compat_uptr_t id;
118099 +} ioc_compat_fm_pcd_net_env_params_t;
118100 +
118101 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
118102 + bool override;
118103 + uint32_t size;
118104 + uint16_t base;
118105 + compat_uptr_t p_code;
118106 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
118107 + uint8_t num_of_labels;
118108 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
118109 +} ioc_compat_fm_pcd_prs_sw_params_t;
118110 +
118111 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
118112 + bool override_fqid;
118113 + uint32_t new_fqid;
118114 +#if DPAA_VERSION >= 11
118115 + uint8_t new_relative_storage_profile_id;
118116 +#endif
118117 + compat_uptr_t p_direct_scheme;
118118 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
118119 +
118120 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
118121 + compat_uptr_t cc_node_id;
118122 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
118123 +
118124 +#if DPAA_VERSION >= 11
118125 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
118126 + compat_uptr_t frm_replic_id;
118127 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
118128 +#endif /* DPAA_VERSION >= 11 */
118129 +
118130 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
118131 + ioc_fm_pcd_engine next_engine;
118132 + union {
118133 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
118134 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
118135 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
118136 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
118137 +#if DPAA_VERSION >= 11
118138 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
118139 +#endif /* DPAA_VERSION >= 11 */
118140 + } params;
118141 + compat_uptr_t manip_id;
118142 + bool statistics_en;
118143 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
118144 +
118145 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
118146 + uint8_t num_of_distinction_units;
118147 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
118148 + 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];
118149 +} ioc_compat_fm_pcd_cc_grp_params_t;
118150 +
118151 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
118152 + compat_uptr_t net_env_id;
118153 + uint8_t num_of_groups;
118154 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
118155 + compat_uptr_t id;
118156 +} ioc_compat_fm_pcd_cc_tree_params_t;
118157 +
118158 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
118159 + compat_uptr_t id;
118160 + uint8_t grp_indx;
118161 + uint8_t indx;
118162 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118163 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
118164 +
118165 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
118166 + compat_uptr_t p_key;
118167 + compat_uptr_t p_mask;
118168 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
118169 +} ioc_compat_fm_pcd_cc_key_params_t;
118170 +
118171 +typedef struct ioc_compat_keys_params_t {
118172 + uint16_t max_num_of_keys;
118173 + bool mask_support;
118174 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118175 +#if (DPAA_VERSION >= 11)
118176 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
118177 +#endif /* (DPAA_VERSION >= 11) */
118178 + uint16_t num_of_keys;
118179 + uint8_t key_size;
118180 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
118181 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
118182 +} ioc_compat_keys_params_t;
118183 +
118184 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
118185 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
118186 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
118187 + compat_uptr_t id;
118188 +} ioc_compat_fm_pcd_cc_node_params_t;
118189 +
118190 +/**************************************************************************//**
118191 + @Description Parameters for defining a hash table
118192 +*//***************************************************************************/
118193 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
118194 + uint16_t max_num_of_keys;
118195 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118196 + uint8_t kg_hash_shift;
118197 + uint16_t hash_res_mask;
118198 + uint8_t hash_shift;
118199 + uint8_t match_key_size;
118200 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
118201 + compat_uptr_t id;
118202 +} ioc_compat_fm_pcd_hash_table_params_t;
118203 +
118204 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
118205 + compat_uptr_t p_hash_tbl;
118206 + uint8_t key_size;
118207 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118208 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
118209 +
118210 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
118211 + compat_uptr_t id;
118212 + uint16_t key_indx;
118213 + uint8_t key_size;
118214 + compat_uptr_t p_key;
118215 + compat_uptr_t p_mask;
118216 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
118217 +
118218 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
118219 + compat_uptr_t p_hash_tbl;
118220 + uint8_t key_size;
118221 + compat_uptr_t p_key;
118222 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
118223 +
118224 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
118225 + compat_uptr_t id;
118226 + uint16_t key_indx;
118227 + uint8_t key_size;
118228 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118229 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
118230 +
118231 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
118232 + compat_uptr_t plcr_profile_id;
118233 +} ioc_compat_fm_port_pcd_plcr_params_t;
118234 +
118235 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
118236 + compat_uptr_t cc_tree_id;
118237 +} ioc_compat_fm_port_pcd_cc_params_t;
118238 +
118239 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
118240 + uint8_t num_of_schemes;
118241 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
118242 + bool direct_scheme;
118243 + compat_uptr_t direct_scheme_id;
118244 +} ioc_compat_fm_port_pcd_kg_params_t;
118245 +
118246 +typedef struct ioc_compat_fm_port_pcd_params_t {
118247 + ioc_fm_port_pcd_support pcd_support;
118248 + compat_uptr_t net_env_id;
118249 + compat_uptr_t p_prs_params;
118250 + compat_uptr_t p_cc_params;
118251 + compat_uptr_t p_kg_params;
118252 + compat_uptr_t p_plcr_params;
118253 + compat_uptr_t p_ip_reassembly_manip;
118254 +#if DPAA_VERSION >= 11
118255 + compat_uptr_t p_capwap_reassembly_manip;
118256 +#endif
118257 +} ioc_compat_fm_port_pcd_params_t;
118258 +
118259 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
118260 + compat_uptr_t tree_id;
118261 + uint8_t grp_id;
118262 + bool plcr_next;
118263 + bool bypass_plcr_profile_generation;
118264 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118265 +} ioc_compat_fm_pcd_kg_cc_t;
118266 +
118267 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
118268 + bool modify;
118269 + union {
118270 + uint8_t relative_scheme_id;
118271 + compat_uptr_t scheme_id;
118272 + } scm_id;
118273 + bool always_direct;
118274 + struct {
118275 + compat_uptr_t net_env_id;
118276 + uint8_t num_of_distinction_units;
118277 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
118278 + } net_env_params;
118279 + bool use_hash;
118280 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
118281 + bool bypass_fqid_generation;
118282 + uint32_t base_fqid;
118283 + uint8_t num_of_used_extracted_ors;
118284 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
118285 +#if DPAA_VERSION >= 11
118286 + bool override_storage_profile;
118287 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
118288 +#endif /* DPAA_VERSION >= 11 */
118289 + ioc_fm_pcd_engine next_engine;
118290 + union{
118291 + ioc_fm_pcd_done_action done_action;
118292 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118293 + ioc_compat_fm_pcd_kg_cc_t cc;
118294 + } kg_next_engine_params;
118295 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
118296 + compat_uptr_t id;
118297 +} ioc_compat_fm_pcd_kg_scheme_params_t;
118298 +
118299 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
118300 + compat_uptr_t id;
118301 + uint16_t key_indx;
118302 + uint8_t key_size;
118303 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118304 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
118305 +
118306 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
118307 + uint8_t offset;
118308 + uint8_t size;
118309 + bool replace;
118310 + compat_uptr_t p_data;
118311 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
118312 +
118313 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
118314 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
118315 + bool update;
118316 + uint8_t size;
118317 + compat_uptr_t p_data;
118318 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
118319 +
118320 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
118321 + uint8_t size; /**< size of inserted section */
118322 + compat_uptr_t p_data; /**< data to be inserted */
118323 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
118324 +
118325 +#if (DPAA_VERSION >= 11)
118326 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
118327 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
118328 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
118329 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
118330 + the inserted header */
118331 + uint16_t id; /**< 16 bit New IP ID */
118332 + bool dont_frag_overwrite;
118333 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
118334 + * This byte is configured to be overwritten when RPD is set. */
118335 + uint8_t last_dst_offset;
118336 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
118337 + * in order to calculate UDP checksum pseudo header;
118338 + * Otherwise set it to '0'. */
118339 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
118340 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
118341 +#endif /* (DPAA_VERSION >= 11) */
118342 +
118343 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
118344 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
118345 + union {
118346 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
118347 +#if (DPAA_VERSION >= 11)
118348 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
118349 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
118350 +#endif /* (DPAA_VERSION >= 11) */
118351 + } u;
118352 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
118353 +
118354 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
118355 + ioc_fm_pcd_manip_hdr_insrt_type type;
118356 + union {
118357 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
118358 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
118359 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118360 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118361 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
118362 +#endif /* FM_CAPWAP_SUPPORT */
118363 + } u;
118364 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
118365 +
118366 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
118367 + bool rmv;
118368 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
118369 + bool insrt;
118370 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
118371 + bool field_update;
118372 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
118373 + bool custom;
118374 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
118375 + bool dont_parse_after_manip;
118376 +} ioc_compat_fm_pcd_manip_hdr_params_t;
118377 +
118378 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
118379 + bool decryption;
118380 + bool ecn_copy;
118381 + bool dscp_copy;
118382 + bool variable_ip_hdr_len;
118383 + bool variable_ip_version;
118384 + uint8_t outer_ip_hdr_len;
118385 + uint16_t arw_size;
118386 + compat_uptr_t arw_addr;
118387 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
118388 +
118389 +typedef struct ioc_compat_fm_pcd_manip_params_t {
118390 + ioc_fm_pcd_manip_type type;
118391 + union {
118392 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
118393 + ioc_fm_pcd_manip_reassem_params_t reassem;
118394 + ioc_fm_pcd_manip_frag_params_t frag;
118395 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
118396 + } u;
118397 + compat_uptr_t p_next_manip;
118398 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118399 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118400 + bool frag_or_reasm;
118401 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
118402 +#endif /* FM_CAPWAP_SUPPORT */
118403 + compat_uptr_t id;
118404 +} ioc_compat_fm_pcd_manip_params_t;
118405 +
118406 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
118407 + compat_uptr_t id;
118408 + ioc_fm_pcd_manip_stats_t stats;
118409 +} ioc_compat_fm_pcd_manip_get_stats_t;
118410 +
118411 +#if (DPAA_VERSION >= 11)
118412 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
118413 + uint8_t max_num_of_entries;
118414 + uint8_t num_of_entries;
118415 + ioc_compat_fm_pcd_cc_next_engine_params_t
118416 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
118417 + compat_uptr_t id;
118418 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
118419 +
118420 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
118421 + compat_uptr_t h_replic_group;
118422 + uint16_t member_index;
118423 +} ioc_compat_fm_pcd_frm_replic_member_t;
118424 +
118425 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
118426 + ioc_compat_fm_pcd_frm_replic_member_t member;
118427 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
118428 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
118429 +
118430 +typedef struct ioc_compat_fm_vsp_params_t {
118431 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
118432 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
118433 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
118434 + parameter associated with Rx / OP port */
118435 + uint16_t liodn_offset; /**< VSP's LIODN offset */
118436 + struct {
118437 + ioc_fm_port_type port_type; /**< Port type */
118438 + uint8_t port_id; /**< Port Id - relative to type */
118439 + } port_params;
118440 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
118441 + defined in relevant FM object */
118442 + compat_uptr_t id; /**< return value */
118443 +} ioc_compat_fm_vsp_params_t;
118444 +
118445 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
118446 + compat_uptr_t p_fm_vsp;
118447 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
118448 +} ioc_compat_fm_buf_pool_depletion_params_t;
118449 +
118450 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
118451 + compat_uptr_t p_fm_vsp;
118452 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
118453 +} ioc_compat_fm_buffer_prefix_content_params_t;
118454 +
118455 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
118456 + compat_uptr_t p_fm_vsp;
118457 + bool no_sg;
118458 +} ioc_compat_fm_vsp_config_no_sg_params_t;
118459 +
118460 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
118461 + compat_uptr_t p_fm_vsp;
118462 + compat_uptr_t p_data;
118463 +} ioc_compat_fm_vsp_prs_result_params_t;
118464 +
118465 +#endif /* (DPAA_VERSION >= 11) */
118466 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
118467 + uint32_t val;
118468 + compat_uptr_t id;
118469 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
118470 +
118471 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
118472 + uint8_t fm_ctrl_index;
118473 + compat_uptr_t p_mon;
118474 +} ioc_compat_fm_ctrl_mon_counters_params_t;
118475 +
118476 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
118477 + compat_uptr_t id;
118478 + uint16_t key_index;
118479 + ioc_fm_pcd_cc_key_statistics_t statistics;
118480 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
118481 +
118482 +
118483 +/* } pcd compat structures */
118484 +
118485 +void compat_obj_delete(
118486 + ioc_compat_fm_obj_t *compat_id,
118487 + ioc_fm_obj_t *id);
118488 +
118489 +/* pcd compat functions { */
118490 +void compat_copy_fm_pcd_plcr_profile(
118491 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118492 + ioc_fm_pcd_plcr_profile_params_t *param,
118493 + uint8_t compat);
118494 +
118495 +void compat_copy_fm_pcd_cc_key(
118496 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118497 + ioc_fm_pcd_cc_key_params_t *param,
118498 + uint8_t compat);
118499 +
118500 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118501 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118502 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118503 + uint8_t compat);
118504 +
118505 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118506 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118507 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118508 + uint8_t compat);
118509 +
118510 +void compat_fm_pcd_cc_tree_modify_next_engine(
118511 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118512 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118513 + uint8_t compat);
118514 +
118515 +void compat_copy_fm_pcd_hash_table(
118516 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118517 + ioc_fm_pcd_hash_table_params_t *param,
118518 + uint8_t compat);
118519 +
118520 +void compat_copy_fm_pcd_cc_grp(
118521 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118522 + ioc_fm_pcd_cc_grp_params_t *param,
118523 + uint8_t compat);
118524 +
118525 +void compat_copy_fm_pcd_cc_tree(
118526 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118527 + ioc_fm_pcd_cc_tree_params_t *param,
118528 + uint8_t compat);
118529 +
118530 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118531 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118532 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118533 + uint8_t compat);
118534 +
118535 +void compat_fm_pcd_prs_sw(
118536 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118537 + ioc_fm_pcd_prs_sw_params_t *param,
118538 + uint8_t compat);
118539 +
118540 +void compat_copy_fm_pcd_kg_scheme(
118541 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118542 + ioc_fm_pcd_kg_scheme_params_t *param,
118543 + uint8_t compat);
118544 +
118545 +void compat_copy_fm_pcd_kg_scheme_select(
118546 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118547 + ioc_fm_pcd_kg_scheme_select_t *param,
118548 + uint8_t compat);
118549 +
118550 +void compat_copy_fm_pcd_kg_schemes_params(
118551 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118552 + ioc_fm_pcd_port_schemes_params_t *param,
118553 + uint8_t compat);
118554 +
118555 +void compat_copy_fm_port_pcd_kg(
118556 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118557 + ioc_fm_port_pcd_kg_params_t *param,
118558 + uint8_t compat);
118559 +
118560 +void compat_copy_fm_port_pcd(
118561 + ioc_compat_fm_port_pcd_params_t *compat_param,
118562 + ioc_fm_port_pcd_params_t *param,
118563 + uint8_t compat);
118564 +
118565 +#if (DPAA_VERSION >= 11)
118566 +void compat_copy_fm_port_vsp_alloc_params(
118567 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118568 + ioc_fm_port_vsp_alloc_params_t *param,
118569 + uint8_t compat);
118570 +#endif /* (DPAA_VERSION >= 11) */
118571 +
118572 +void compat_copy_fm_pcd_net_env(
118573 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118574 + ioc_fm_pcd_net_env_params_t *param,
118575 + uint8_t compat);
118576 +
118577 +void compat_copy_fm_pcd_cc_node_modify_key(
118578 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118579 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118580 + uint8_t compat);
118581 +
118582 +void compat_copy_keys(
118583 + ioc_compat_keys_params_t *compat_param,
118584 + ioc_keys_params_t *param,
118585 + uint8_t compat);
118586 +
118587 +void compat_copy_fm_pcd_cc_node(
118588 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118589 + ioc_fm_pcd_cc_node_params_t *param,
118590 + uint8_t compat);
118591 +
118592 +void compat_fm_pcd_manip_set_node(
118593 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118594 + ioc_fm_pcd_manip_params_t *param,
118595 + uint8_t compat);
118596 +
118597 +void compat_copy_fm_pcd_manip_get_stats(
118598 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118599 + ioc_fm_pcd_manip_get_stats_t *param,
118600 + uint8_t compat);
118601 +
118602 +void compat_copy_fm_port_pcd_modify_tree(
118603 + ioc_compat_fm_obj_t *compat_id,
118604 + ioc_fm_obj_t *id,
118605 + uint8_t compat);
118606 +
118607 +#if (DPAA_VERSION >= 11)
118608 +void compat_copy_fm_pcd_frm_replic_group_params(
118609 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118610 + ioc_fm_pcd_frm_replic_group_params_t *param,
118611 + uint8_t compat);
118612 +
118613 +void compat_copy_fm_pcd_frm_replic_member(
118614 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118615 + ioc_fm_pcd_frm_replic_member_t *param,
118616 + uint8_t compat);
118617 +
118618 +void compat_copy_fm_pcd_frm_replic_member_params(
118619 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118620 + ioc_fm_pcd_frm_replic_member_params_t *param,
118621 + uint8_t compat);
118622 +
118623 +void compat_copy_fm_vsp_params(
118624 + ioc_compat_fm_vsp_params_t *compat_param,
118625 + ioc_fm_vsp_params_t *param,
118626 + uint8_t compat);
118627 +
118628 +void compat_copy_fm_buf_pool_depletion_params(
118629 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118630 + ioc_fm_buf_pool_depletion_params_t *param,
118631 + uint8_t compat);
118632 +
118633 +void compat_copy_fm_buffer_prefix_content_params(
118634 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118635 + ioc_fm_buffer_prefix_content_params_t *param,
118636 + uint8_t compat);
118637 +
118638 +void compat_copy_fm_vsp_config_no_sg_params(
118639 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118640 + ioc_fm_vsp_config_no_sg_params_t *param,
118641 + uint8_t compat);
118642 +
118643 +void compat_copy_fm_vsp_prs_result_params(
118644 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118645 + ioc_fm_vsp_prs_result_params_t *param,
118646 + uint8_t compat);
118647 +
118648 +#endif /* (DPAA_VERSION >= 11) */
118649 +
118650 +void compat_copy_fm_pcd_kg_scheme_spc(
118651 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118652 + ioc_fm_pcd_kg_scheme_spc_t *param,
118653 + uint8_t compat);
118654 +
118655 +/* } pcd compat functions */
118656 +#endif
118657 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118658 new file mode 100644
118659 index 00000000..1b72e1d5
118660 --- /dev/null
118661 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118662 @@ -0,0 +1,121 @@
118663 +/*
118664 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118665 + *
118666 + * Redistribution and use in source and binary forms, with or without
118667 + * modification, are permitted provided that the following conditions are met:
118668 + * * Redistributions of source code must retain the above copyright
118669 + * notice, this list of conditions and the following disclaimer.
118670 + * * Redistributions in binary form must reproduce the above copyright
118671 + * notice, this list of conditions and the following disclaimer in the
118672 + * documentation and/or other materials provided with the distribution.
118673 + * * Neither the name of Freescale Semiconductor nor the
118674 + * names of its contributors may be used to endorse or promote products
118675 + * derived from this software without specific prior written permission.
118676 + *
118677 + *
118678 + * ALTERNATIVELY, this software may be distributed under the terms of the
118679 + * GNU General Public License ("GPL") as published by the Free Software
118680 + * Foundation, either version 2 of that License or (at your option) any
118681 + * later version.
118682 + *
118683 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118684 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118685 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118686 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118687 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118688 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118689 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118690 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118691 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118692 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118693 + */
118694 +
118695 +/*
118696 + @File lnxwrp_resources.h
118697 +
118698 + @Description FMD wrapper resource allocation functions.
118699 +
118700 +*/
118701 +
118702 +#ifndef LNXWRP_RESOURCES_H_
118703 +#define LNXWRP_RESOURCES_H_
118704 +
118705 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118706 +#include "lnxwrp_fm.h"
118707 +#else
118708 +#include "lnxwrp_resources_ut.h"
118709 +#endif
118710 +
118711 +#define ROUND(X) ((2*(X)+1)/2)
118712 +#define CEIL(X) ((X)+1)
118713 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118714 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118715 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118716 +
118717 +/* used for resource calculus */
118718 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118719 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118720 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118721 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118722 +
118723 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118724 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118725 +
118726 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118727 + * value and s/g software support (! Kernel does not suport s/g).
118728 + *
118729 + * Algorithm summary:
118730 + * - Calculate the the minimum fifosize required for every type of port
118731 + * (TX,RX for 1G, 2.5G and 10G).
118732 + * - Set TX the minimum fifosize required.
118733 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118734 + * based on:
118735 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118736 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118737 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118738 + * - if the RX is smaller than the minimum required, then set the minimum
118739 + * required
118740 + * - In the end distribuite the leftovers if there are any (due to
118741 + * unprecise calculus) or if over allocation cat some buffers from all RX
118742 + * ports w/o pass over minimum required treshold, but if there must be
118743 + * pass the treshold in order to cat the over allocation ,then this
118744 + * configuration can not be set - KERN_ALERT.
118745 +*/
118746 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118747 + int muram_fifo_size);
118748 +
118749 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118750 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118751 +#endif
118752 +
118753 +/* Compute FMan open DMA based on total number of open DMAs and
118754 + * number of available fman ports.
118755 + *
118756 + * By default 10g ports are set to input parameters. The other ports
118757 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118758 + *
118759 + * If leftovers, then those will be set as shared.
118760 + *
118761 + * If after computing overflow appears, then it decrements open dma
118762 + * for all ports w/o cross the tresholds. If the tresholds are meet
118763 + * and is still overflow, then it returns error.
118764 +*/
118765 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118766 + int max_fm_open_dma,
118767 + int default_tx_10g_dmas,
118768 + int default_rx_10g_dmas,
118769 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118770 +
118771 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118772 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118773 +#endif
118774 +
118775 +/* Compute FMan tnums based on available tnums and number of ports.
118776 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118777 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118778 +
118779 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118780 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118781 +#endif
118782 +
118783 +#endif /* LNXWRP_RESOURCES_H_ */
118784 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118785 new file mode 100644
118786 index 00000000..6c06a5a6
118787 --- /dev/null
118788 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118789 @@ -0,0 +1,191 @@
118790 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118791 + * All rights reserved.
118792 + *
118793 + * Redistribution and use in source and binary forms, with or without
118794 + * modification, are permitted provided that the following conditions are met:
118795 + * * Redistributions of source code must retain the above copyright
118796 + * notice, this list of conditions and the following disclaimer.
118797 + * * Redistributions in binary form must reproduce the above copyright
118798 + * notice, this list of conditions and the following disclaimer in the
118799 + * documentation and/or other materials provided with the distribution.
118800 + * * Neither the name of Freescale Semiconductor nor the
118801 + * names of its contributors may be used to endorse or promote products
118802 + * derived from this software without specific prior written permission.
118803 + *
118804 + *
118805 + * ALTERNATIVELY, this software may be distributed under the terms of the
118806 + * GNU General Public License ("GPL") as published by the Free Software
118807 + * Foundation, either version 2 of that License or (at your option) any
118808 + * later version.
118809 + *
118810 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118811 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118812 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118813 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118814 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118815 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118816 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118817 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118818 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118819 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118820 + */
118821 +
118822 +#include "lnxwrp_resources.h"
118823 +#include "lnxwrp_resources_ut.h"
118824 +
118825 +#define KILOBYTE 0x400 /* 1024 */
118826 +
118827 +typedef enum e_board_type {
118828 + e_p3041,
118829 + e_p4080,
118830 + e_p5020,
118831 + e_p1023
118832 +} e_board_type;
118833 +
118834 +uint8_t board_type;
118835 +uint32_t muram_size = 0;
118836 +uint32_t dmas_num = 0;
118837 +uint32_t task_num = 0;
118838 +uint32_t frame_size = 0;
118839 +uint32_t oh_num = 0;
118840 +uint32_t num_ports_1g = 0;
118841 +uint32_t num_ports_10g = 0;
118842 +uint32_t num_ports_2g5 = 0;
118843 +uint32_t fsl_fman_phy_maxfrm = 0;
118844 +uint32_t dpa_rx_extra_headroom = 0;
118845 +
118846 +void show_help(void){
118847 + printf(" help: \n");
118848 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
118849 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
118850 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
118851 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
118852 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
118853 + printf(" Number of ports:\n");
118854 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
118855 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
118856 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
118857 + printf(" MTU: Default:1522, Jumbo:9600 \n");
118858 +}
118859 +
118860 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
118861 + struct fm_active_ports *fm_active_ports_info = NULL;
118862 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
118863 +
118864 + switch(board_type){
118865 + case e_p3041:
118866 + case e_p5020:
118867 + muram_size = 160*KILOBYTE;
118868 + dmas_num = 32;
118869 + task_num = 128;
118870 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
118871 + goto err_fm_set_param;
118872 + break;
118873 + case e_p4080:
118874 + muram_size = 160*KILOBYTE;
118875 + dmas_num = 32;
118876 + task_num = 128;
118877 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
118878 + goto err_fm_set_param;
118879 + break;
118880 + case e_p1023:
118881 + muram_size = 64*KILOBYTE;
118882 + dmas_num = 16;
118883 + task_num = 128;
118884 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
118885 + goto err_fm_set_param;
118886 + break;
118887 + default:
118888 + goto err_fm_set_param;
118889 + break;
118890 + }
118891 +
118892 + p_LnxWrpFmDev->id = 0;
118893 + fsl_fman_phy_maxfrm = frame_size;
118894 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
118895 + fm_active_ports_info->num_oh_ports = oh_num;
118896 + fm_active_ports_info->num_tx_ports = num_ports_1g;
118897 + fm_active_ports_info->num_rx_ports = num_ports_1g;
118898 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
118899 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
118900 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
118901 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
118902 +
118903 + return 0;
118904 +
118905 +err_fm_set_param:
118906 + printf(" ERR: To many ports!!! \n");
118907 + return -1;
118908 +}
118909 +
118910 +int main (int argc, char *argv[]){
118911 + t_LnxWrpFmDev LnxWrpFmDev;
118912 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
118913 + int tokens_cnt = 1;
118914 +
118915 + char *token = NULL;
118916 +
118917 + while(tokens_cnt < argc)
118918 + {
118919 + token = argv[tokens_cnt++];
118920 + if (strcmp(token, "-b") == 0){
118921 + if(strcmp(argv[tokens_cnt],"p3") == 0)
118922 + board_type = e_p3041;
118923 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
118924 + board_type = e_p4080;
118925 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
118926 + board_type = e_p5020;
118927 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
118928 + board_type = e_p1023;
118929 + else
118930 + show_help();
118931 + tokens_cnt++;
118932 + }
118933 + else if(strcmp(token, "-d") == 0){
118934 + dmas_num = atoi(argv[tokens_cnt++]);
118935 + }
118936 + else if(strcmp(token, "-t") == 0)
118937 + task_num = atoi(argv[tokens_cnt++]);
118938 + else if(strcmp(token, "-f") == 0)
118939 + frame_size = atoi(argv[tokens_cnt++]);
118940 + else if(strcmp(token, "-o") == 0)
118941 + oh_num = atoi(argv[tokens_cnt++]);
118942 + else if(strcmp(token, "-g1") == 0)
118943 + num_ports_1g = atoi(argv[tokens_cnt++]);
118944 + else if(strcmp(token, "-g10") == 0)
118945 + num_ports_10g = atoi(argv[tokens_cnt++]);
118946 + else if(strcmp(token, "-g25") == 0)
118947 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
118948 + else {
118949 + show_help();
118950 + return -1;
118951 + }
118952 + }
118953 +
118954 + if(fm_set_param(p_LnxWrpFmDev) < 0){
118955 + show_help();
118956 + return -1;
118957 + }
118958 +
118959 + if(fm_precalculate_fifosizes(
118960 + p_LnxWrpFmDev,
118961 + 128*KILOBYTE)
118962 + != 0)
118963 + return -1;
118964 + if(fm_precalculate_open_dma(
118965 + p_LnxWrpFmDev,
118966 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
118967 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
118968 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
118969 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
118970 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
118971 + != 0)
118972 + return -1;
118973 + if(fm_precalculate_tnums(
118974 + p_LnxWrpFmDev,
118975 + task_num) /* max TNUMS: dpa integration file. */
118976 + != 0)
118977 + return -1;
118978 +
118979 + return 0;
118980 +}
118981 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118982 new file mode 100644
118983 index 00000000..063946eb
118984 --- /dev/null
118985 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118986 @@ -0,0 +1,144 @@
118987 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
118988 + * All rights reserved.
118989 + *
118990 + * Redistribution and use in source and binary forms, with or without
118991 + * modification, are permitted provided that the following conditions are met:
118992 + * * Redistributions of source code must retain the above copyright
118993 + * notice, this list of conditions and the following disclaimer.
118994 + * * Redistributions in binary form must reproduce the above copyright
118995 + * notice, this list of conditions and the following disclaimer in the
118996 + * documentation and/or other materials provided with the distribution.
118997 + * * Neither the name of Freescale Semiconductor nor the
118998 + * names of its contributors may be used to endorse or promote products
118999 + * derived from this software without specific prior written permission.
119000 + *
119001 + *
119002 + * ALTERNATIVELY, this software may be distributed under the terms of the
119003 + * GNU General Public License ("GPL") as published by the Free Software
119004 + * Foundation, either version 2 of that License or (at your option) any
119005 + * later version.
119006 + *
119007 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119008 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119009 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119010 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119011 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119012 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119013 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119014 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119015 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119016 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119017 + */
119018 +
119019 +#ifndef FM_RESS_TEST_H_
119020 +#define FM_RESS_TEST_H_
119021 +
119022 +#include <stdint.h>
119023 +#include <stdbool.h>
119024 +#include <stdio.h>
119025 +#include <assert.h>
119026 +#include <string.h>
119027 +#include <stdlib.h>
119028 +
119029 +#define _Packed
119030 +#define _PackedType __attribute__ ((packed))
119031 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
119032 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
119033 +#define KERN_ALERT ""
119034 +#define KERN_INFO ""
119035 +#define ASSERT_COND assert
119036 +#define printk printf
119037 +#define NET_IP_ALIGN 0
119038 +#define FM_FIFO_ALLOCATION_OLD_ALG
119039 +
119040 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
119041 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
119042 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
119043 +#else
119044 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
119045 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
119046 +#endif
119047 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
119048 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
119049 +
119050 +/* information about all active ports for an FMan.
119051 + * !Some ports may be disabled by u-boot, thus will not be available */
119052 +struct fm_active_ports {
119053 + uint32_t num_oh_ports;
119054 + uint32_t num_tx_ports;
119055 + uint32_t num_rx_ports;
119056 + uint32_t num_tx25_ports;
119057 + uint32_t num_rx25_ports;
119058 + uint32_t num_tx10_ports;
119059 + uint32_t num_rx10_ports;
119060 +};
119061 +
119062 +/* FMan resources precalculated at fm probe based
119063 + * on available FMan port. */
119064 +struct fm_resource_settings {
119065 + /* buffers - fifo sizes */
119066 + uint32_t tx1g_num_buffers;
119067 + uint32_t rx1g_num_buffers;
119068 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
119069 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
119070 + uint32_t tx10g_num_buffers;
119071 + uint32_t rx10g_num_buffers;
119072 + uint32_t oh_num_buffers;
119073 + uint32_t shared_ext_buffers;
119074 +
119075 +
119076 + /* open DMAs */
119077 + uint32_t tx_1g_dmas;
119078 + uint32_t rx_1g_dmas;
119079 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
119080 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
119081 + uint32_t tx_10g_dmas;
119082 + uint32_t rx_10g_dmas;
119083 + uint32_t oh_dmas;
119084 + uint32_t shared_ext_open_dma;
119085 +
119086 + /* Tnums */
119087 + uint32_t tx_1g_tnums;
119088 + uint32_t rx_1g_tnums;
119089 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
119090 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
119091 + uint32_t tx_10g_tnums;
119092 + uint32_t rx_10g_tnums;
119093 + uint32_t oh_tnums;
119094 + uint32_t shared_ext_tnums;
119095 +};
119096 +
119097 +typedef struct {
119098 + uint8_t id;
119099 + struct fm_active_ports fm_active_ports_info;
119100 + struct fm_resource_settings fm_resource_settings_info;
119101 +} t_LnxWrpFmDev;
119102 +
119103 +typedef struct {
119104 + uint8_t id;
119105 +} t_LnxWrpFmPortDev;
119106 +
119107 +typedef _Packed struct t_FmPrsResult {
119108 + volatile uint8_t lpid; /**< Logical port id */
119109 + volatile uint8_t shimr; /**< Shim header result */
119110 + volatile uint16_t l2r; /**< Layer 2 result */
119111 + volatile uint16_t l3r; /**< Layer 3 result */
119112 + volatile uint8_t l4r; /**< Layer 4 result */
119113 + volatile uint8_t cplan; /**< Classification plan id */
119114 + volatile uint16_t nxthdr; /**< Next Header */
119115 + volatile uint16_t cksum; /**< Checksum */
119116 + volatile uint32_t lcv; /**< LCV */
119117 + volatile uint8_t shim_off[3]; /**< Shim offset */
119118 + volatile uint8_t eth_off; /**< ETH offset */
119119 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
119120 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
119121 + volatile uint8_t etype_off; /**< ETYPE offset */
119122 + volatile uint8_t pppoe_off; /**< PPP offset */
119123 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
119124 + volatile uint8_t ip_off[2]; /**< IP offset */
119125 + volatile uint8_t gre_off; /**< GRE offset */
119126 + volatile uint8_t l4_off; /**< Layer 4 offset */
119127 + volatile uint8_t nxthdr_off; /**< Parser end point */
119128 +} _PackedType t_FmPrsResult;
119129 +
119130 +#endif
119131 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
119132 new file mode 100644
119133 index 00000000..58009cd8
119134 --- /dev/null
119135 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
119136 @@ -0,0 +1,28 @@
119137 +CC=gcc
119138 +
119139 +LNXWRP_RESS_UT=lnxwrp_resources_ut
119140 +OBJ=lnxwrp_resources
119141 +
119142 +INC_PATH=
119143 +LIB_PATH=
119144 +
119145 +INC=$(addprefix -I,$(INC_PATH))
119146 +LIB=$(addprefix -L,$(LIB_PATH))
119147 +
119148 +CFLAGS= -gdwarf-2 -g -O0 -Wall
119149 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
119150 +
119151 +all: $(LNXWRP_RESS_UT)
119152 +
119153 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
119154 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
119155 +
119156 +%.o: %.c
119157 + @(echo " (CC) $@")
119158 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
119159 +
119160 +.PHONY: clean
119161 +
119162 +clean:
119163 + rm -f *.o
119164 + rm -f $(LNXWRP_RESS_UT)
119165 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
119166 new file mode 100644
119167 index 00000000..813771bf
119168 --- /dev/null
119169 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
119170 @@ -0,0 +1,60 @@
119171 +/*
119172 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119173 + *
119174 + * Redistribution and use in source and binary forms, with or without
119175 + * modification, are permitted provided that the following conditions are met:
119176 + * * Redistributions of source code must retain the above copyright
119177 + * notice, this list of conditions and the following disclaimer.
119178 + * * Redistributions in binary form must reproduce the above copyright
119179 + * notice, this list of conditions and the following disclaimer in the
119180 + * documentation and/or other materials provided with the distribution.
119181 + * * Neither the name of Freescale Semiconductor nor the
119182 + * names of its contributors may be used to endorse or promote products
119183 + * derived from this software without specific prior written permission.
119184 + *
119185 + *
119186 + * ALTERNATIVELY, this software may be distributed under the terms of the
119187 + * GNU General Public License ("GPL") as published by the Free Software
119188 + * Foundation, either version 2 of that License or (at your option) any
119189 + * later version.
119190 + *
119191 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119192 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119193 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119194 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119195 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119196 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119197 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119198 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119199 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119200 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119201 + */
119202 +
119203 +/*
119204 + @File lnxwrp_sysfs.c
119205 +
119206 + @Description FM wrapper sysfs related functions.
119207 +
119208 +*/
119209 +
119210 +#include <linux/types.h>
119211 +#include "lnxwrp_sysfs.h"
119212 +
119213 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119214 + const struct sysfs_stats_t *sysfs_stats,
119215 + uint8_t *offset)
119216 +{
119217 + int i = 0;
119218 +
119219 + while (sysfs_stats[i].stat_name != NULL) {
119220 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
119221 + if (offset != NULL)
119222 + *offset = i;
119223 + return sysfs_stats[i].stat_counter;
119224 + }
119225 +
119226 + i++;
119227 + }
119228 + WARN(1, "FMD: Should never get here!");
119229 + return 0;
119230 +}
119231 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
119232 new file mode 100644
119233 index 00000000..2098b244
119234 --- /dev/null
119235 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
119236 @@ -0,0 +1,60 @@
119237 +/*
119238 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119239 + *
119240 + * Redistribution and use in source and binary forms, with or without
119241 + * modification, are permitted provided that the following conditions are met:
119242 + * * Redistributions of source code must retain the above copyright
119243 + * notice, this list of conditions and the following disclaimer.
119244 + * * Redistributions in binary form must reproduce the above copyright
119245 + * notice, this list of conditions and the following disclaimer in the
119246 + * documentation and/or other materials provided with the distribution.
119247 + * * Neither the name of Freescale Semiconductor nor the
119248 + * names of its contributors may be used to endorse or promote products
119249 + * derived from this software without specific prior written permission.
119250 + *
119251 + *
119252 + * ALTERNATIVELY, this software may be distributed under the terms of the
119253 + * GNU General Public License ("GPL") as published by the Free Software
119254 + * Foundation, either version 2 of that License or (at your option) any
119255 + * later version.
119256 + *
119257 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119258 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119259 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119260 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119261 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119262 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119263 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119264 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119265 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119266 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119267 + */
119268 +
119269 +#ifndef LNXWRP_SYSFS_H_
119270 +#define LNXWRP_SYSFS_H_
119271 +
119272 +/* Linux Headers ------------------- */
119273 +#include <linux/version.h>
119274 +
119275 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
119276 +#define MODVERSIONS
119277 +#endif
119278 +#ifdef MODVERSIONS
119279 +#include <config/modversions.h>
119280 +#endif /* MODVERSIONS */
119281 +
119282 +#include <linux/kernel.h>
119283 +#include <linux/module.h>
119284 +#include <linux/device.h>
119285 +#include <linux/sysfs.h>
119286 +
119287 +struct sysfs_stats_t {
119288 + const char *stat_name;
119289 + uint8_t stat_counter;
119290 +};
119291 +
119292 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119293 + const struct sysfs_stats_t *sysfs_stats,
119294 + uint8_t *offset);
119295 +
119296 +#endif /* LNXWRP_SYSFS_H_ */
119297 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
119298 new file mode 100644
119299 index 00000000..1badbf98
119300 --- /dev/null
119301 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
119302 @@ -0,0 +1,1855 @@
119303 +/*
119304 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119305 + *
119306 + * Redistribution and use in source and binary forms, with or without
119307 + * modification, are permitted provided that the following conditions are met:
119308 + * * Redistributions of source code must retain the above copyright
119309 + * notice, this list of conditions and the following disclaimer.
119310 + * * Redistributions in binary form must reproduce the above copyright
119311 + * notice, this list of conditions and the following disclaimer in the
119312 + * documentation and/or other materials provided with the distribution.
119313 + * * Neither the name of Freescale Semiconductor nor the
119314 + * names of its contributors may be used to endorse or promote products
119315 + * derived from this software without specific prior written permission.
119316 + *
119317 + *
119318 + * ALTERNATIVELY, this software may be distributed under the terms of the
119319 + * GNU General Public License ("GPL") as published by the Free Software
119320 + * Foundation, either version 2 of that License or (at your option) any
119321 + * later version.
119322 + *
119323 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119324 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119325 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119326 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119327 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119328 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119329 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119330 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119331 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119332 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119333 + */
119334 +
119335 +#include "lnxwrp_sysfs.h"
119336 +#include "lnxwrp_sysfs_fm.h"
119337 +#include "lnxwrp_fm.h"
119338 +
119339 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
119340 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
119341 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
119342 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
119343 +
119344 +#if defined(__ERR_MODULE__)
119345 +#undef __ERR_MODULE__
119346 +#endif
119347 +
119348 +#include "../../sdk_fman/Peripherals/FM/fm.h"
119349 +#include <linux/delay.h>
119350 +
119351 +
119352 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
119353 +
119354 +enum fm_dma_match_stats {
119355 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119356 + FM_DMA_COUNTERS_BUS_ERROR,
119357 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119358 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119359 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
119360 +};
119361 +
119362 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
119363 + /* FM statistics */
119364 + {
119365 + .stat_name = "enq_total_frame",
119366 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
119367 + },
119368 + {
119369 + .stat_name = "deq_total_frame",
119370 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
119371 + },
119372 + {
119373 + .stat_name = "deq_0",
119374 + .stat_counter = e_FM_COUNTERS_DEQ_0,
119375 + },
119376 + {
119377 + .stat_name = "deq_1",
119378 + .stat_counter = e_FM_COUNTERS_DEQ_1,
119379 + },
119380 + {
119381 + .stat_name = "deq_2",
119382 + .stat_counter = e_FM_COUNTERS_DEQ_2,
119383 + },
119384 + {
119385 + .stat_name = "deq_3",
119386 + .stat_counter = e_FM_COUNTERS_DEQ_3,
119387 + },
119388 + {
119389 + .stat_name = "deq_from_default",
119390 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
119391 + },
119392 + {
119393 + .stat_name = "deq_from_context",
119394 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
119395 + },
119396 + {
119397 + .stat_name = "deq_from_fd",
119398 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
119399 + },
119400 + {
119401 + .stat_name = "deq_confirm",
119402 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
119403 + },
119404 + /* FM:DMA statistics */
119405 + {
119406 + .stat_name = "cmq_not_empty",
119407 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119408 + },
119409 + {
119410 + .stat_name = "bus_error",
119411 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
119412 + },
119413 + {
119414 + .stat_name = "read_buf_ecc_error",
119415 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119416 + },
119417 + {
119418 + .stat_name = "write_buf_ecc_sys_error",
119419 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119420 + },
119421 + {
119422 + .stat_name = "write_buf_ecc_fm_error",
119423 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
119424 + },
119425 + /* FM:PCD statistics */
119426 + {
119427 + .stat_name = "pcd_kg_total",
119428 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
119429 + },
119430 + {
119431 + .stat_name = "pcd_plcr_yellow",
119432 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
119433 + },
119434 + {
119435 + .stat_name = "pcd_plcr_red",
119436 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
119437 + },
119438 + {
119439 + .stat_name = "pcd_plcr_recolored_to_red",
119440 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
119441 + },
119442 + {
119443 + .stat_name = "pcd_plcr_recolored_to_yellow",
119444 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
119445 + },
119446 + {
119447 + .stat_name = "pcd_plcr_total",
119448 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
119449 + },
119450 + {
119451 + .stat_name = "pcd_plcr_length_mismatch",
119452 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
119453 + },
119454 + {
119455 + .stat_name = "pcd_prs_parse_dispatch",
119456 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
119457 + },
119458 + {
119459 + .stat_name = "pcd_prs_l2_parse_result_returned",
119460 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
119461 + },
119462 + {
119463 + .stat_name = "pcd_prs_l3_parse_result_returned",
119464 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
119465 + },
119466 + {
119467 + .stat_name = "pcd_prs_l4_parse_result_returned",
119468 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
119469 + },
119470 + {
119471 + .stat_name = "pcd_prs_shim_parse_result_returned",
119472 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
119473 + },
119474 + {
119475 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
119476 + .stat_counter =
119477 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
119478 + },
119479 + {
119480 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
119481 + .stat_counter =
119482 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
119483 + },
119484 + {
119485 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
119486 + .stat_counter =
119487 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
119488 + },
119489 + {
119490 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
119491 + .stat_counter =
119492 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
119493 + },
119494 + {
119495 + .stat_name = "pcd_prs_soft_prs_cycles",
119496 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
119497 + },
119498 + {
119499 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
119500 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
119501 + },
119502 + {
119503 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
119504 + .stat_counter =
119505 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
119506 + },
119507 + {
119508 + .stat_name = "pcd_prs_muram_read_cycles",
119509 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
119510 + },
119511 + {
119512 + .stat_name = "pcd_prs_muram_read_stall_cycles",
119513 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
119514 + },
119515 + {
119516 + .stat_name = "pcd_prs_muram_write_cycles",
119517 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
119518 + },
119519 + {
119520 + .stat_name = "pcd_prs_muram_write_stall_cycles",
119521 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
119522 + },
119523 + {
119524 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
119525 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
119526 + },
119527 + {}
119528 +};
119529 +
119530 +
119531 +static ssize_t show_fm_risc_load(struct device *dev,
119532 + struct device_attribute *attr, char *buf)
119533 +{
119534 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119535 + unsigned long flags;
119536 + int m =0;
119537 + int err =0;
119538 + unsigned n = 0;
119539 + t_FmCtrlMon util;
119540 + uint8_t i =0 ;
119541 +
119542 + if (attr == NULL || buf == NULL || dev == NULL)
119543 + return -EINVAL;
119544 +
119545 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119546 + if (WARN_ON(p_wrp_fm_dev == NULL))
119547 + return -EINVAL;
119548 +
119549 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119550 + return -EIO;
119551 +
119552 + local_irq_save(flags);
119553 +
119554 + /* Calculate risc load */
119555 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
119556 + msleep(1000);
119557 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
119558 +
119559 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
119560 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
119561 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
119562 + i, util.percentCnt[0], util.percentCnt[1]);
119563 + n=m+n;
119564 + }
119565 +
119566 + local_irq_restore(flags);
119567 +
119568 + return n;
119569 +}
119570 +
119571 +/* Fm stats and regs dumps via sysfs */
119572 +static ssize_t show_fm_dma_stats(struct device *dev,
119573 + struct device_attribute *attr, char *buf)
119574 +{
119575 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119576 + t_FmDmaStatus dma_status;
119577 + unsigned long flags = 0;
119578 + unsigned n = 0;
119579 + uint8_t counter_value = 0, counter = 0;
119580 +
119581 + if (attr == NULL || buf == NULL || dev == NULL)
119582 + return -EINVAL;
119583 +
119584 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119585 + if (WARN_ON(p_wrp_fm_dev == NULL))
119586 + return -EINVAL;
119587 +
119588 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119589 + return -EIO;
119590 +
119591 + counter = fm_find_statistic_counter_by_name(
119592 + attr->attr.name,
119593 + fm_sysfs_stats, NULL);
119594 +
119595 + local_irq_save(flags);
119596 +
119597 + memset(&dma_status, 0, sizeof(dma_status));
119598 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
119599 +
119600 + switch (counter) {
119601 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
119602 + counter_value = dma_status.cmqNotEmpty;
119603 + break;
119604 + case FM_DMA_COUNTERS_BUS_ERROR:
119605 + counter_value = dma_status.busError;
119606 + break;
119607 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
119608 + counter_value = dma_status.readBufEccError;
119609 + break;
119610 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
119611 + counter_value = dma_status.writeBufEccSysError;
119612 + break;
119613 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
119614 + counter_value = dma_status.writeBufEccFmError;
119615 + break;
119616 + default:
119617 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119618 + __func__);
119619 + break;
119620 + };
119621 +
119622 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119623 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119624 +
119625 + local_irq_restore(flags);
119626 +
119627 + return n;
119628 +}
119629 +
119630 +static ssize_t show_fm_stats(struct device *dev,
119631 + struct device_attribute *attr, char *buf)
119632 +{
119633 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119634 + unsigned long flags = 0;
119635 + unsigned n = 0, cnt_e = 0;
119636 + uint32_t cnt_val;
119637 + int err;
119638 +
119639 + if (attr == NULL || buf == NULL || dev == NULL)
119640 + return -EINVAL;
119641 +
119642 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119643 + if (WARN_ON(p_wrp_fm_dev == NULL))
119644 + return -EINVAL;
119645 +
119646 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119647 + return -EIO;
119648 +
119649 + cnt_e = fm_find_statistic_counter_by_name(
119650 + attr->attr.name,
119651 + fm_sysfs_stats, NULL);
119652 +
119653 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119654 + (e_FmCounters) cnt_e, &cnt_val);
119655 +
119656 + if (err)
119657 + return err;
119658 +
119659 + local_irq_save(flags);
119660 +
119661 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119662 + p_wrp_fm_dev->id, cnt_val);
119663 +
119664 + local_irq_restore(flags);
119665 +
119666 + return n;
119667 +}
119668 +
119669 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119670 + struct device_attribute *attr, char *buf)
119671 +{
119672 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119673 + unsigned long flags = 0;
119674 + unsigned n = 0;
119675 + uint64_t muram_free_size = 0;
119676 +
119677 + if (attr == NULL || buf == NULL || dev == NULL)
119678 + return -EINVAL;
119679 +
119680 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119681 + if (WARN_ON(p_wrp_fm_dev == NULL))
119682 + return -EINVAL;
119683 +
119684 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119685 + return -EIO;
119686 +
119687 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119688 +
119689 + local_irq_save(flags);
119690 +
119691 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119692 + p_wrp_fm_dev->id, muram_free_size);
119693 +
119694 + local_irq_restore(flags);
119695 +
119696 + return n;
119697 +}
119698 +
119699 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119700 + struct device_attribute *attr, char *buf)
119701 +{
119702 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119703 + unsigned long flags = 0;
119704 + unsigned n = 0;
119705 + t_FmCtrlCodeRevisionInfo rv_info;
119706 +
119707 + if (attr == NULL || buf == NULL || dev == NULL)
119708 + return -EINVAL;
119709 +
119710 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119711 + if (WARN_ON(p_wrp_fm_dev == NULL))
119712 + return -EINVAL;
119713 +
119714 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119715 + return -EIO;
119716 +
119717 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119718 +
119719 + local_irq_save(flags);
119720 +
119721 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119722 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119723 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119724 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119725 +
119726 + local_irq_restore(flags);
119727 +
119728 + return n;
119729 +}
119730 +
119731 +static ssize_t show_fm_pcd_stats(struct device *dev,
119732 + struct device_attribute *attr, char *buf)
119733 +{
119734 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119735 + unsigned long flags = 0;
119736 + unsigned n = 0, counter = 0;
119737 +
119738 + if (attr == NULL || buf == NULL || dev == NULL)
119739 + return -EINVAL;
119740 +
119741 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119742 + if (WARN_ON(p_wrp_fm_dev == NULL))
119743 + return -EINVAL;
119744 +
119745 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119746 + !p_wrp_fm_dev->h_PcdDev)
119747 + return -EIO;
119748 +
119749 + counter = fm_find_statistic_counter_by_name(
119750 + attr->attr.name,
119751 + fm_sysfs_stats, NULL);
119752 +
119753 + local_irq_save(flags);
119754 +
119755 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119756 + p_wrp_fm_dev->id,
119757 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119758 + (e_FmPcdCounters) counter));
119759 +
119760 + local_irq_restore(flags);
119761 +
119762 + return n;
119763 +}
119764 +
119765 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119766 + struct device_attribute *attr,
119767 + char *buf)
119768 +{
119769 + unsigned long flags;
119770 + unsigned n = 0;
119771 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119772 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119773 +#endif
119774 +
119775 + if (attr == NULL || buf == NULL || dev == NULL)
119776 + return -EINVAL;
119777 +
119778 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119779 +
119780 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119781 + if (WARN_ON(p_wrp_fm_dev == NULL))
119782 + return -EINVAL;
119783 +
119784 + local_irq_save(flags);
119785 +
119786 + if (!p_wrp_fm_dev->active)
119787 + return -EIO;
119788 + else {
119789 + int tn_s;
119790 +
119791 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119792 + return -EINVAL;
119793 +
119794 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119795 + tn_s, tn_s + 15, buf, n);
119796 + }
119797 + local_irq_restore(flags);
119798 +#else
119799 +
119800 + local_irq_save(flags);
119801 + n = snprintf(buf, PAGE_SIZE,
119802 + "Debug level is too low to dump registers!!!\n");
119803 + local_irq_restore(flags);
119804 +#endif /* (defined(DEBUG_ERRORS) && ... */
119805 +
119806 + return n;
119807 +}
119808 +
119809 +static ssize_t show_fm_cls_plan(struct device *dev,
119810 + struct device_attribute *attr,
119811 + char *buf)
119812 +{
119813 + unsigned long flags;
119814 + unsigned n = 0;
119815 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119816 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119817 +#endif
119818 +
119819 + if (attr == NULL || buf == NULL || dev == NULL)
119820 + return -EINVAL;
119821 +
119822 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119823 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119824 + if (WARN_ON(p_wrp_fm_dev == NULL))
119825 + return -EINVAL;
119826 +
119827 + local_irq_save(flags);
119828 +
119829 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
119830 +
119831 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119832 + return -EIO;
119833 + else {
119834 + int cpn;
119835 +
119836 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
119837 + return -EINVAL;
119838 +
119839 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
119840 + }
119841 + local_irq_restore(flags);
119842 +#else
119843 + local_irq_save(flags);
119844 + n = snprintf(buf, PAGE_SIZE,
119845 + "Debug level is too low to dump registers!!!\n");
119846 + local_irq_restore(flags);
119847 +#endif /* (defined(DEBUG_ERRORS) && ... */
119848 +
119849 + return n;
119850 +}
119851 +
119852 +static ssize_t show_fm_profiles(struct device *dev,
119853 + struct device_attribute *attr,
119854 + char *buf)
119855 +{
119856 + unsigned long flags;
119857 + unsigned n = 0;
119858 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119859 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119860 +#endif
119861 +
119862 + if (attr == NULL || buf == NULL || dev == NULL)
119863 + return -EINVAL;
119864 +
119865 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119866 +
119867 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119868 + if (WARN_ON(p_wrp_fm_dev == NULL))
119869 + return -EINVAL;
119870 +
119871 + local_irq_save(flags);
119872 +
119873 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
119874 +
119875 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119876 + return -EIO;
119877 + else {
119878 + int pn;
119879 +
119880 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
119881 + return -EINVAL;
119882 +
119883 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
119884 + }
119885 + local_irq_restore(flags);
119886 +#else
119887 + local_irq_save(flags);
119888 + n = snprintf(buf, PAGE_SIZE,
119889 + "Debug level is too low to dump registers!!!\n");
119890 + local_irq_restore(flags);
119891 +#endif /* (defined(DEBUG_ERRORS) && ... */
119892 +
119893 + return n;
119894 +}
119895 +
119896 +static ssize_t show_fm_schemes(struct device *dev,
119897 + struct device_attribute *attr,
119898 + char *buf)
119899 +{
119900 + unsigned long flags;
119901 + unsigned n = 0;
119902 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119903 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119904 +#endif
119905 +
119906 + if (attr == NULL || buf == NULL || dev == NULL)
119907 + return -EINVAL;
119908 +
119909 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119910 +
119911 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119912 + if (WARN_ON(p_wrp_fm_dev == NULL))
119913 + return -EINVAL;
119914 +
119915 + local_irq_save(flags);
119916 +
119917 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
119918 +
119919 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119920 + return -EIO;
119921 + else {
119922 + int sn;
119923 +
119924 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
119925 + return -EINVAL;
119926 +
119927 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
119928 + }
119929 + local_irq_restore(flags);
119930 +#else
119931 +
119932 + local_irq_save(flags);
119933 + n = snprintf(buf, PAGE_SIZE,
119934 + "Debug level is too low to dump registers!!!\n");
119935 + local_irq_restore(flags);
119936 +#endif /* (defined(DEBUG_ERRORS) && ... */
119937 +
119938 + return n;
119939 +}
119940 +
119941 +/* FM */
119942 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
119943 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
119944 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
119945 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
119946 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
119947 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
119948 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
119949 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
119950 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
119951 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
119952 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
119953 +/* FM:DMA */
119954 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
119955 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
119956 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
119957 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
119958 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
119959 +/* FM:PCD */
119960 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
119961 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
119962 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
119963 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
119964 + NULL);
119965 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
119966 + NULL);
119967 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
119968 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
119969 + NULL);
119970 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
119971 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
119972 + show_fm_pcd_stats, NULL);
119973 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
119974 + show_fm_pcd_stats, NULL);
119975 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
119976 + show_fm_pcd_stats, NULL);
119977 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
119978 + show_fm_pcd_stats, NULL);
119979 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
119980 + show_fm_pcd_stats, NULL);
119981 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
119982 + show_fm_pcd_stats, NULL);
119983 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
119984 + show_fm_pcd_stats, NULL);
119985 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
119986 + show_fm_pcd_stats, NULL);
119987 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
119988 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
119989 + NULL);
119990 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
119991 + show_fm_pcd_stats, NULL);
119992 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
119993 + NULL);
119994 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
119995 + show_fm_pcd_stats, NULL);
119996 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
119997 + NULL);
119998 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
119999 + show_fm_pcd_stats, NULL);
120000 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
120001 + show_fm_pcd_stats, NULL);
120002 +
120003 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
120004 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
120005 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
120006 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
120007 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
120008 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
120009 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
120010 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
120011 +
120012 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
120013 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
120014 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
120015 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
120016 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
120017 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
120018 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
120019 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
120020 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
120021 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
120022 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
120023 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
120024 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
120025 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
120026 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
120027 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
120028 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
120029 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
120030 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
120031 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
120032 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
120033 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
120034 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
120035 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
120036 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
120037 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
120038 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
120039 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
120040 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
120041 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
120042 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
120043 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
120044 +
120045 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
120046 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
120047 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
120048 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
120049 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
120050 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
120051 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
120052 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
120053 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
120054 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
120055 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
120056 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
120057 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
120058 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
120059 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
120060 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
120061 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
120062 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
120063 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
120064 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
120065 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
120066 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
120067 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
120068 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
120069 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
120070 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
120071 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
120072 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
120073 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
120074 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
120075 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
120076 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
120077 +
120078 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
120079 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
120080 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
120081 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
120082 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
120083 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
120084 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
120085 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
120086 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
120087 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
120088 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
120089 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
120090 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
120091 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
120092 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
120093 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
120094 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
120095 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
120096 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
120097 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
120098 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
120099 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
120100 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
120101 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
120102 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
120103 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
120104 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
120105 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
120106 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
120107 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
120108 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
120109 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
120110 +
120111 +
120112 +static struct attribute *fm_dev_stats_attributes[] = {
120113 + &dev_attr_enq_total_frame.attr,
120114 + &dev_attr_deq_total_frame.attr,
120115 + &dev_attr_deq_0.attr,
120116 + &dev_attr_deq_1.attr,
120117 + &dev_attr_deq_2.attr,
120118 + &dev_attr_deq_3.attr,
120119 + &dev_attr_deq_from_default.attr,
120120 + &dev_attr_deq_from_context.attr,
120121 + &dev_attr_deq_from_fd.attr,
120122 + &dev_attr_deq_confirm.attr,
120123 + &dev_attr_cmq_not_empty.attr,
120124 + &dev_attr_bus_error.attr,
120125 + &dev_attr_read_buf_ecc_error.attr,
120126 + &dev_attr_write_buf_ecc_sys_error.attr,
120127 + &dev_attr_write_buf_ecc_fm_error.attr,
120128 + &dev_attr_pcd_kg_total.attr,
120129 + &dev_attr_pcd_plcr_yellow.attr,
120130 + &dev_attr_pcd_plcr_red.attr,
120131 + &dev_attr_pcd_plcr_recolored_to_red.attr,
120132 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
120133 + &dev_attr_pcd_plcr_total.attr,
120134 + &dev_attr_pcd_plcr_length_mismatch.attr,
120135 + &dev_attr_pcd_prs_parse_dispatch.attr,
120136 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
120137 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
120138 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
120139 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
120140 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
120141 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
120142 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
120143 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
120144 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
120145 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
120146 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
120147 + &dev_attr_pcd_prs_muram_read_cycles.attr,
120148 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
120149 + &dev_attr_pcd_prs_muram_write_cycles.attr,
120150 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
120151 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
120152 + NULL
120153 +};
120154 +
120155 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
120156 + &dev_attr_tnum_dbg_0.attr,
120157 + &dev_attr_tnum_dbg_16.attr,
120158 + &dev_attr_tnum_dbg_32.attr,
120159 + &dev_attr_tnum_dbg_48.attr,
120160 + &dev_attr_tnum_dbg_64.attr,
120161 + &dev_attr_tnum_dbg_80.attr,
120162 + &dev_attr_tnum_dbg_96.attr,
120163 + &dev_attr_tnum_dbg_112.attr,
120164 + NULL
120165 +};
120166 +
120167 +static struct attribute *fm_dev_cls_plans_attributes[] = {
120168 + &dev_attr_cls_plan_0.attr,
120169 + &dev_attr_cls_plan_1.attr,
120170 + &dev_attr_cls_plan_2.attr,
120171 + &dev_attr_cls_plan_3.attr,
120172 + &dev_attr_cls_plan_4.attr,
120173 + &dev_attr_cls_plan_5.attr,
120174 + &dev_attr_cls_plan_6.attr,
120175 + &dev_attr_cls_plan_7.attr,
120176 + &dev_attr_cls_plan_8.attr,
120177 + &dev_attr_cls_plan_9.attr,
120178 + &dev_attr_cls_plan_10.attr,
120179 + &dev_attr_cls_plan_11.attr,
120180 + &dev_attr_cls_plan_12.attr,
120181 + &dev_attr_cls_plan_13.attr,
120182 + &dev_attr_cls_plan_14.attr,
120183 + &dev_attr_cls_plan_15.attr,
120184 + &dev_attr_cls_plan_16.attr,
120185 + &dev_attr_cls_plan_17.attr,
120186 + &dev_attr_cls_plan_18.attr,
120187 + &dev_attr_cls_plan_19.attr,
120188 + &dev_attr_cls_plan_20.attr,
120189 + &dev_attr_cls_plan_21.attr,
120190 + &dev_attr_cls_plan_22.attr,
120191 + &dev_attr_cls_plan_23.attr,
120192 + &dev_attr_cls_plan_24.attr,
120193 + &dev_attr_cls_plan_25.attr,
120194 + &dev_attr_cls_plan_26.attr,
120195 + &dev_attr_cls_plan_27.attr,
120196 + &dev_attr_cls_plan_28.attr,
120197 + &dev_attr_cls_plan_29.attr,
120198 + &dev_attr_cls_plan_30.attr,
120199 + &dev_attr_cls_plan_31.attr,
120200 + NULL
120201 +};
120202 +
120203 +static struct attribute *fm_dev_profiles_attributes[] = {
120204 + &dev_attr_profile_0.attr,
120205 + &dev_attr_profile_1.attr,
120206 + &dev_attr_profile_2.attr,
120207 + &dev_attr_profile_3.attr,
120208 + &dev_attr_profile_4.attr,
120209 + &dev_attr_profile_5.attr,
120210 + &dev_attr_profile_6.attr,
120211 + &dev_attr_profile_7.attr,
120212 + &dev_attr_profile_8.attr,
120213 + &dev_attr_profile_9.attr,
120214 + &dev_attr_profile_10.attr,
120215 + &dev_attr_profile_11.attr,
120216 + &dev_attr_profile_12.attr,
120217 + &dev_attr_profile_13.attr,
120218 + &dev_attr_profile_14.attr,
120219 + &dev_attr_profile_15.attr,
120220 + &dev_attr_profile_16.attr,
120221 + &dev_attr_profile_17.attr,
120222 + &dev_attr_profile_18.attr,
120223 + &dev_attr_profile_19.attr,
120224 + &dev_attr_profile_20.attr,
120225 + &dev_attr_profile_21.attr,
120226 + &dev_attr_profile_22.attr,
120227 + &dev_attr_profile_23.attr,
120228 + &dev_attr_profile_24.attr,
120229 + &dev_attr_profile_25.attr,
120230 + &dev_attr_profile_26.attr,
120231 + &dev_attr_profile_27.attr,
120232 + &dev_attr_profile_28.attr,
120233 + &dev_attr_profile_29.attr,
120234 + &dev_attr_profile_30.attr,
120235 + &dev_attr_profile_31.attr,
120236 + NULL
120237 +};
120238 +
120239 +static struct attribute *fm_dev_schemes_attributes[] = {
120240 + &dev_attr_scheme_0.attr,
120241 + &dev_attr_scheme_1.attr,
120242 + &dev_attr_scheme_2.attr,
120243 + &dev_attr_scheme_3.attr,
120244 + &dev_attr_scheme_4.attr,
120245 + &dev_attr_scheme_5.attr,
120246 + &dev_attr_scheme_6.attr,
120247 + &dev_attr_scheme_7.attr,
120248 + &dev_attr_scheme_8.attr,
120249 + &dev_attr_scheme_9.attr,
120250 + &dev_attr_scheme_10.attr,
120251 + &dev_attr_scheme_11.attr,
120252 + &dev_attr_scheme_12.attr,
120253 + &dev_attr_scheme_13.attr,
120254 + &dev_attr_scheme_14.attr,
120255 + &dev_attr_scheme_15.attr,
120256 + &dev_attr_scheme_16.attr,
120257 + &dev_attr_scheme_17.attr,
120258 + &dev_attr_scheme_18.attr,
120259 + &dev_attr_scheme_19.attr,
120260 + &dev_attr_scheme_20.attr,
120261 + &dev_attr_scheme_21.attr,
120262 + &dev_attr_scheme_22.attr,
120263 + &dev_attr_scheme_23.attr,
120264 + &dev_attr_scheme_24.attr,
120265 + &dev_attr_scheme_25.attr,
120266 + &dev_attr_scheme_26.attr,
120267 + &dev_attr_scheme_27.attr,
120268 + &dev_attr_scheme_28.attr,
120269 + &dev_attr_scheme_29.attr,
120270 + &dev_attr_scheme_30.attr,
120271 + &dev_attr_scheme_31.attr,
120272 + NULL
120273 +};
120274 +
120275 +static const struct attribute_group fm_dev_stats_attr_grp = {
120276 + .name = "statistics",
120277 + .attrs = fm_dev_stats_attributes
120278 +};
120279 +
120280 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
120281 + .name = "tnums_dbg",
120282 + .attrs = fm_dev_tnums_dbg_attributes
120283 +};
120284 +
120285 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
120286 + .name = "cls_plans",
120287 + .attrs = fm_dev_cls_plans_attributes
120288 +};
120289 +
120290 +static const struct attribute_group fm_dev_schemes_attr_grp = {
120291 + .name = "schemes",
120292 + .attrs = fm_dev_schemes_attributes
120293 +};
120294 +
120295 +static const struct attribute_group fm_dev_profiles_attr_grp = {
120296 + .name = "profiles",
120297 + .attrs = fm_dev_profiles_attributes
120298 +};
120299 +
120300 +static ssize_t show_fm_regs(struct device *dev,
120301 + struct device_attribute *attr,
120302 + char *buf)
120303 +{
120304 + unsigned long flags;
120305 + unsigned n = 0;
120306 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120307 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120308 +#endif
120309 + if (attr == NULL || buf == NULL || dev == NULL)
120310 + return -EINVAL;
120311 +
120312 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120313 +
120314 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120315 + if (WARN_ON(p_wrp_fm_dev == NULL))
120316 + return -EINVAL;
120317 +
120318 + local_irq_save(flags);
120319 +
120320 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
120321 +
120322 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120323 + return -EIO;
120324 + else
120325 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120326 +
120327 + local_irq_restore(flags);
120328 +#else
120329 +
120330 + local_irq_save(flags);
120331 + n = snprintf(buf, PAGE_SIZE,
120332 + "Debug level is too low to dump registers!!!\n");
120333 + local_irq_restore(flags);
120334 +#endif /* (defined(DEBUG_ERRORS) && ... */
120335 +
120336 + return n;
120337 +}
120338 +
120339 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
120340 + struct device_attribute *attr,
120341 + char *buf)
120342 +{
120343 + unsigned long flags;
120344 + unsigned n = 0;
120345 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120346 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120347 +#endif
120348 +
120349 + if (attr == NULL || buf == NULL || dev == NULL)
120350 + return -EINVAL;
120351 +
120352 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120353 +
120354 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120355 + if (WARN_ON(p_wrp_fm_dev == NULL))
120356 + return -EINVAL;
120357 +
120358 + local_irq_save(flags);
120359 +
120360 + n = snprintf(buf, PAGE_SIZE,
120361 + "\n FM-KG Port Partition Config registers dump.\n");
120362 +
120363 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120364 + return -EIO;
120365 + else
120366 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120367 +
120368 + local_irq_restore(flags);
120369 +#else
120370 +
120371 + local_irq_save(flags);
120372 + n = snprintf(buf, PAGE_SIZE,
120373 + "Debug level is too low to dump registers!!!\n");
120374 + local_irq_restore(flags);
120375 +#endif /* (defined(DEBUG_ERRORS) && ... */
120376 +
120377 + return n;
120378 +}
120379 +
120380 +static ssize_t show_fm_kg_regs(struct device *dev,
120381 + struct device_attribute *attr,
120382 + char *buf)
120383 +{
120384 + unsigned long flags;
120385 + unsigned n = 0;
120386 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120387 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120388 +#endif
120389 +
120390 + if (attr == NULL || buf == NULL || dev == NULL)
120391 + return -EINVAL;
120392 +
120393 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120394 +
120395 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120396 + if (WARN_ON(p_wrp_fm_dev == NULL))
120397 + return -EINVAL;
120398 +
120399 + local_irq_save(flags);
120400 +
120401 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
120402 +
120403 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120404 + return -EIO;
120405 + else
120406 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120407 +
120408 + local_irq_restore(flags);
120409 +#else
120410 +
120411 + local_irq_save(flags);
120412 + n = snprintf(buf, PAGE_SIZE,
120413 + "Debug level is too low to dump registers!!!\n");
120414 + local_irq_restore(flags);
120415 +#endif /* (defined(DEBUG_ERRORS) && ... */
120416 +
120417 + return n;
120418 +}
120419 +
120420 +
120421 +static ssize_t show_fm_fpm_regs(struct device *dev,
120422 + struct device_attribute *attr,
120423 + char *buf)
120424 +{
120425 + unsigned long flags;
120426 + unsigned n = 0;
120427 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120428 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120429 +#endif
120430 +
120431 + if (attr == NULL || buf == NULL || dev == NULL)
120432 + return -EINVAL;
120433 +
120434 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120435 +
120436 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120437 + if (WARN_ON(p_wrp_fm_dev == NULL))
120438 + return -EINVAL;
120439 +
120440 + local_irq_save(flags);
120441 +
120442 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
120443 +
120444 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120445 + return -EIO;
120446 + else
120447 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120448 +
120449 + local_irq_restore(flags);
120450 +#else
120451 +
120452 + local_irq_save(flags);
120453 + n = snprintf(buf, PAGE_SIZE,
120454 + "Debug level is too low to dump registers!!!\n");
120455 + local_irq_restore(flags);
120456 +#endif /* (defined(DEBUG_ERRORS) && ... */
120457 +
120458 + return n;
120459 +}
120460 +
120461 +static ssize_t show_prs_regs(struct device *dev,
120462 + struct device_attribute *attr, char *buf)
120463 +{
120464 + unsigned long flags;
120465 + unsigned n = 0;
120466 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120467 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120468 +#endif
120469 +
120470 + if (attr == NULL || buf == NULL || dev == NULL)
120471 + return -EINVAL;
120472 +
120473 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120474 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120475 + if (WARN_ON(p_wrp_fm_dev == NULL))
120476 + return -EINVAL;
120477 +
120478 + local_irq_save(flags);
120479 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120480 +
120481 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120482 + return -EIO;
120483 + else
120484 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120485 +
120486 + local_irq_restore(flags);
120487 +#else
120488 +
120489 + local_irq_save(flags);
120490 + n = snprintf(buf, PAGE_SIZE,
120491 + "Debug level is too low to dump registers!!!\n");
120492 + local_irq_restore(flags);
120493 +
120494 +#endif /* (defined(DEBUG_ERRORS) && ... */
120495 +
120496 + return n;
120497 +}
120498 +
120499 +static ssize_t show_plcr_regs(struct device *dev,
120500 + struct device_attribute *attr,
120501 + char *buf)
120502 +{
120503 + unsigned long flags;
120504 + unsigned n = 0;
120505 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120506 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120507 +#endif
120508 +
120509 + if (attr == NULL || buf == NULL || dev == NULL)
120510 + return -EINVAL;
120511 +
120512 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120513 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120514 + if (WARN_ON(p_wrp_fm_dev == NULL))
120515 + return -EINVAL;
120516 +
120517 + local_irq_save(flags);
120518 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120519 +
120520 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120521 + return -EIO;
120522 + else
120523 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120524 +
120525 + local_irq_restore(flags);
120526 +#else
120527 +
120528 + local_irq_save(flags);
120529 + n = snprintf(buf, PAGE_SIZE,
120530 + "Debug level is too low to dump registers!!!\n");
120531 + local_irq_restore(flags);
120532 +
120533 +#endif /* (defined(DEBUG_ERRORS) && ... */
120534 +
120535 + return n;
120536 +}
120537 +
120538 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
120539 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
120540 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
120541 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
120542 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
120543 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
120544 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
120545 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
120546 +
120547 +int fm_sysfs_create(struct device *dev)
120548 +{
120549 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120550 +
120551 + if (dev == NULL)
120552 + return -EIO;
120553 +
120554 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120555 +
120556 + /* store to remove them when module is disabled */
120557 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
120558 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
120559 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
120560 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
120561 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
120562 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
120563 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
120564 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
120565 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
120566 +
120567 + /* Create sysfs statistics group for FM module */
120568 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
120569 + return -EIO;
120570 +
120571 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
120572 + return -EIO;
120573 +
120574 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
120575 + return -EIO;
120576 +
120577 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
120578 + return -EIO;
120579 +
120580 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
120581 + return -EIO;
120582 +
120583 + /* Registers dump entry - in future will be moved to debugfs */
120584 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
120585 + return -EIO;
120586 +
120587 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
120588 + return -EIO;
120589 +
120590 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
120591 + return -EIO;
120592 +
120593 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
120594 + return -EIO;
120595 +
120596 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
120597 + return -EIO;
120598 +
120599 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
120600 + return -EIO;
120601 +
120602 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
120603 + return -EIO;
120604 +
120605 + /* muram free size */
120606 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
120607 + return -EIO;
120608 +
120609 + /* fm ctrl code version */
120610 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
120611 + return -EIO;
120612 +
120613 + return 0;
120614 +}
120615 +
120616 +void fm_sysfs_destroy(struct device *dev)
120617 +{
120618 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120619 +
120620 + if (WARN_ON(dev == NULL))
120621 + return;
120622 +
120623 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120624 + if (WARN_ON(p_wrp_fm_dev == NULL))
120625 + return;
120626 +
120627 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120628 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120629 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120630 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120631 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120632 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120633 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120634 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120635 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120636 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120637 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120638 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120639 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120640 +}
120641 +
120642 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120643 +{
120644 + t_Fm *p_Fm = (t_Fm *)h_fm;
120645 + uint8_t i = 0;
120646 + int n = nn;
120647 +
120648 + FM_DMP_SUBTITLE(buf, n, "\n");
120649 +
120650 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120651 +
120652 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120653 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120654 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120655 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120656 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120657 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120658 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120659 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120660 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120661 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120662 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120663 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120664 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120665 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120666 +
120667 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120668 +
120669 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120670 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120671 +
120672 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120673 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120674 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120675 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120676 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120677 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120678 +
120679 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120680 + for (i = 0; i < 8 ; ++i)
120681 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120682 +
120683 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120684 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120685 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120686 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120687 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120688 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120689 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120690 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120691 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120692 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120693 +
120694 + return n;
120695 +}
120696 +
120697 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120698 +{
120699 + t_Fm *p_Fm = (t_Fm *)h_fm;
120700 + uint8_t i, j = 0;
120701 + int n = nn;
120702 +
120703 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120704 + tn_s, tn_e);
120705 +
120706 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120707 +
120708 + mb();
120709 +
120710 + for (j = tn_s; j <= tn_e; j++) {
120711 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120712 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120713 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120714 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120715 +
120716 + for (i = 0; i < 4 ; ++i)
120717 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120718 +
120719 + FM_DMP_LN(buf, n, "\n");
120720 +
120721 + }
120722 +
120723 + return n;
120724 +}
120725 +
120726 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120727 +{
120728 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120729 + int i = 0;
120730 + uint32_t tmp;
120731 + unsigned long i_flg;
120732 + int n = nn;
120733 + u_FmPcdKgIndirectAccessRegs *idac;
120734 + spinlock_t *p_lk;
120735 +
120736 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120737 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120738 +
120739 + spin_lock_irqsave(p_lk, i_flg);
120740 +
120741 + /* Read ClsPlan Block Action Regs */
120742 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120743 + FM_KG_KGAR_READ |
120744 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120745 + DUMMY_PORT_ID |
120746 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120747 + FM_PCD_KG_KGAR_WSEL_MASK);
120748 +
120749 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120750 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120751 + spin_unlock_irqrestore(p_lk, i_flg);
120752 + return nn;
120753 + }
120754 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120755 + "ClsPlan %d Indirect Access Regs", cpn);
120756 +
120757 + for (i = 0; i < 8; i++)
120758 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120759 +
120760 + spin_unlock_irqrestore(p_lk, i_flg);
120761 +
120762 + return n;
120763 +}
120764 +
120765 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120766 +{
120767 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120768 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120769 + t_FmPcdPlcrRegs *p_plcr_regs;
120770 + t_FmPcdPlcr *p_plcr;
120771 + uint32_t tmp;
120772 + unsigned long i_flg;
120773 + int n = nn;
120774 + int toc = 10;
120775 + spinlock_t *p_lk;
120776 +
120777 + p_plcr = p_pcd->p_FmPcdPlcr;
120778 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120779 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120780 +
120781 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120782 +
120783 + FM_DMP_SUBTITLE(buf, n, "\n");
120784 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120785 +
120786 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120787 + FM_PCD_PLCR_PAR_R |
120788 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120789 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120790 +
120791 + spin_lock_irqsave(p_lk, i_flg);
120792 +
120793 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120794 +
120795 + mb();
120796 +
120797 + /* wait for the porfile regs to be present */
120798 + do {
120799 + --toc;
120800 + udelay(10);
120801 + if (!toc) {
120802 + /* looks like PLCR_PAR_GO refuses to clear */
120803 + spin_unlock_irqrestore(p_lk, i_flg);
120804 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
120805 + FM_DMP_LN(buf, n, " check profile init process\n");
120806 + return n;
120807 + }
120808 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
120809 +
120810 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
120811 +
120812 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
120813 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
120814 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
120815 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
120816 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
120817 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
120818 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
120819 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
120820 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
120821 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
120822 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
120823 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
120824 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
120825 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
120826 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
120827 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
120828 +
120829 + spin_unlock_irqrestore(p_lk, i_flg);
120830 +
120831 + return n;
120832 +}
120833 +
120834 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
120835 +{
120836 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120837 + uint32_t tmp_ar;
120838 + unsigned long i_flg;
120839 + int i, n = nn;
120840 + spinlock_t *p_lk;
120841 + u_FmPcdKgIndirectAccessRegs *idac;
120842 +
120843 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120844 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120845 +
120846 + spin_lock_irqsave(p_lk, i_flg);
120847 +
120848 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
120849 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
120850 + FM_DMP_LN(buf, nn,
120851 + "Keygen scheme access violation or no such scheme");
120852 + spin_unlock_irqrestore(p_lk, i_flg);
120853 + return nn;
120854 + }
120855 +
120856 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
120857 + "Scheme %d Indirect Access Regs", scnum);
120858 +
120859 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
120860 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
120861 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
120862 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
120863 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
120864 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
120865 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
120866 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
120867 +
120868 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
120869 +
120870 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
120871 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
120872 +
120873 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
120874 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
120875 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
120876 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
120877 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
120878 +
120879 + FM_DMP_SUBTITLE(buf, n, "\n");
120880 +
120881 + spin_unlock_irqrestore(p_lk, i_flg);
120882 +
120883 + return n;
120884 +}
120885 +
120886 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
120887 +{
120888 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120889 + int i = 0;
120890 + uint8_t prt_id = 0;
120891 + uint32_t tmp_ar;
120892 + unsigned long i_flg;
120893 + int n = nn;
120894 + u_FmPcdKgIndirectAccessRegs *idac;
120895 + t_FmPcdKg *p_kg;
120896 + spinlock_t *p_lk;
120897 +
120898 + p_kg = p_pcd->p_FmPcdKg;
120899 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120900 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
120901 +
120902 + spin_lock_irqsave(p_lk, i_flg);
120903 +
120904 + FM_DMP_SUBTITLE(buf, n, "\n");
120905 +
120906 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
120907 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
120908 +
120909 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
120910 +
120911 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
120912 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120913 + spin_unlock_irqrestore(p_lk, i_flg);
120914 + return nn;
120915 + }
120916 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
120917 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
120918 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
120919 + }
120920 +
120921 + FM_DMP_SUBTITLE(buf, n, "\n");
120922 +
120923 + spin_unlock_irqrestore(p_lk, i_flg);
120924 +
120925 + return n;
120926 +}
120927 +
120928 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
120929 +{
120930 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120931 + int n = nn;
120932 +
120933 + FM_DMP_SUBTITLE(buf, n, "\n");
120934 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
120935 + "FmPcdKgRegs Regs");
120936 +
120937 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
120938 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
120939 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
120940 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
120941 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
120942 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
120943 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
120944 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
120945 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
120946 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
120947 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
120948 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
120949 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
120950 +
120951 + FM_DMP_SUBTITLE(buf, n, "\n");
120952 +
120953 + return n;
120954 +}
120955 +
120956 +
120957 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
120958 +{
120959 + t_Fm *p_fm = (t_Fm *)h_fm;
120960 + uint8_t i;
120961 + int n = nn;
120962 +
120963 + FM_DMP_SUBTITLE(buf, n, "\n");
120964 +
120965 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
120966 +
120967 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
120968 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
120969 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
120970 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
120971 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
120972 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
120973 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
120974 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
120975 +
120976 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
120977 + for (i = 0; i < 4; ++i)
120978 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
120979 +
120980 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
120981 + for (i = 0; i < 4; ++i)
120982 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
120983 +
120984 + FM_DMP_SUBTITLE(buf, n, "\n");
120985 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
120986 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
120987 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
120988 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
120989 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
120990 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
120991 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
120992 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
120993 +
120994 + FM_DMP_SUBTITLE(buf, n, "\n");
120995 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
120996 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
120997 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
120998 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
120999 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
121000 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
121001 +
121002 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
121003 + for (i = 0; i < 4; ++i)
121004 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
121005 +
121006 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
121007 + for (i = 0; i < 64; ++i)
121008 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
121009 +
121010 + return n;
121011 +}
121012 +
121013 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
121014 +{
121015 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121016 + int n = nn;
121017 +
121018 + FM_DMP_SUBTITLE(buf, n, "\n");
121019 +
121020 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
121021 + "FM-PCD parser regs");
121022 +
121023 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
121024 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
121025 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
121026 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
121027 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
121028 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
121029 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
121030 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
121031 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
121032 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
121033 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
121034 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
121035 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
121036 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
121037 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
121038 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
121039 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
121040 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
121041 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
121042 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
121043 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
121044 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
121045 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
121046 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
121047 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
121048 +
121049 + return n;
121050 +}
121051 +
121052 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
121053 +{
121054 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121055 + int i = 0;
121056 + int n = nn;
121057 +
121058 + FM_DMP_SUBTITLE(buf, n, "\n");
121059 +
121060 + FM_DMP_TITLE(buf, n,
121061 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
121062 + "FM policer regs");
121063 +
121064 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
121065 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
121066 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
121067 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
121068 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
121069 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
121070 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
121071 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
121072 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
121073 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
121074 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
121075 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
121076 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
121077 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
121078 +
121079 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
121080 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
121081 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
121082 +
121083 + FM_DMP_TITLE(buf, n,
121084 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
121085 + "fmpl_pmr");
121086 +
121087 + for (i = 0; i < 63; ++i)
121088 + FM_DMP_MEM_32(buf, n,
121089 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
121090 +
121091 + return n;
121092 +}
121093 +
121094 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
121095 +{
121096 + t_Fm *p_fm = (t_Fm *)h_fm;
121097 +
121098 + /* When applicable (when there is an "enable counters" bit),
121099 + check that counters are enabled */
121100 +
121101 + switch (cnt_e) {
121102 + case (e_FM_COUNTERS_DEQ_1):
121103 + case (e_FM_COUNTERS_DEQ_2):
121104 + case (e_FM_COUNTERS_DEQ_3):
121105 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
121106 + return -EINVAL; /* counter not available */
121107 +
121108 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
121109 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
121110 + case (e_FM_COUNTERS_DEQ_0):
121111 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
121112 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
121113 + case (e_FM_COUNTERS_DEQ_FROM_FD):
121114 + case (e_FM_COUNTERS_DEQ_CONFIRM):
121115 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
121116 + QMI_CFG_EN_COUNTERS))
121117 + return -EINVAL; /* Requested counter not available */
121118 + break;
121119 + default:
121120 + break;
121121 + }
121122 +
121123 + switch (cnt_e) {
121124 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
121125 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
121126 + return 0;
121127 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
121128 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
121129 + return 0;
121130 + case (e_FM_COUNTERS_DEQ_0):
121131 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
121132 + return 0;
121133 + case (e_FM_COUNTERS_DEQ_1):
121134 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
121135 + return 0;
121136 + case (e_FM_COUNTERS_DEQ_2):
121137 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
121138 + return 0;
121139 + case (e_FM_COUNTERS_DEQ_3):
121140 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
121141 + return 0;
121142 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
121143 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
121144 + return 0;
121145 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
121146 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
121147 + return 0;
121148 + case (e_FM_COUNTERS_DEQ_FROM_FD):
121149 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
121150 + return 0;
121151 + case (e_FM_COUNTERS_DEQ_CONFIRM):
121152 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
121153 + return 0;
121154 + }
121155 + /* should never get here */
121156 + return -EINVAL; /* counter not available */
121157 +}
121158 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
121159 new file mode 100644
121160 index 00000000..137653e9
121161 --- /dev/null
121162 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
121163 @@ -0,0 +1,136 @@
121164 +/*
121165 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121166 + *
121167 + * Redistribution and use in source and binary forms, with or without
121168 + * modification, are permitted provided that the following conditions are met:
121169 + * * Redistributions of source code must retain the above copyright
121170 + * notice, this list of conditions and the following disclaimer.
121171 + * * Redistributions in binary form must reproduce the above copyright
121172 + * notice, this list of conditions and the following disclaimer in the
121173 + * documentation and/or other materials provided with the distribution.
121174 + * * Neither the name of Freescale Semiconductor nor the
121175 + * names of its contributors may be used to endorse or promote products
121176 + * derived from this software without specific prior written permission.
121177 + *
121178 + *
121179 + * ALTERNATIVELY, this software may be distributed under the terms of the
121180 + * GNU General Public License ("GPL") as published by the Free Software
121181 + * Foundation, either version 2 of that License or (at your option) any
121182 + * later version.
121183 + *
121184 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121185 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121186 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121187 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121188 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121189 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121190 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121191 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121192 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121193 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121194 + */
121195 +
121196 +
121197 +#ifndef LNXWRP_SYSFS_FM_H_
121198 +#define LNXWRP_SYSFS_FM_H_
121199 +
121200 +#include "lnxwrp_sysfs.h"
121201 +
121202 +int fm_sysfs_create(struct device *dev);
121203 +void fm_sysfs_destroy(struct device *dev);
121204 +int fm_dump_regs(void *h_dev, char *buf, int nn);
121205 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
121206 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
121207 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
121208 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
121209 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
121210 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
121211 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
121212 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
121213 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
121214 +
121215 +#define FM_DMP_PGSZ_ERR { \
121216 + snprintf(&buf[PAGE_SIZE - 80], 70, \
121217 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
121218 + n = PAGE_SIZE - 2; \
121219 + }
121220 +
121221 +#define FM_DMP_LN(buf, n, ...) \
121222 + do { \
121223 + int k, m = n; \
121224 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121225 + if (k < 0 || m > PAGE_SIZE - 90) \
121226 + FM_DMP_PGSZ_ERR \
121227 + n = m; \
121228 + } while (0)
121229 +
121230 +#define FM_DMP_TITLE(buf, n, addr, ...) \
121231 + do { \
121232 + int k, m = n; \
121233 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121234 + if (k < 0 || m > PAGE_SIZE - 90) \
121235 + FM_DMP_PGSZ_ERR \
121236 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121237 + if (k < 0 || m > PAGE_SIZE - 90) \
121238 + FM_DMP_PGSZ_ERR \
121239 + if (addr) { \
121240 + phys_addr_t pa; \
121241 + pa = virt_to_phys(addr); \
121242 + m += k = \
121243 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
121244 + (long unsigned int)(pa)); \
121245 + if (k < 0 || m > PAGE_SIZE - 90) \
121246 + FM_DMP_PGSZ_ERR \
121247 + } \
121248 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
121249 + "\n----------------------------------------\n\n"); \
121250 + if (k < 0 || m > PAGE_SIZE - 90) \
121251 + FM_DMP_PGSZ_ERR \
121252 + n = m; \
121253 + } while (0)
121254 +
121255 +#define FM_DMP_SUBTITLE(buf, n, ...) \
121256 + do { \
121257 + int k, m = n; \
121258 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
121259 + if (k < 0 || m > PAGE_SIZE - 90) \
121260 + FM_DMP_PGSZ_ERR \
121261 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121262 + if (k < 0 || m > PAGE_SIZE - 90) \
121263 + FM_DMP_PGSZ_ERR \
121264 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121265 + if (k < 0 || m > PAGE_SIZE - 90) \
121266 + FM_DMP_PGSZ_ERR \
121267 + n = m; \
121268 + } while (0)
121269 +
121270 +#define FM_DMP_MEM_32(buf, n, addr) \
121271 + { \
121272 + uint32_t val; \
121273 + phys_addr_t pa; \
121274 + int k, m = n; \
121275 + pa = virt_to_phys(addr); \
121276 + val = ioread32be((addr)); \
121277 + do { \
121278 + m += k = snprintf(&buf[m], \
121279 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
121280 + pa, val); \
121281 + if (k < 0 || m > PAGE_SIZE - 90) \
121282 + FM_DMP_PGSZ_ERR \
121283 + n += k; \
121284 + } while (0) ;\
121285 + }
121286 +
121287 +#define FM_DMP_V32(buf, n, st, phrase) \
121288 + do { \
121289 + int k, m = n; \
121290 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
121291 + k = snprintf(&buf[m], PAGE_SIZE - m, \
121292 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
121293 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
121294 + if (k < 0 || m > PAGE_SIZE - 90) \
121295 + FM_DMP_PGSZ_ERR \
121296 + n += k; \
121297 + } while (0)
121298 +
121299 +#endif /* LNXWRP_SYSFS_FM_H_ */
121300 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
121301 new file mode 100644
121302 index 00000000..db8e824c
121303 --- /dev/null
121304 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
121305 @@ -0,0 +1,1268 @@
121306 +/*
121307 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121308 + *
121309 + * Redistribution and use in source and binary forms, with or without
121310 + * modification, are permitted provided that the following conditions are met:
121311 + * * Redistributions of source code must retain the above copyright
121312 + * notice, this list of conditions and the following disclaimer.
121313 + * * Redistributions in binary form must reproduce the above copyright
121314 + * notice, this list of conditions and the following disclaimer in the
121315 + * documentation and/or other materials provided with the distribution.
121316 + * * Neither the name of Freescale Semiconductor nor the
121317 + * names of its contributors may be used to endorse or promote products
121318 + * derived from this software without specific prior written permission.
121319 + *
121320 + *
121321 + * ALTERNATIVELY, this software may be distributed under the terms of the
121322 + * GNU General Public License ("GPL") as published by the Free Software
121323 + * Foundation, either version 2 of that License or (at your option) any
121324 + * later version.
121325 + *
121326 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121327 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121328 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121329 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121330 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121331 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121332 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121333 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121334 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121335 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121336 + */
121337 +
121338 +#include "lnxwrp_sysfs.h"
121339 +#include "lnxwrp_fm.h"
121340 +#include "debug_ext.h"
121341 +#include "lnxwrp_sysfs_fm_port.h"
121342 +#include "lnxwrp_sysfs_fm.h"
121343 +
121344 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
121345 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
121346 +
121347 +#if defined(__ERR_MODULE__)
121348 +#undef __ERR_MODULE__
121349 +#endif
121350 +
121351 +#include "../../sdk_fman/Peripherals/FM/fm.h"
121352 +
121353 +static const struct sysfs_stats_t portSysfsStats[] = {
121354 + /* RX/TX/OH common statistics */
121355 + {
121356 + .stat_name = "port_frame",
121357 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
121358 + },
121359 + {
121360 + .stat_name = "port_discard_frame",
121361 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
121362 + },
121363 + {
121364 + .stat_name = "port_dealloc_buf",
121365 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
121366 + },
121367 + {
121368 + .stat_name = "port_enq_total",
121369 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
121370 + },
121371 + /* TX/OH */
121372 + {
121373 + .stat_name = "port_length_err",
121374 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
121375 + },
121376 + {
121377 + .stat_name = "port_unsupprted_format",
121378 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
121379 + },
121380 + {
121381 + .stat_name = "port_deq_total",
121382 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
121383 + },
121384 + {
121385 + .stat_name = "port_deq_from_default",
121386 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
121387 + },
121388 + {
121389 + .stat_name = "port_deq_confirm",
121390 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
121391 + },
121392 + /* RX/OH */
121393 + {
121394 + .stat_name = "port_rx_bad_frame",
121395 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
121396 + },
121397 + {
121398 + .stat_name = "port_rx_large_frame",
121399 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
121400 + },
121401 + {
121402 + .stat_name = "port_rx_out_of_buffers_discard",
121403 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
121404 + },
121405 + {
121406 + .stat_name = "port_rx_filter_frame",
121407 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
121408 + },
121409 + /* TODO: Particular statistics for OH ports */
121410 + {}
121411 +};
121412 +
121413 +static ssize_t show_fm_port_stats(struct device *dev,
121414 + struct device_attribute *attr, char *buf)
121415 +{
121416 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121417 + t_LnxWrpFmDev *p_LnxWrpFmDev;
121418 + unsigned long flags;
121419 + int n = 0;
121420 + uint8_t counter = 0;
121421 +
121422 + if (attr == NULL || buf == NULL || dev == NULL)
121423 + return -EINVAL;
121424 +
121425 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121426 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121427 + return -EINVAL;
121428 +
121429 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
121430 + if (WARN_ON(p_LnxWrpFmDev == NULL))
121431 + return -EINVAL;
121432 +
121433 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
121434 + return -EIO;
121435 +
121436 + if (!p_LnxWrpFmPortDev->h_Dev) {
121437 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121438 + return n;
121439 + }
121440 +
121441 + counter = fm_find_statistic_counter_by_name(
121442 + attr->attr.name,
121443 + portSysfsStats, NULL);
121444 +
121445 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
121446 + uint32_t fmRev = 0;
121447 + fmRev = 0xffff &
121448 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
121449 + 0x000c30c4));
121450 +
121451 + if (fmRev == 0x0100) {
121452 + local_irq_save(flags);
121453 + n = snprintf(buf, PAGE_SIZE,
121454 + "counter not available for revision 1\n");
121455 + local_irq_restore(flags);
121456 + }
121457 + return n;
121458 + }
121459 +
121460 + local_irq_save(flags);
121461 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
121462 + p_LnxWrpFmPortDev->name,
121463 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
121464 + (e_FmPortCounters) counter));
121465 + local_irq_restore(flags);
121466 +
121467 + return n;
121468 +}
121469 +
121470 +/* FM PORT RX/TX/OH statistics */
121471 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
121472 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
121473 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
121474 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
121475 +/* FM PORT TX/OH statistics */
121476 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
121477 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
121478 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
121479 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
121480 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
121481 +/* FM PORT RX/OH statistics */
121482 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
121483 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
121484 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
121485 + show_fm_port_stats, NULL);
121486 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
121487 +
121488 +/* FM PORT TX statistics */
121489 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
121490 + &dev_attr_port_frame.attr,
121491 + &dev_attr_port_discard_frame.attr,
121492 + &dev_attr_port_dealloc_buf.attr,
121493 + &dev_attr_port_enq_total.attr,
121494 + &dev_attr_port_length_err.attr,
121495 + &dev_attr_port_unsupprted_format.attr,
121496 + &dev_attr_port_deq_total.attr,
121497 + &dev_attr_port_deq_from_default.attr,
121498 + &dev_attr_port_deq_confirm.attr,
121499 + NULL
121500 +};
121501 +
121502 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
121503 + .name = "statistics",
121504 + .attrs = fm_tx_port_dev_stats_attributes
121505 +};
121506 +
121507 +/* FM PORT RX statistics */
121508 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
121509 + &dev_attr_port_frame.attr,
121510 + &dev_attr_port_discard_frame.attr,
121511 + &dev_attr_port_dealloc_buf.attr,
121512 + &dev_attr_port_enq_total.attr,
121513 + &dev_attr_port_rx_bad_frame.attr,
121514 + &dev_attr_port_rx_large_frame.attr,
121515 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121516 + &dev_attr_port_rx_filter_frame.attr,
121517 + NULL
121518 +};
121519 +
121520 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
121521 + .name = "statistics",
121522 + .attrs = fm_rx_port_dev_stats_attributes
121523 +};
121524 +
121525 +/* TODO: add particular OH ports statistics */
121526 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
121527 + &dev_attr_port_frame.attr,
121528 + &dev_attr_port_discard_frame.attr,
121529 + &dev_attr_port_dealloc_buf.attr,
121530 + &dev_attr_port_enq_total.attr,
121531 + /*TX*/ &dev_attr_port_length_err.attr,
121532 + &dev_attr_port_unsupprted_format.attr,
121533 + &dev_attr_port_deq_total.attr,
121534 + &dev_attr_port_deq_from_default.attr,
121535 + &dev_attr_port_deq_confirm.attr,
121536 + /* &dev_attr_port_rx_bad_frame.attr, */
121537 + /* &dev_attr_port_rx_large_frame.attr, */
121538 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121539 + /*&dev_attr_port_rx_filter_frame.attr, */
121540 + NULL
121541 +};
121542 +
121543 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
121544 + .name = "statistics",
121545 + .attrs = fm_oh_port_dev_stats_attributes
121546 +};
121547 +
121548 +static ssize_t show_fm_port_regs(struct device *dev,
121549 + struct device_attribute *attr, char *buf)
121550 +{
121551 + unsigned long flags;
121552 + unsigned n = 0;
121553 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121554 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121555 +#endif
121556 + if (attr == NULL || buf == NULL || dev == NULL)
121557 + return -EINVAL;
121558 +
121559 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121560 + p_LnxWrpFmPortDev =
121561 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121562 +
121563 +
121564 + local_irq_save(flags);
121565 +
121566 + if (!p_LnxWrpFmPortDev->h_Dev) {
121567 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121568 + return n;
121569 + } else {
121570 + n = snprintf(buf, PAGE_SIZE,
121571 + "FM port driver registers dump.\n");
121572 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121573 + }
121574 +
121575 + local_irq_restore(flags);
121576 +
121577 + return n;
121578 +#else
121579 +
121580 + local_irq_save(flags);
121581 + n = snprintf(buf, PAGE_SIZE,
121582 + "Debug level is too low to dump registers!!!\n");
121583 + local_irq_restore(flags);
121584 +
121585 + return n;
121586 +#endif
121587 +}
121588 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
121589 +{
121590 + t_FmPort *p_FmPort;
121591 + t_Fm *p_Fm;
121592 + uint8_t hardwarePortId;
121593 + uint32_t *param_page;
121594 + t_ArCommonDesc *ArCommonDescPtr;
121595 + uint32_t *mem;
121596 + int i, n = nn;
121597 +
121598 + p_FmPort = (t_FmPort *)h_dev;
121599 + hardwarePortId = p_FmPort->hardwarePortId;
121600 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121601 +
121602 + if (!FM_PORT_IsInDsar(p_FmPort))
121603 + {
121604 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121605 + hardwarePortId);
121606 + return n;
121607 + }
121608 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
121609 + FM_DMP_LN(buf, n, "========================\n");
121610 +
121611 + /* do I need request_mem_region here? */
121612 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121613 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
121614 + mem = (uint32_t*)ArCommonDescPtr;
121615 + for (i = 0; i < 300; i+=4)
121616 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
121617 + iounmap(ArCommonDescPtr);
121618 + iounmap(param_page);
121619 + return n;
121620 +}
121621 +
121622 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121623 +{
121624 + t_FmPort *p_FmPort;
121625 + t_Fm *p_Fm;
121626 + uint8_t hardwarePortId;
121627 + uint32_t *param_page;
121628 + t_ArCommonDesc *ArCommonDescPtr;
121629 + int i, n = nn;
121630 +
121631 + p_FmPort = (t_FmPort *)h_dev;
121632 + hardwarePortId = p_FmPort->hardwarePortId;
121633 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121634 +
121635 + if (!FM_PORT_IsInDsar(p_FmPort))
121636 + {
121637 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121638 + hardwarePortId);
121639 + return n;
121640 + }
121641 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121642 + FM_DMP_LN(buf, n, "========================\n");
121643 +
121644 + /* do I need request_mem_region here? */
121645 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121646 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121647 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121648 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121649 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121650 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121651 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121652 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121653 + ArCommonDescPtr->macStationAddr[5]);
121654 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121655 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121656 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121657 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121658 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121659 + if (ArCommonDescPtr->p_ArStats)
121660 + {
121661 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121662 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121663 + p_FmPort->fmMuramPhysBaseAddr,
121664 + sizeof (t_ArStatistics));
121665 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121666 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121667 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121668 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121669 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121670 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121671 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121672 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121673 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121674 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121675 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121676 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121677 +
121678 + iounmap(arStatistics);
121679 + }
121680 + if (ArCommonDescPtr->p_ArpDescriptor)
121681 + {
121682 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121683 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121684 + p_FmPort->fmMuramPhysBaseAddr,
121685 + sizeof (t_DsarArpDescriptor));
121686 + FM_DMP_LN(buf, n, "\nARP\n");
121687 + FM_DMP_LN(buf, n, "===\n");
121688 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121689 + if (ArpDescriptor->numOfBindings)
121690 + {
121691 + char ip_str[100];
121692 + t_DsarArpBindingEntry* bindings = ioremap(
121693 + ioread32be(&ArpDescriptor->p_Bindings) +
121694 + p_FmPort->fmMuramPhysBaseAddr,
121695 + ArpDescriptor->numOfBindings *
121696 + sizeof(t_DsarArpBindingEntry));
121697 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121698 + FM_DMP_LN(buf, n, " ip vlan id\n");
121699 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121700 + {
121701 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121702 + ip_addr[0], ip_addr[1],
121703 + ip_addr[2], ip_addr[3]);
121704 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121705 + ip_str, bindings->vlanId);
121706 + }
121707 + iounmap(bindings);
121708 + }
121709 + if (ArpDescriptor->p_Statistics)
121710 + {
121711 + t_DsarArpStatistics* arpStats = ioremap(
121712 + ioread32be(&ArpDescriptor->p_Statistics) +
121713 + p_FmPort->fmMuramPhysBaseAddr,
121714 + sizeof(t_DsarArpStatistics));
121715 + FM_DMP_LN(buf, n, "statistics\n");
121716 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121717 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121718 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121719 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121720 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121721 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121722 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121723 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121724 + iounmap(arpStats);
121725 + }
121726 +
121727 + iounmap(ArpDescriptor);
121728 + }
121729 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121730 + {
121731 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121732 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121733 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121734 + p_FmPort->fmMuramPhysBaseAddr,
121735 + sizeof (t_DsarIcmpV4Descriptor));
121736 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121737 + FM_DMP_LN(buf, n, "===========\n");
121738 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121739 + if (ICMPV4Descriptor->numOfBindings)
121740 + {
121741 + char ip_str[100];
121742 + t_DsarArpBindingEntry* bindings = ioremap(
121743 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121744 + p_FmPort->fmMuramPhysBaseAddr,
121745 + ICMPV4Descriptor->numOfBindings *
121746 + sizeof(t_DsarArpBindingEntry));
121747 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121748 + FM_DMP_LN(buf, n, " ip vlan id\n");
121749 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121750 + {
121751 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121752 + ip_addr[0], ip_addr[1],
121753 + ip_addr[2], ip_addr[3]);
121754 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121755 + ip_str, bindings->vlanId);
121756 + }
121757 + iounmap(bindings);
121758 + }
121759 + if (ICMPV4Descriptor->p_Statistics)
121760 + {
121761 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121762 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121763 + p_FmPort->fmMuramPhysBaseAddr,
121764 + sizeof(t_DsarIcmpV4Statistics));
121765 + FM_DMP_LN(buf, n, "statistics\n");
121766 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121767 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121768 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121769 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121770 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121771 + iounmap(icmpv4Stats);
121772 + }
121773 + iounmap(ICMPV4Descriptor);
121774 + }
121775 + if (ArCommonDescPtr->p_NdDescriptor)
121776 + {
121777 + t_DsarNdDescriptor *NDDescriptor =
121778 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121779 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121780 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121781 + FM_DMP_LN(buf, n, "\nNDP\n");
121782 + FM_DMP_LN(buf, n, "===\n");
121783 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121784 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121785 + if (NDDescriptor->numOfBindings)
121786 + {
121787 + char ip_str[100];
121788 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121789 + ioread32be(&NDDescriptor->p_Bindings) +
121790 + p_FmPort->fmMuramPhysBaseAddr,
121791 + NDDescriptor->numOfBindings *
121792 + sizeof(t_DsarIcmpV6BindingEntry));
121793 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121794 + FM_DMP_LN(buf, n, " ip vlan id\n");
121795 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121796 + {
121797 + n += snprintf(ip_str, 100,
121798 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121799 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121800 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121801 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121802 + }
121803 + iounmap(bindings);
121804 + }
121805 + if (NDDescriptor->p_Statistics)
121806 + {
121807 + t_NdStatistics* ndStats = ioremap(
121808 + ioread32be(&NDDescriptor->p_Statistics) +
121809 + p_FmPort->fmMuramPhysBaseAddr,
121810 + sizeof(t_NdStatistics));
121811 + FM_DMP_LN(buf, n, "statistics\n");
121812 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
121813 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
121814 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
121815 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
121816 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
121817 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
121818 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
121819 + iounmap(ndStats);
121820 + }
121821 + iounmap(NDDescriptor);
121822 + }
121823 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
121824 + {
121825 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
121826 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
121827 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
121828 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
121829 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
121830 + FM_DMP_LN(buf, n, "===========\n");
121831 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
121832 + if (ICMPV6Descriptor->numOfBindings)
121833 + {
121834 + char ip_str[100];
121835 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121836 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
121837 + p_FmPort->fmMuramPhysBaseAddr,
121838 + ICMPV6Descriptor->numOfBindings *
121839 + sizeof(t_DsarIcmpV6BindingEntry));
121840 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121841 + FM_DMP_LN(buf, n, " ip vlan id\n");
121842 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
121843 + {
121844 + n += snprintf(ip_str, 100,
121845 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121846 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121847 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121848 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121849 + }
121850 + iounmap(bindings);
121851 + }
121852 + if (ICMPV6Descriptor->p_Statistics)
121853 + {
121854 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
121855 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
121856 + p_FmPort->fmMuramPhysBaseAddr,
121857 + sizeof(t_DsarIcmpV6Statistics));
121858 + FM_DMP_LN(buf, n, "statistics\n");
121859 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
121860 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
121861 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
121862 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
121863 + iounmap(icmpv6Stats);
121864 + }
121865 + iounmap(ICMPV6Descriptor);
121866 + }
121867 + if (ArCommonDescPtr->p_SnmpDescriptor)
121868 + {
121869 + t_DsarSnmpDescriptor *SnmpDescriptor =
121870 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
121871 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
121872 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
121873 + FM_DMP_LN(buf, n, "\nSNMP\n");
121874 + FM_DMP_LN(buf, n, "===========\n");
121875 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
121876 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
121877 + if (SnmpDescriptor->numOfIpv4Addresses)
121878 + {
121879 + char ip_str[100];
121880 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
121881 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
121882 + p_FmPort->fmMuramPhysBaseAddr,
121883 + SnmpDescriptor->numOfIpv4Addresses *
121884 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
121885 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
121886 + FM_DMP_LN(buf, n, " ip vlan id\n");
121887 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
121888 + {
121889 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121890 + ip_addr[0], ip_addr[1],
121891 + ip_addr[2], ip_addr[3]);
121892 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
121893 + }
121894 + iounmap(addrs);
121895 + }
121896 + if (SnmpDescriptor->p_Statistics)
121897 + {
121898 + t_DsarSnmpStatistics* snmpStats = ioremap(
121899 + ioread32be(&SnmpDescriptor->p_Statistics) +
121900 + p_FmPort->fmMuramPhysBaseAddr,
121901 + sizeof(t_DsarSnmpStatistics));
121902 + FM_DMP_LN(buf, n, "statistics\n");
121903 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
121904 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
121905 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
121906 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
121907 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
121908 + iounmap(snmpStats);
121909 + }
121910 + iounmap(SnmpDescriptor);
121911 + }
121912 + iounmap(ArCommonDescPtr);
121913 + iounmap(param_page);
121914 + return n;
121915 +}
121916 +
121917 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
121918 + struct device_attribute *attr, char *buf)
121919 +{
121920 + unsigned long flags;
121921 + unsigned n = 0;
121922 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121923 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121924 +#endif
121925 + if (attr == NULL || buf == NULL || dev == NULL)
121926 + return -EINVAL;
121927 +
121928 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121929 + p_LnxWrpFmPortDev =
121930 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121931 +
121932 + local_irq_save(flags);
121933 +
121934 + if (!p_LnxWrpFmPortDev->h_Dev) {
121935 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121936 + return n;
121937 + } else {
121938 + n = snprintf(buf, PAGE_SIZE,
121939 + "FM port driver registers dump.\n");
121940 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
121941 + }
121942 +
121943 + local_irq_restore(flags);
121944 +
121945 + return n;
121946 +#else
121947 +
121948 + local_irq_save(flags);
121949 + n = snprintf(buf, PAGE_SIZE,
121950 + "Debug level is too low to dump registers!!!\n");
121951 + local_irq_restore(flags);
121952 +
121953 + return n;
121954 +#endif
121955 +}
121956 +
121957 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
121958 + struct device_attribute *attr, char *buf)
121959 +{
121960 + unsigned long flags;
121961 + unsigned n = 0;
121962 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121963 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121964 +#endif
121965 + if (attr == NULL || buf == NULL || dev == NULL)
121966 + return -EINVAL;
121967 +
121968 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121969 + p_LnxWrpFmPortDev =
121970 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121971 +
121972 + local_irq_save(flags);
121973 +
121974 + if (!p_LnxWrpFmPortDev->h_Dev) {
121975 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121976 + return n;
121977 + } else {
121978 + n = snprintf(buf, PAGE_SIZE,
121979 + "FM port driver registers dump.\n");
121980 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121981 + }
121982 +
121983 + local_irq_restore(flags);
121984 +
121985 + return n;
121986 +#else
121987 +
121988 + local_irq_save(flags);
121989 + n = snprintf(buf, PAGE_SIZE,
121990 + "Debug level is too low to dump registers!!!\n");
121991 + local_irq_restore(flags);
121992 +
121993 + return n;
121994 +#endif
121995 +}
121996 +
121997 +#if (DPAA_VERSION >= 11)
121998 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
121999 + struct device_attribute *attr, char *buf)
122000 +{
122001 + unsigned long flags;
122002 + unsigned n = 0;
122003 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122004 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122005 +#endif
122006 +
122007 + if (attr == NULL || buf == NULL || dev == NULL)
122008 + return -EINVAL;
122009 +
122010 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122011 + p_LnxWrpFmPortDev =
122012 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122013 +
122014 + local_irq_save(flags);
122015 +
122016 + if (!p_LnxWrpFmPortDev->h_Dev) {
122017 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122018 + return n;
122019 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
122020 + == NULL) {
122021 + n = snprintf(buf, PAGE_SIZE,
122022 + "\tPort: FMan-controller params page not set\n");
122023 + return n;
122024 + } else {
122025 + n = snprintf(buf, PAGE_SIZE,
122026 + "Counter for fragmented pkt with IP header options\n");
122027 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
122028 + }
122029 +
122030 + local_irq_restore(flags);
122031 +
122032 + return n;
122033 +#else
122034 +
122035 + local_irq_save(flags);
122036 + n = snprintf(buf, PAGE_SIZE,
122037 + "Debug level is too low to dump registers!!!\n");
122038 + local_irq_restore(flags);
122039 +
122040 + return n;
122041 +#endif
122042 +}
122043 +
122044 +#endif
122045 +
122046 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
122047 + struct device_attribute *attr, char *buf)
122048 +{
122049 + unsigned long flags;
122050 + unsigned n = 0;
122051 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122052 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122053 +#endif
122054 +
122055 + if (attr == NULL || buf == NULL || dev == NULL)
122056 + return -EINVAL;
122057 +
122058 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122059 + p_LnxWrpFmPortDev =
122060 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122061 +
122062 + local_irq_save(flags);
122063 +
122064 + if (!p_LnxWrpFmPortDev->h_Dev) {
122065 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122066 + return n;
122067 + } else {
122068 + n = snprintf(buf, PAGE_SIZE,
122069 + "FM port driver registers dump.\n");
122070 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
122071 + }
122072 +
122073 + local_irq_restore(flags);
122074 +
122075 + return n;
122076 +#else
122077 +
122078 + local_irq_save(flags);
122079 + n = snprintf(buf, PAGE_SIZE,
122080 + "Debug level is too low to dump registers!!!\n");
122081 + local_irq_restore(flags);
122082 +
122083 + return n;
122084 +#endif
122085 +}
122086 +
122087 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
122088 + struct device_attribute *attr, char *buf)
122089 +{
122090 + unsigned long flags;
122091 + unsigned n = 0;
122092 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122093 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122094 +#endif
122095 +
122096 + if (attr == NULL || buf == NULL || dev == NULL)
122097 + return -EINVAL;
122098 +
122099 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122100 + p_LnxWrpFmPortDev =
122101 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122102 +
122103 + local_irq_save(flags);
122104 +
122105 + if (!p_LnxWrpFmPortDev->h_Dev) {
122106 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122107 + return n;
122108 + } else {
122109 + n = snprintf(buf, PAGE_SIZE,
122110 + "FM port driver registers dump.\n");
122111 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
122112 + }
122113 +
122114 + local_irq_restore(flags);
122115 +
122116 + return n;
122117 +#else
122118 +
122119 + local_irq_save(flags);
122120 + n = snprintf(buf, PAGE_SIZE,
122121 + "Debug level is too low to dump registers!!!\n");
122122 + local_irq_restore(flags);
122123 +
122124 + return n;
122125 +#endif
122126 +}
122127 +
122128 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
122129 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
122130 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
122131 +#if (DPAA_VERSION >= 11)
122132 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
122133 +#endif
122134 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
122135 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
122136 +
122137 +int fm_port_sysfs_create(struct device *dev)
122138 +{
122139 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122140 +
122141 + if (dev == NULL)
122142 + return -EINVAL;
122143 +
122144 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122145 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122146 + return -EINVAL;
122147 +
122148 + /* store to remove them when module is disabled */
122149 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
122150 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
122151 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
122152 +#if (DPAA_VERSION >= 11)
122153 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
122154 +#endif
122155 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
122156 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
122157 + /* Registers dump entry - in future will be moved to debugfs */
122158 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
122159 + return -EIO;
122160 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
122161 + return -EIO;
122162 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
122163 + return -EIO;
122164 +#if (DPAA_VERSION >= 11)
122165 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
122166 + return -EIO;
122167 +#endif
122168 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
122169 + return -EIO;
122170 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
122171 + return -EIO;
122172 +
122173 + /* FM Ports statistics */
122174 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122175 + case e_FM_PORT_TYPE_TX:
122176 + case e_FM_PORT_TYPE_TX_10G:
122177 + if (sysfs_create_group
122178 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
122179 + return -EIO;
122180 + break;
122181 + case e_FM_PORT_TYPE_RX:
122182 + case e_FM_PORT_TYPE_RX_10G:
122183 + if (sysfs_create_group
122184 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
122185 + return -EIO;
122186 + break;
122187 + case e_FM_PORT_TYPE_DUMMY:
122188 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122189 + if (sysfs_create_group
122190 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
122191 + return -EIO;
122192 + break;
122193 + default:
122194 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122195 + __func__);
122196 + return -EINVAL;
122197 + break;
122198 + };
122199 +
122200 + return 0;
122201 +}
122202 +
122203 +void fm_port_sysfs_destroy(struct device *dev)
122204 +{
122205 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
122206 +
122207 + /* this function has never been tested !!! */
122208 +
122209 + if (WARN_ON(dev == NULL))
122210 + return;
122211 +
122212 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122213 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122214 + return;
122215 +
122216 + /* The name attribute will be freed also by these 2 functions? */
122217 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122218 + case e_FM_PORT_TYPE_TX:
122219 + case e_FM_PORT_TYPE_TX_10G:
122220 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
122221 + break;
122222 + case e_FM_PORT_TYPE_RX:
122223 + case e_FM_PORT_TYPE_RX_10G:
122224 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
122225 + break;
122226 + case e_FM_PORT_TYPE_DUMMY:
122227 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122228 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
122229 + break;
122230 + default:
122231 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122232 + __func__);
122233 + break;
122234 + };
122235 +
122236 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
122237 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
122238 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
122239 +#if (DPAA_VERSION >= 11)
122240 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
122241 +#endif
122242 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
122243 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
122244 +}
122245 +
122246 +
122247 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
122248 +{
122249 + t_FmPort *p_FmPort;
122250 + t_Fm *p_Fm;
122251 + uint8_t hardwarePortId;
122252 + int n = nn;
122253 +
122254 + p_FmPort = (t_FmPort *)h_dev;
122255 + hardwarePortId = p_FmPort->hardwarePortId;
122256 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
122257 +
122258 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
122259 + "fmbm_pp for port %u", hardwarePortId);
122260 + FM_DMP_MEM_32(buf, n,
122261 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
122262 +
122263 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
122264 + "fmbm_pfs for port %u", hardwarePortId);
122265 + FM_DMP_MEM_32(buf, n,
122266 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
122267 +
122268 + FM_DMP_TITLE(buf, n,
122269 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
122270 + "fmbm_spliodn for port %u", hardwarePortId);
122271 + FM_DMP_MEM_32(buf, n,
122272 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
122273 +
122274 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
122275 + "fmfp_psfor port %u", hardwarePortId);
122276 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
122277 +
122278 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
122279 + "fmdmplrfor port %u", hardwarePortId);
122280 + FM_DMP_MEM_32(buf, n,
122281 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
122282 + return n;
122283 +}
122284 +
122285 +#if (DPAA_VERSION >= 11)
122286 +
122287 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
122288 +{
122289 + t_FmPort *p_FmPort;
122290 + int n = nn;
122291 +
122292 + p_FmPort = (t_FmPort *)h_dev;
122293 +
122294 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
122295 +
122296 + FM_DMP_SUBTITLE(buf, n, "\n");
122297 +
122298 + return n;
122299 +}
122300 +#endif
122301 +
122302 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
122303 +{
122304 + t_FmPort *p_FmPort;
122305 + u_FmPortBmiRegs *p_bmi;
122306 +
122307 + char arr[20];
122308 + uint8_t flag;
122309 + int i = 0;
122310 + int n = nn;
122311 +
122312 + p_FmPort = (t_FmPort *)h_dev;
122313 + p_bmi = p_FmPort->p_FmPortBmiRegs;
122314 +
122315 + memset(arr, 0, sizeof(arr));
122316 + switch (p_FmPort->portType) {
122317 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
122318 + strcpy(arr, "OFFLINE-PARSING");
122319 + flag = 0;
122320 + break;
122321 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
122322 + strcpy(arr, "HOST-COMMAND");
122323 + flag = 0;
122324 + break;
122325 + case (e_FM_PORT_TYPE_RX):
122326 + strcpy(arr, "RX");
122327 + flag = 1;
122328 + break;
122329 + case (e_FM_PORT_TYPE_RX_10G):
122330 + strcpy(arr, "RX-10G");
122331 + flag = 1;
122332 + break;
122333 + case (e_FM_PORT_TYPE_TX):
122334 + strcpy(arr, "TX");
122335 + flag = 2;
122336 + break;
122337 + case (e_FM_PORT_TYPE_TX_10G):
122338 + strcpy(arr, "TX-10G");
122339 + flag = 2;
122340 + break;
122341 + default:
122342 + return -EINVAL;
122343 + }
122344 +
122345 + FM_DMP_TITLE(buf, n, NULL,
122346 + "FMan-Port (%s #%d) registers:",
122347 + arr, p_FmPort->portId);
122348 +
122349 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
122350 +
122351 + switch (flag) {
122352 + case (0):
122353 + FM_DMP_SUBTITLE(buf, n, "\n");
122354 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
122355 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
122356 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
122357 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
122358 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
122359 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
122360 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
122361 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
122362 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
122363 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
122364 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
122365 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
122366 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
122367 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
122368 +
122369 + FM_DMP_TITLE(buf, n,
122370 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
122371 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122372 + FM_DMP_MEM_32(buf, n,
122373 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
122374 + }
122375 + FM_DMP_SUBTITLE(buf, n, "\n");
122376 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
122377 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
122378 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
122379 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
122380 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
122381 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
122382 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
122383 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
122384 + {
122385 +#ifndef FM_NO_OP_OBSERVED_POOLS
122386 + if (p_FmPort->fmRevInfo.majorRev == 4) {
122387 + FM_DMP_TITLE(buf, n,
122388 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
122389 + "fmbm_oebmpi");
122390 +
122391 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
122392 + FM_DMP_MEM_32(buf, n,
122393 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
122394 + }
122395 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
122396 + }
122397 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
122398 + }
122399 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
122400 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
122401 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
122402 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
122403 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
122404 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
122405 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
122406 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
122407 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
122408 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
122409 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
122410 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
122411 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
122412 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
122413 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
122414 + "fmbm_odcfg");
122415 + for (i = 0; i < 3; ++i) {
122416 + FM_DMP_MEM_32(buf, n,
122417 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
122418 + }
122419 + FM_DMP_SUBTITLE(buf, n, "\n");
122420 +
122421 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
122422 + break;
122423 + case (1):
122424 + FM_DMP_SUBTITLE(buf, n, "\n");
122425 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
122426 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
122427 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
122428 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
122429 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
122430 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
122431 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
122432 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
122433 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
122434 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
122435 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
122436 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
122437 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
122438 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
122439 + "fmbm_rprai");
122440 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122441 + FM_DMP_MEM_32(buf, n,
122442 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
122443 + }
122444 + FM_DMP_SUBTITLE(buf, n, "\n");
122445 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
122446 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
122447 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
122448 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
122449 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
122450 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
122451 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
122452 + "fmbm_ebmpi");
122453 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122454 + FM_DMP_MEM_32(buf, n,
122455 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
122456 + }
122457 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
122458 + "fmbm_acnt");
122459 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122460 + FM_DMP_MEM_32(buf, n,
122461 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
122462 + }
122463 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
122464 + "fmbm_rcgm");
122465 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
122466 + FM_DMP_MEM_32(buf, n,
122467 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
122468 + }
122469 +
122470 + FM_DMP_SUBTITLE(buf, n, "\n");
122471 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
122472 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
122473 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
122474 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
122475 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
122476 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
122477 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
122478 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
122479 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
122480 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
122481 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
122482 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
122483 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
122484 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
122485 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
122486 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
122487 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
122488 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
122489 + "fmbm_rdcfg");
122490 + for (i = 0; i < 3; ++i) {
122491 + FM_DMP_MEM_32(buf, n,
122492 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
122493 + }
122494 + FM_DMP_SUBTITLE(buf, n, "\n");
122495 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
122496 + break;
122497 + case (2):
122498 + FM_DMP_SUBTITLE(buf, n, "\n");
122499 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
122500 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
122501 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
122502 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
122503 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
122504 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
122505 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
122506 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
122507 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
122508 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
122509 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
122510 +#if (DPAA_VERSION >= 11)
122511 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
122512 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
122513 +#endif /* (DPAA_VERSION >= 11) */
122514 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
122515 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
122516 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
122517 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
122518 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
122519 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
122520 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
122521 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
122522 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
122523 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
122524 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
122525 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
122526 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
122527 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
122528 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
122529 + "fmbm_tdcfg");
122530 + for (i = 0; i < 3 ; ++i) {
122531 + FM_DMP_MEM_32(buf, n,
122532 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
122533 + }
122534 + FM_DMP_SUBTITLE(buf, n, "\n");
122535 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
122536 + break;
122537 + }
122538 +
122539 + FM_DMP_SUBTITLE(buf, n, "\n");
122540 +
122541 + return n;
122542 +}
122543 +
122544 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
122545 +{
122546 + t_FmPort *p_FmPort;
122547 + int n = nn;
122548 +
122549 + p_FmPort = (t_FmPort *)h_dev;
122550 +
122551 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
122552 +
122553 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
122554 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
122555 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
122556 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
122557 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
122558 + FM_DMP_V32(buf, n,
122559 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
122560 + FM_DMP_V32(buf, n,
122561 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
122562 + FM_DMP_V32(buf, n,
122563 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
122564 + FM_DMP_V32(buf, n,
122565 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
122566 + FM_DMP_V32(buf, n,
122567 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
122568 +
122569 + FM_DMP_SUBTITLE(buf, n, "\n");
122570 +
122571 + return n;
122572 +}
122573 +
122574 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122575 new file mode 100644
122576 index 00000000..1e7636f4
122577 --- /dev/null
122578 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122579 @@ -0,0 +1,56 @@
122580 +/*
122581 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122582 + *
122583 + * Redistribution and use in source and binary forms, with or without
122584 + * modification, are permitted provided that the following conditions are met:
122585 + * * Redistributions of source code must retain the above copyright
122586 + * notice, this list of conditions and the following disclaimer.
122587 + * * Redistributions in binary form must reproduce the above copyright
122588 + * notice, this list of conditions and the following disclaimer in the
122589 + * documentation and/or other materials provided with the distribution.
122590 + * * Neither the name of Freescale Semiconductor nor the
122591 + * names of its contributors may be used to endorse or promote products
122592 + * derived from this software without specific prior written permission.
122593 + *
122594 + *
122595 + * ALTERNATIVELY, this software may be distributed under the terms of the
122596 + * GNU General Public License ("GPL") as published by the Free Software
122597 + * Foundation, either version 2 of that License or (at your option) any
122598 + * later version.
122599 + *
122600 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122601 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122602 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122603 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122604 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122605 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122606 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122607 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122608 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122609 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122610 + */
122611 +
122612 +/*
122613 + @File lnxwrp_sysfs_fm_port.h
122614 +
122615 + @Description FM port sysfs functions.
122616 +
122617 +*/
122618 +
122619 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
122620 +#define LNXWRP_SYSFS_FM_PORT_H_
122621 +
122622 +#include "lnxwrp_sysfs.h"
122623 +
122624 +int fm_port_sysfs_create(struct device *dev);
122625 +void fm_port_sysfs_destroy(struct device *dev);
122626 +
122627 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122628 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122629 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122630 +
122631 +#if (DPAA_VERSION >= 11)
122632 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122633 +#endif
122634 +
122635 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122636 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122637 new file mode 100644
122638 index 00000000..1071c22a
122639 --- /dev/null
122640 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122641 @@ -0,0 +1,18 @@
122642 +#
122643 +# Makefile for the Freescale Ethernet controllers
122644 +#
122645 +ccflags-y += -DVERSION=\"\"
122646 +#
122647 +#Include netcomm SW specific definitions
122648 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122649 +
122650 +obj-y += fsl-ncsw-xx.o
122651 +
122652 +ifneq ($(CONFIG_FMAN_ARM),y)
122653 +fsl-ncsw-xx-objs := xx_linux.o \
122654 + module_strings.o
122655 +else
122656 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122657 + module_strings.o
122658 +endif
122659 +
122660 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122661 new file mode 100644
122662 index 00000000..d7fed170
122663 --- /dev/null
122664 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122665 @@ -0,0 +1,46 @@
122666 +/*
122667 + * Copyright 2012 Freescale Semiconductor Inc.
122668 + *
122669 + * Redistribution and use in source and binary forms, with or without
122670 + * modification, are permitted provided that the following conditions are met:
122671 + * * Redistributions of source code must retain the above copyright
122672 + * notice, this list of conditions and the following disclaimer.
122673 + * * Redistributions in binary form must reproduce the above copyright
122674 + * notice, this list of conditions and the following disclaimer in the
122675 + * documentation and/or other materials provided with the distribution.
122676 + * * Neither the name of Freescale Semiconductor nor the
122677 + * names of its contributors may be used to endorse or promote products
122678 + * derived from this software without specific prior written permission.
122679 + *
122680 + *
122681 + * ALTERNATIVELY, this software may be distributed under the terms of the
122682 + * GNU General Public License ("GPL") as published by the Free Software
122683 + * Foundation, either version 2 of that License or (at your option) any
122684 + * later version.
122685 + *
122686 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122687 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122688 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122689 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122690 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122691 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122692 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122693 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122694 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122695 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122696 + */
122697 +
122698 +/* Module names for debug messages */
122699 +const char *moduleStrings[] =
122700 +{
122701 + "", /* MODULE_UNKNOWN */
122702 + "FM", /* MODULE_FM */
122703 + "FM-MURAM", /* MODULE_FM_MURAM */
122704 + "FM-PCD", /* MODULE_FM_PCD */
122705 + "FM-RTC", /* MODULE_FM_RTC */
122706 + "FM-MAC", /* MODULE_FM_MAC */
122707 + "FM-Port", /* MODULE_FM_PORT */
122708 + "MM", /* MODULE_MM */
122709 + "FM-SP", /* MODULE_FM_SP */
122710 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122711 +};
122712 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122713 new file mode 100644
122714 index 00000000..dd3e376e
122715 --- /dev/null
122716 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122717 @@ -0,0 +1,905 @@
122718 +/*
122719 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122720 + *
122721 + * Redistribution and use in source and binary forms, with or without
122722 + * modification, are permitted provided that the following conditions are met:
122723 + * * Redistributions of source code must retain the above copyright
122724 + * notice, this list of conditions and the following disclaimer.
122725 + * * Redistributions in binary form must reproduce the above copyright
122726 + * notice, this list of conditions and the following disclaimer in the
122727 + * documentation and/or other materials provided with the distribution.
122728 + * * Neither the name of Freescale Semiconductor nor the
122729 + * names of its contributors may be used to endorse or promote products
122730 + * derived from this software without specific prior written permission.
122731 + *
122732 + *
122733 + * ALTERNATIVELY, this software may be distributed under the terms of the
122734 + * GNU General Public License ("GPL") as published by the Free Software
122735 + * Foundation, either version 2 of that License or (at your option) any
122736 + * later version.
122737 + *
122738 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122739 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122740 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122741 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122742 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122743 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122744 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122745 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122746 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122747 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122748 + */
122749 +
122750 +/**************************************************************************//**
122751 + @File xx_arm_linux.c
122752 +
122753 + @Description XX routines implementation for Linux.
122754 +*//***************************************************************************/
122755 +#include <linux/version.h>
122756 +
122757 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122758 +#define MODVERSIONS
122759 +#endif
122760 +#ifdef MODVERSIONS
122761 +#include <config/modversions.h>
122762 +#endif /* MODVERSIONS */
122763 +
122764 +#include <linux/module.h>
122765 +#include <linux/kernel.h>
122766 +#include <linux/sched.h>
122767 +#include <linux/string.h>
122768 +#include <linux/ptrace.h>
122769 +#include <linux/errno.h>
122770 +#include <linux/ioport.h>
122771 +#include <linux/slab.h>
122772 +#include <linux/interrupt.h>
122773 +#include <linux/fs.h>
122774 +#include <linux/vmalloc.h>
122775 +#include <linux/init.h>
122776 +#include <linux/timer.h>
122777 +#include <linux/spinlock.h>
122778 +#include <linux/delay.h>
122779 +#include <linux/proc_fs.h>
122780 +#include <linux/smp.h>
122781 +#include <linux/of.h>
122782 +#include <linux/irqdomain.h>
122783 +
122784 +#include <linux/workqueue.h>
122785 +
122786 +#ifdef BIGPHYSAREA_ENABLE
122787 +#include <linux/bigphysarea.h>
122788 +#endif /* BIGPHYSAREA_ENABLE */
122789 +
122790 +//#include <sysdev/fsl_soc.h>
122791 +#include <asm/pgtable.h>
122792 +#include <asm/irq.h>
122793 +#include <asm/bitops.h>
122794 +#include <asm/uaccess.h>
122795 +#include <asm/io.h>
122796 +#include <asm/atomic.h>
122797 +#include <asm/string.h>
122798 +#include <asm/byteorder.h>
122799 +#include <asm/page.h>
122800 +
122801 +#include "error_ext.h"
122802 +#include "std_ext.h"
122803 +#include "list_ext.h"
122804 +#include "mm_ext.h"
122805 +#include "sys_io_ext.h"
122806 +#include "xx.h"
122807 +
122808 +
122809 +#define __ERR_MODULE__ MODULE_UNKNOWN
122810 +
122811 +#ifdef BIGPHYSAREA_ENABLE
122812 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
122813 +
122814 +
122815 +/* TODO: large allocations => use big phys area */
122816 +/******************************************************************************
122817 + * routine: get_nr_pages
122818 + *
122819 + * description:
122820 + * calculates the number of memory pages for a given size (in bytes)
122821 + *
122822 + * arguments:
122823 + * size - the number of bytes
122824 + *
122825 + * return code:
122826 + * The number of pages
122827 + *
122828 + *****************************************************************************/
122829 +static __inline__ uint32_t get_nr_pages (uint32_t size)
122830 +{
122831 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
122832 +}
122833 +
122834 +static bool in_big_phys_area (uint32_t addr)
122835 +{
122836 + uint32_t base, size;
122837 +
122838 + bigphysarea_get_details (&base, &size);
122839 + return ((addr >= base) && (addr < base + size));
122840 +}
122841 +#endif /* BIGPHYSAREA_ENABLE */
122842 +
122843 +void * xx_Malloc(uint32_t n)
122844 +{
122845 + void *a;
122846 + uint32_t flags;
122847 +
122848 + flags = XX_DisableAllIntr();
122849 +#ifdef BIGPHYSAREA_ENABLE
122850 + if (n >= MAX_ALLOCATION_SIZE)
122851 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
122852 + else
122853 +#endif /* BIGPHYSAREA_ENABLE */
122854 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
122855 + if (!a)
122856 + XX_Print("No memory for XX_Malloc\n");
122857 + XX_RestoreAllIntr(flags);
122858 +
122859 + return a;
122860 +}
122861 +
122862 +void xx_Free(void *p)
122863 +{
122864 +#ifdef BIGPHYSAREA_ENABLE
122865 + if (in_big_phys_area ((uint32_t)p))
122866 + bigphysarea_free_pages(p);
122867 + else
122868 +#endif /* BIGPHYSAREA_ENABLE */
122869 + kfree(p);
122870 +}
122871 +
122872 +void XX_Exit(int status)
122873 +{
122874 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
122875 +}
122876 +
122877 +#define BUF_SIZE 512
122878 +void XX_Print(char *str, ...)
122879 +{
122880 + va_list args;
122881 +#ifdef CONFIG_SMP
122882 + char buf[BUF_SIZE];
122883 +#endif /* CONFIG_SMP */
122884 +
122885 + va_start(args, str);
122886 +#ifdef CONFIG_SMP
122887 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122888 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122889 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
122890 +#else
122891 + vprintk(str, args);
122892 +#endif /* CONFIG_SMP */
122893 + va_end(args);
122894 +}
122895 +
122896 +void XX_Fprint(void *file, char *str, ...)
122897 +{
122898 + va_list args;
122899 +#ifdef CONFIG_SMP
122900 + char buf[BUF_SIZE];
122901 +#endif /* CONFIG_SMP */
122902 +
122903 + va_start(args, str);
122904 +#ifdef CONFIG_SMP
122905 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122906 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122907 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
122908 +
122909 +#else
122910 + vprintk(str, args);
122911 +#endif /* CONFIG_SMP */
122912 + va_end(args);
122913 +}
122914 +
122915 +#ifdef DEBUG_XX_MALLOC
122916 +typedef void (*t_ffn)(void *);
122917 +typedef struct {
122918 + t_ffn f_free;
122919 + void *mem;
122920 + char *fname;
122921 + int fline;
122922 + uint32_t size;
122923 + t_List node;
122924 +} t_MemDebug;
122925 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
122926 +
122927 +LIST(memDbgLst);
122928 +
122929 +
122930 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
122931 +{
122932 + void *mem;
122933 + t_MemDebug *p_MemDbg;
122934 +
122935 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
122936 + if (p_MemDbg == NULL)
122937 + return NULL;
122938 +
122939 + mem = xx_Malloc(size);
122940 + if (mem == NULL)
122941 + {
122942 + XX_Free(p_MemDbg);
122943 + return NULL;
122944 + }
122945 +
122946 + INIT_LIST(&p_MemDbg->node);
122947 + p_MemDbg->f_free = xx_Free;
122948 + p_MemDbg->mem = mem;
122949 + p_MemDbg->fname = fname;
122950 + p_MemDbg->fline = line;
122951 + p_MemDbg->size = size+sizeof(t_MemDebug);
122952 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122953 +
122954 + return mem;
122955 +}
122956 +
122957 +void * XX_MallocSmartDebug(uint32_t size,
122958 + int memPartitionId,
122959 + uint32_t align,
122960 + char *fname,
122961 + int line)
122962 +{
122963 + void *mem;
122964 + t_MemDebug *p_MemDbg;
122965 +
122966 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
122967 + if (p_MemDbg == NULL)
122968 + return NULL;
122969 +
122970 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
122971 + if (mem == NULL)
122972 + {
122973 + XX_Free(p_MemDbg);
122974 + return NULL;
122975 + }
122976 +
122977 + INIT_LIST(&p_MemDbg->node);
122978 + p_MemDbg->f_free = xx_FreeSmart;
122979 + p_MemDbg->mem = mem;
122980 + p_MemDbg->fname = fname;
122981 + p_MemDbg->fline = line;
122982 + p_MemDbg->size = size+sizeof(t_MemDebug);
122983 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122984 +
122985 + return mem;
122986 +}
122987 +
122988 +static void debug_free(void *mem)
122989 +{
122990 + t_List *p_MemDbgLh = NULL;
122991 + t_MemDebug *p_MemDbg;
122992 + bool found = FALSE;
122993 +
122994 + if (LIST_IsEmpty(&memDbgLst))
122995 + {
122996 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
122997 + return;
122998 + }
122999 +
123000 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123001 + {
123002 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123003 + if (p_MemDbg->mem == mem)
123004 + {
123005 + found = TRUE;
123006 + break;
123007 + }
123008 + }
123009 +
123010 + if (!found)
123011 + {
123012 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123013 + ("Attempt to free unallocated address (0x%08x)",mem));
123014 + dump_stack();
123015 + return;
123016 + }
123017 +
123018 + LIST_Del(p_MemDbgLh);
123019 + p_MemDbg->f_free(mem);
123020 + p_MemDbg->f_free(p_MemDbg);
123021 +}
123022 +
123023 +void XX_FreeSmart(void *p)
123024 +{
123025 + debug_free(p);
123026 +}
123027 +
123028 +
123029 +void XX_Free(void *p)
123030 +{
123031 + debug_free(p);
123032 +}
123033 +
123034 +#else /* not DEBUG_XX_MALLOC */
123035 +void * XX_Malloc(uint32_t size)
123036 +{
123037 + return xx_Malloc(size);
123038 +}
123039 +
123040 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123041 +{
123042 + return xx_MallocSmart(size,memPartitionId, alignment);
123043 +}
123044 +
123045 +void XX_FreeSmart(void *p)
123046 +{
123047 + xx_FreeSmart(p);
123048 +}
123049 +
123050 +
123051 +void XX_Free(void *p)
123052 +{
123053 + xx_Free(p);
123054 +}
123055 +#endif /* not DEBUG_XX_MALLOC */
123056 +
123057 +
123058 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123059 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123060 +{
123061 + e_Event eventCode = (e_Event)event;
123062 +
123063 + UNUSED(eventCode);
123064 + UNUSED(appId);
123065 + UNUSED(flags);
123066 + UNUSED(msg);
123067 +}
123068 +#endif /* (defined(REPORT_EVENTS) && ... */
123069 +
123070 +
123071 +uint32_t XX_DisableAllIntr(void)
123072 +{
123073 + unsigned long flags;
123074 +
123075 +#ifdef local_irq_save_nort
123076 + local_irq_save_nort(flags);
123077 +#else
123078 + local_irq_save(flags);
123079 +#endif
123080 +
123081 + return (uint32_t)flags;
123082 +}
123083 +
123084 +void XX_RestoreAllIntr(uint32_t flags)
123085 +{
123086 +#ifdef local_irq_restore_nort
123087 + local_irq_restore_nort((unsigned long)flags);
123088 +#else
123089 + local_irq_restore((unsigned long)flags);
123090 +#endif
123091 +}
123092 +
123093 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123094 +{
123095 + UNUSED(qid);
123096 + UNUSED(appId);
123097 + UNUSED(flags);
123098 +
123099 + return f(id);
123100 +}
123101 +
123102 +int XX_IsICacheEnable(void)
123103 +{
123104 + return TRUE;
123105 +}
123106 +
123107 +int XX_IsDCacheEnable(void)
123108 +{
123109 + return TRUE;
123110 +}
123111 +
123112 +
123113 +typedef struct {
123114 + t_Isr *f_Isr;
123115 + t_Handle handle;
123116 +} t_InterruptHandler;
123117 +
123118 +
123119 +t_Handle interruptHandlers[0x00010000];
123120 +
123121 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123122 +{
123123 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123124 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123125 + return IRQ_HANDLED;
123126 +}
123127 +
123128 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123129 +{
123130 + const char *device;
123131 + t_InterruptHandler *p_IntrHndl;
123132 +
123133 + device = GetDeviceName(irq);
123134 + if (device == NULL)
123135 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123136 +
123137 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123138 + if (p_IntrHndl == NULL)
123139 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123140 + p_IntrHndl->f_Isr = f_Isr;
123141 + p_IntrHndl->handle = handle;
123142 + interruptHandlers[irq] = p_IntrHndl;
123143 +
123144 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123145 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123146 + disable_irq(GetDeviceIrqNum(irq));
123147 +
123148 + return E_OK;
123149 +}
123150 +
123151 +t_Error XX_FreeIntr(int irq)
123152 +{
123153 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123154 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123155 + XX_Free(p_IntrHndl);
123156 + interruptHandlers[irq] = 0;
123157 + return E_OK;
123158 +}
123159 +
123160 +t_Error XX_EnableIntr(int irq)
123161 +{
123162 + enable_irq(GetDeviceIrqNum(irq));
123163 + return E_OK;
123164 +}
123165 +
123166 +t_Error XX_DisableIntr(int irq)
123167 +{
123168 + disable_irq(GetDeviceIrqNum(irq));
123169 + return E_OK;
123170 +}
123171 +
123172 +
123173 +/*****************************************************************************/
123174 +/* Tasklet Service Routines */
123175 +/*****************************************************************************/
123176 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123177 +typedef struct
123178 +{
123179 + t_Handle h_Data;
123180 + void (*f_Callback) (void *);
123181 + struct delayed_work dwork;
123182 +} t_Tasklet;
123183 +
123184 +static void GenericTaskletCallback(struct work_struct *p_Work)
123185 +{
123186 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123187 +
123188 + p_Task->f_Callback(p_Task->h_Data);
123189 +}
123190 +#endif /* LINUX_VERSION_CODE */
123191 +
123192 +
123193 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123194 +{
123195 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123196 + struct work_struct *p_Task;
123197 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123198 + INIT_WORK(p_Task, routine, data);
123199 +#else
123200 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123201 + p_Task->h_Data = data;
123202 + p_Task->f_Callback = routine;
123203 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123204 +#endif /* LINUX_VERSION_CODE */
123205 +
123206 + return (t_TaskletHandle)p_Task;
123207 +}
123208 +
123209 +
123210 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123211 +{
123212 + if (h_Tasklet)
123213 + XX_Free(h_Tasklet);
123214 +}
123215 +
123216 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123217 +{
123218 + int ans;
123219 +
123220 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123221 + if (immediate)
123222 + ans = schedule_work(h_Tasklet);
123223 + else
123224 + ans = schedule_delayed_work(h_Tasklet, 1);
123225 +#else
123226 + if (immediate)
123227 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123228 + else
123229 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123230 +#endif /* LINUX_VERSION_CODE */
123231 +
123232 + return ans;
123233 +}
123234 +
123235 +void XX_FlushScheduledTasks(void)
123236 +{
123237 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123238 + flush_scheduled_tasks();
123239 +#else
123240 + flush_scheduled_work();
123241 +#endif /* LINUX_VERSION_CODE */
123242 +}
123243 +
123244 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123245 +{
123246 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123247 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123248 +#else
123249 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123250 +#endif /* LINUX_VERSION_CODE */
123251 +}
123252 +
123253 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123254 +{
123255 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123256 + ((struct tq_struct *)h_Tasklet)->data = data;
123257 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123258 + ((struct work_struct *)h_Tasklet)->data = data;
123259 +#else
123260 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123261 +#endif /* LINUX_VERSION_CODE */
123262 +}
123263 +
123264 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123265 +{
123266 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123267 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123268 +#else
123269 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123270 +#endif /* LINUX_VERSION_CODE */
123271 +}
123272 +
123273 +
123274 +/*****************************************************************************/
123275 +/* Spinlock Service Routines */
123276 +/*****************************************************************************/
123277 +
123278 +t_Handle XX_InitSpinlock(void)
123279 +{
123280 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123281 + if (!p_Spinlock)
123282 + return NULL;
123283 +
123284 + spin_lock_init(p_Spinlock);
123285 +
123286 + return (t_Handle)p_Spinlock;
123287 +}
123288 +
123289 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123290 +{
123291 + if (h_Spinlock)
123292 + XX_Free(h_Spinlock);
123293 +}
123294 +
123295 +void XX_LockSpinlock(t_Handle h_Spinlock)
123296 +{
123297 + spin_lock((spinlock_t *)h_Spinlock);
123298 +}
123299 +
123300 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123301 +{
123302 + spin_unlock((spinlock_t *)h_Spinlock);
123303 +}
123304 +
123305 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123306 +{
123307 + unsigned long intrFlags;
123308 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123309 + return intrFlags;
123310 +}
123311 +
123312 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123313 +{
123314 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123315 +}
123316 +
123317 +
123318 +/*****************************************************************************/
123319 +/* Timers Service Routines */
123320 +/*****************************************************************************/
123321 +/* The time now is in mili sec. resolution */
123322 +uint32_t XX_CurrentTime(void)
123323 +{
123324 + return (jiffies*1000)/HZ;
123325 +}
123326 +
123327 +
123328 +t_Handle XX_CreateTimer(void)
123329 +{
123330 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123331 + if (p_Timer)
123332 + {
123333 + memset(p_Timer, 0, sizeof(struct timer_list));
123334 + init_timer(p_Timer);
123335 + }
123336 + return (t_Handle)p_Timer;
123337 +}
123338 +
123339 +void XX_FreeTimer(t_Handle h_Timer)
123340 +{
123341 + if (h_Timer)
123342 + XX_Free(h_Timer);
123343 +}
123344 +
123345 +void XX_StartTimer(t_Handle h_Timer,
123346 + uint32_t msecs,
123347 + bool periodic,
123348 + void (*f_TimerExpired)(t_Handle),
123349 + t_Handle h_Arg)
123350 +{
123351 + int tmp_jiffies = (msecs*HZ)/1000;
123352 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123353 +
123354 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123355 +
123356 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123357 + p_Timer->data = (unsigned long)h_Arg;
123358 + if ((msecs*HZ)%1000)
123359 + tmp_jiffies++;
123360 + p_Timer->expires = (jiffies + tmp_jiffies);
123361 +
123362 + add_timer((struct timer_list *)h_Timer);
123363 +}
123364 +
123365 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123366 +{
123367 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123368 +
123369 + p_Timer->data = (unsigned long)data;
123370 +}
123371 +
123372 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123373 +{
123374 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123375 +
123376 + return (t_Handle)p_Timer->data;
123377 +}
123378 +
123379 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123380 +{
123381 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123382 +
123383 + return (uint32_t)p_Timer->expires;
123384 +}
123385 +
123386 +void XX_StopTimer(t_Handle h_Timer)
123387 +{
123388 + del_timer((struct timer_list *)h_Timer);
123389 +}
123390 +
123391 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123392 +{
123393 + int tmp_jiffies = (msecs*HZ)/1000;
123394 +
123395 + if ((msecs*HZ)%1000)
123396 + tmp_jiffies++;
123397 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123398 +}
123399 +
123400 +int XX_TimerIsActive(t_Handle h_Timer)
123401 +{
123402 + return timer_pending((struct timer_list *)h_Timer);
123403 +}
123404 +
123405 +uint32_t XX_Sleep(uint32_t msecs)
123406 +{
123407 + int tmp_jiffies = (msecs*HZ)/1000;
123408 +
123409 + if ((msecs*HZ)%1000)
123410 + tmp_jiffies++;
123411 + return schedule_timeout(tmp_jiffies);
123412 +}
123413 +
123414 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123415 +void XX_UDelay(uint32_t usecs)
123416 +{
123417 + udelay(usecs);
123418 +}
123419 +
123420 +/* TODO: verify that these are correct */
123421 +#define MSG_BODY_SIZE 512
123422 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123423 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123424 +t_Error XX_SendMessage(char *p_DestAddr,
123425 + uint32_t msgId,
123426 + uint8_t msgBody[MSG_BODY_SIZE],
123427 + t_MsgCompletionCB *f_CompletionCB,
123428 + t_Handle h_CBArg);
123429 +
123430 +typedef struct {
123431 + char *p_Addr;
123432 + t_MsgHandler *f_MsgHandlerCB;
123433 + t_Handle h_Mod;
123434 + t_List node;
123435 +} t_MsgHndlr;
123436 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123437 +
123438 +LIST(msgHndlrList);
123439 +
123440 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123441 +{
123442 + uint32_t intFlags;
123443 +
123444 + intFlags = XX_DisableAllIntr();
123445 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123446 + XX_RestoreAllIntr(intFlags);
123447 +}
123448 +/* TODO: add this for multi-platform support
123449 +static t_MsgHndlr * DequeueMsgHndlr(void)
123450 +{
123451 + t_MsgHndlr *p_MsgHndlr = NULL;
123452 + uint32_t intFlags;
123453 +
123454 + intFlags = XX_DisableAllIntr();
123455 + if (!LIST_IsEmpty(&msgHndlrList))
123456 + {
123457 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123458 + LIST_DelAndInit(&p_MsgHndlr->node);
123459 + }
123460 + XX_RestoreAllIntr(intFlags);
123461 +
123462 + return p_MsgHndlr;
123463 +}
123464 +*/
123465 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123466 +{
123467 + t_MsgHndlr *p_MsgHndlr;
123468 + t_List *p_Pos;
123469 +
123470 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123471 + {
123472 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123473 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123474 + return p_MsgHndlr;
123475 + }
123476 +
123477 + return NULL;
123478 +}
123479 +
123480 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123481 +{
123482 + t_MsgHndlr *p_MsgHndlr;
123483 + uint32_t len;
123484 +
123485 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123486 + if (!p_MsgHndlr)
123487 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123488 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123489 +
123490 + len = strlen(p_Addr);
123491 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123492 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123493 +
123494 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123495 + p_MsgHndlr->h_Mod = h_Mod;
123496 + INIT_LIST(&p_MsgHndlr->node);
123497 + EnqueueMsgHndlr(p_MsgHndlr);
123498 +
123499 + return E_OK;
123500 +}
123501 +
123502 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123503 +{
123504 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123505 + if (!p_MsgHndlr)
123506 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123507 +
123508 + LIST_Del(&p_MsgHndlr->node);
123509 + XX_Free(p_MsgHndlr->p_Addr);
123510 + XX_Free(p_MsgHndlr);
123511 +
123512 + return E_OK;
123513 +}
123514 +
123515 +t_Error XX_SendMessage(char *p_DestAddr,
123516 + uint32_t msgId,
123517 + uint8_t msgBody[MSG_BODY_SIZE],
123518 + t_MsgCompletionCB *f_CompletionCB,
123519 + t_Handle h_CBArg)
123520 +{
123521 + t_Error ans;
123522 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123523 + if (!p_MsgHndlr)
123524 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123525 +
123526 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123527 +
123528 + if (f_CompletionCB)
123529 + f_CompletionCB(h_CBArg, msgBody);
123530 +
123531 + return ans;
123532 +}
123533 +
123534 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123535 + t_IpcMsgHandler *f_MsgHandler,
123536 + t_Handle h_Module,
123537 + uint32_t replyLength)
123538 +{
123539 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123540 + return E_OK;
123541 +}
123542 +
123543 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123544 +{
123545 + UNUSED(addr);
123546 + return E_OK;
123547 +}
123548 +
123549 +
123550 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123551 + uint8_t *p_Msg,
123552 + uint32_t msgLength,
123553 + uint8_t *p_Reply,
123554 + uint32_t *p_ReplyLength,
123555 + t_IpcMsgCompletion *f_Completion,
123556 + t_Handle h_Arg)
123557 +{
123558 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123559 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123560 + return E_OK;
123561 +}
123562 +
123563 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123564 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123565 +{
123566 + UNUSED(destAddr); UNUSED(srcAddr);
123567 + return E_OK;
123568 +}
123569 +
123570 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123571 +int GetDeviceIrqNum(int irq)
123572 +{
123573 + struct device_node *iPar;
123574 + struct irq_domain *irqHost;
123575 + uint32_t hwIrq;
123576 +
123577 + /* Get the interrupt controller */
123578 + iPar = of_find_node_by_name(NULL, "mpic");
123579 + hwIrq = 0;
123580 +
123581 + ASSERT_COND(iPar != NULL);
123582 + /* Get the irq host */
123583 + irqHost = irq_find_host(iPar);
123584 + of_node_put(iPar);
123585 +
123586 + /* Create irq mapping */
123587 + return irq_create_mapping(irqHost, hwIrq);
123588 +}
123589 +#else
123590 +#error "kernel not supported!!!"
123591 +#endif /* LINUX_VERSION_CODE */
123592 +
123593 +void * XX_PhysToVirt(physAddress_t addr)
123594 +{
123595 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123596 +}
123597 +
123598 +physAddress_t XX_VirtToPhys(void * addr)
123599 +{
123600 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123601 +}
123602 +
123603 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123604 +{
123605 + uintptr_t *returnCode, tmp;
123606 +
123607 + if (alignment < sizeof(uintptr_t))
123608 + alignment = sizeof(uintptr_t);
123609 + size += alignment + sizeof(returnCode);
123610 + tmp = (uintptr_t)xx_Malloc(size);
123611 + if (tmp == 0)
123612 + return NULL;
123613 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123614 + *(returnCode - 1) = tmp;
123615 +
123616 + return (void*)returnCode;
123617 +}
123618 +
123619 +void xx_FreeSmart(void *p)
123620 +{
123621 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123622 +}
123623 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123624 new file mode 100644
123625 index 00000000..992757d4
123626 --- /dev/null
123627 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123628 @@ -0,0 +1,918 @@
123629 +/*
123630 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123631 + *
123632 + * Redistribution and use in source and binary forms, with or without
123633 + * modification, are permitted provided that the following conditions are met:
123634 + * * Redistributions of source code must retain the above copyright
123635 + * notice, this list of conditions and the following disclaimer.
123636 + * * Redistributions in binary form must reproduce the above copyright
123637 + * notice, this list of conditions and the following disclaimer in the
123638 + * documentation and/or other materials provided with the distribution.
123639 + * * Neither the name of Freescale Semiconductor nor the
123640 + * names of its contributors may be used to endorse or promote products
123641 + * derived from this software without specific prior written permission.
123642 + *
123643 + *
123644 + * ALTERNATIVELY, this software may be distributed under the terms of the
123645 + * GNU General Public License ("GPL") as published by the Free Software
123646 + * Foundation, either version 2 of that License or (at your option) any
123647 + * later version.
123648 + *
123649 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123650 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123651 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123652 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123653 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123654 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123655 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123656 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123657 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123658 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123659 + */
123660 +
123661 +/**************************************************************************//**
123662 + @File xx_linux.c
123663 +
123664 + @Description XX routines implementation for Linux.
123665 +*//***************************************************************************/
123666 +#include <linux/version.h>
123667 +
123668 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123669 +#define MODVERSIONS
123670 +#endif
123671 +#ifdef MODVERSIONS
123672 +#include <config/modversions.h>
123673 +#endif /* MODVERSIONS */
123674 +
123675 +#include <linux/module.h>
123676 +#include <linux/kernel.h>
123677 +#include <linux/sched.h>
123678 +#include <linux/string.h>
123679 +#include <linux/ptrace.h>
123680 +#include <linux/errno.h>
123681 +#include <linux/ioport.h>
123682 +#include <linux/slab.h>
123683 +#include <linux/interrupt.h>
123684 +#include <linux/fs.h>
123685 +#include <linux/vmalloc.h>
123686 +#include <linux/init.h>
123687 +#include <linux/timer.h>
123688 +#include <linux/spinlock.h>
123689 +#include <linux/delay.h>
123690 +#include <linux/proc_fs.h>
123691 +#include <linux/smp.h>
123692 +#include <linux/of.h>
123693 +#ifdef CONFIG_FMAN_ARM
123694 +#include <linux/irqdomain.h>
123695 +#endif
123696 +
123697 +#include <linux/workqueue.h>
123698 +
123699 +#ifdef BIGPHYSAREA_ENABLE
123700 +#include <linux/bigphysarea.h>
123701 +#endif /* BIGPHYSAREA_ENABLE */
123702 +
123703 +#ifndef CONFIG_FMAN_ARM
123704 +#include <sysdev/fsl_soc.h>
123705 +#endif
123706 +#include <asm/pgtable.h>
123707 +#include <asm/irq.h>
123708 +#include <asm/bitops.h>
123709 +#include <asm/uaccess.h>
123710 +#include <asm/io.h>
123711 +#include <asm/atomic.h>
123712 +#include <asm/string.h>
123713 +#include <asm/byteorder.h>
123714 +#include <asm/page.h>
123715 +
123716 +#include "error_ext.h"
123717 +#include "std_ext.h"
123718 +#include "list_ext.h"
123719 +#include "mm_ext.h"
123720 +#include "sys_io_ext.h"
123721 +#include "xx.h"
123722 +
123723 +
123724 +#define __ERR_MODULE__ MODULE_UNKNOWN
123725 +
123726 +#ifdef BIGPHYSAREA_ENABLE
123727 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123728 +
123729 +
123730 +/* TODO: large allocations => use big phys area */
123731 +/******************************************************************************
123732 + * routine: get_nr_pages
123733 + *
123734 + * description:
123735 + * calculates the number of memory pages for a given size (in bytes)
123736 + *
123737 + * arguments:
123738 + * size - the number of bytes
123739 + *
123740 + * return code:
123741 + * The number of pages
123742 + *
123743 + *****************************************************************************/
123744 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123745 +{
123746 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123747 +}
123748 +
123749 +static bool in_big_phys_area (uint32_t addr)
123750 +{
123751 + uint32_t base, size;
123752 +
123753 + bigphysarea_get_details (&base, &size);
123754 + return ((addr >= base) && (addr < base + size));
123755 +}
123756 +#endif /* BIGPHYSAREA_ENABLE */
123757 +
123758 +void * xx_Malloc(uint32_t n)
123759 +{
123760 + void *a;
123761 + uint32_t flags;
123762 +
123763 + flags = XX_DisableAllIntr();
123764 +#ifdef BIGPHYSAREA_ENABLE
123765 + if (n >= MAX_ALLOCATION_SIZE)
123766 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123767 + else
123768 +#endif /* BIGPHYSAREA_ENABLE */
123769 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123770 + if (!a)
123771 + XX_Print("No memory for XX_Malloc\n");
123772 + XX_RestoreAllIntr(flags);
123773 +
123774 + return a;
123775 +}
123776 +
123777 +void xx_Free(void *p)
123778 +{
123779 +#ifdef BIGPHYSAREA_ENABLE
123780 + if (in_big_phys_area ((uint32_t)p))
123781 + bigphysarea_free_pages(p);
123782 + else
123783 +#endif /* BIGPHYSAREA_ENABLE */
123784 + kfree(p);
123785 +}
123786 +
123787 +void XX_Exit(int status)
123788 +{
123789 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123790 +}
123791 +
123792 +#define BUF_SIZE 512
123793 +void XX_Print(char *str, ...)
123794 +{
123795 + va_list args;
123796 +#ifdef CONFIG_SMP
123797 + char buf[BUF_SIZE];
123798 +#endif /* CONFIG_SMP */
123799 +
123800 + va_start(args, str);
123801 +#ifdef CONFIG_SMP
123802 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123803 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123804 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123805 +#else
123806 + vprintk(str, args);
123807 +#endif /* CONFIG_SMP */
123808 + va_end(args);
123809 +}
123810 +
123811 +void XX_Fprint(void *file, char *str, ...)
123812 +{
123813 + va_list args;
123814 +#ifdef CONFIG_SMP
123815 + char buf[BUF_SIZE];
123816 +#endif /* CONFIG_SMP */
123817 +
123818 + va_start(args, str);
123819 +#ifdef CONFIG_SMP
123820 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123821 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123822 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123823 +
123824 +#else
123825 + vprintk(str, args);
123826 +#endif /* CONFIG_SMP */
123827 + va_end(args);
123828 +}
123829 +
123830 +#ifdef DEBUG_XX_MALLOC
123831 +typedef void (*t_ffn)(void *);
123832 +typedef struct {
123833 + t_ffn f_free;
123834 + void *mem;
123835 + char *fname;
123836 + int fline;
123837 + uint32_t size;
123838 + t_List node;
123839 +} t_MemDebug;
123840 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123841 +
123842 +LIST(memDbgLst);
123843 +
123844 +
123845 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123846 +{
123847 + void *mem;
123848 + t_MemDebug *p_MemDbg;
123849 +
123850 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123851 + if (p_MemDbg == NULL)
123852 + return NULL;
123853 +
123854 + mem = xx_Malloc(size);
123855 + if (mem == NULL)
123856 + {
123857 + XX_Free(p_MemDbg);
123858 + return NULL;
123859 + }
123860 +
123861 + INIT_LIST(&p_MemDbg->node);
123862 + p_MemDbg->f_free = xx_Free;
123863 + p_MemDbg->mem = mem;
123864 + p_MemDbg->fname = fname;
123865 + p_MemDbg->fline = line;
123866 + p_MemDbg->size = size+sizeof(t_MemDebug);
123867 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123868 +
123869 + return mem;
123870 +}
123871 +
123872 +void * XX_MallocSmartDebug(uint32_t size,
123873 + int memPartitionId,
123874 + uint32_t align,
123875 + char *fname,
123876 + int line)
123877 +{
123878 + void *mem;
123879 + t_MemDebug *p_MemDbg;
123880 +
123881 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123882 + if (p_MemDbg == NULL)
123883 + return NULL;
123884 +
123885 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123886 + if (mem == NULL)
123887 + {
123888 + XX_Free(p_MemDbg);
123889 + return NULL;
123890 + }
123891 +
123892 + INIT_LIST(&p_MemDbg->node);
123893 + p_MemDbg->f_free = xx_FreeSmart;
123894 + p_MemDbg->mem = mem;
123895 + p_MemDbg->fname = fname;
123896 + p_MemDbg->fline = line;
123897 + p_MemDbg->size = size+sizeof(t_MemDebug);
123898 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123899 +
123900 + return mem;
123901 +}
123902 +
123903 +static void debug_free(void *mem)
123904 +{
123905 + t_List *p_MemDbgLh = NULL;
123906 + t_MemDebug *p_MemDbg;
123907 + bool found = FALSE;
123908 +
123909 + if (LIST_IsEmpty(&memDbgLst))
123910 + {
123911 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123912 + return;
123913 + }
123914 +
123915 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123916 + {
123917 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123918 + if (p_MemDbg->mem == mem)
123919 + {
123920 + found = TRUE;
123921 + break;
123922 + }
123923 + }
123924 +
123925 + if (!found)
123926 + {
123927 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123928 + ("Attempt to free unallocated address (0x%08x)",mem));
123929 + dump_stack();
123930 + return;
123931 + }
123932 +
123933 + LIST_Del(p_MemDbgLh);
123934 + p_MemDbg->f_free(mem);
123935 + p_MemDbg->f_free(p_MemDbg);
123936 +}
123937 +
123938 +void XX_FreeSmart(void *p)
123939 +{
123940 + debug_free(p);
123941 +}
123942 +
123943 +
123944 +void XX_Free(void *p)
123945 +{
123946 + debug_free(p);
123947 +}
123948 +
123949 +#else /* not DEBUG_XX_MALLOC */
123950 +void * XX_Malloc(uint32_t size)
123951 +{
123952 + return xx_Malloc(size);
123953 +}
123954 +
123955 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123956 +{
123957 + return xx_MallocSmart(size,memPartitionId, alignment);
123958 +}
123959 +
123960 +void XX_FreeSmart(void *p)
123961 +{
123962 + xx_FreeSmart(p);
123963 +}
123964 +
123965 +
123966 +void XX_Free(void *p)
123967 +{
123968 + xx_Free(p);
123969 +}
123970 +#endif /* not DEBUG_XX_MALLOC */
123971 +
123972 +
123973 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123974 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123975 +{
123976 + e_Event eventCode = (e_Event)event;
123977 +
123978 + UNUSED(eventCode);
123979 + UNUSED(appId);
123980 + UNUSED(flags);
123981 + UNUSED(msg);
123982 +}
123983 +#endif /* (defined(REPORT_EVENTS) && ... */
123984 +
123985 +
123986 +uint32_t XX_DisableAllIntr(void)
123987 +{
123988 + unsigned long flags;
123989 +
123990 +#ifdef local_irq_save_nort
123991 + local_irq_save_nort(flags);
123992 +#else
123993 + local_irq_save(flags);
123994 +#endif
123995 +
123996 + return (uint32_t)flags;
123997 +}
123998 +
123999 +void XX_RestoreAllIntr(uint32_t flags)
124000 +{
124001 +#ifdef local_irq_restore_nort
124002 + local_irq_restore_nort((unsigned long)flags);
124003 +#else
124004 + local_irq_restore((unsigned long)flags);
124005 +#endif
124006 +}
124007 +
124008 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
124009 +{
124010 + UNUSED(qid);
124011 + UNUSED(appId);
124012 + UNUSED(flags);
124013 +
124014 + return f(id);
124015 +}
124016 +
124017 +int XX_IsICacheEnable(void)
124018 +{
124019 + return TRUE;
124020 +}
124021 +
124022 +int XX_IsDCacheEnable(void)
124023 +{
124024 + return TRUE;
124025 +}
124026 +
124027 +
124028 +typedef struct {
124029 + t_Isr *f_Isr;
124030 + t_Handle handle;
124031 +} t_InterruptHandler;
124032 +
124033 +
124034 +t_Handle interruptHandlers[0x00010000];
124035 +
124036 +#ifdef CONFIG_FMAN_ARM
124037 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
124038 +{
124039 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
124040 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
124041 + return IRQ_HANDLED;
124042 +}
124043 +#endif
124044 +
124045 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
124046 +{
124047 +#ifdef CONFIG_FMAN_ARM
124048 + const char *device;
124049 + t_InterruptHandler *p_IntrHndl;
124050 +
124051 + device = GetDeviceName(irq);
124052 + if (device == NULL)
124053 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
124054 +
124055 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
124056 + if (p_IntrHndl == NULL)
124057 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
124058 + p_IntrHndl->f_Isr = f_Isr;
124059 + p_IntrHndl->handle = handle;
124060 + interruptHandlers[irq] = p_IntrHndl;
124061 +
124062 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
124063 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
124064 + disable_irq(GetDeviceIrqNum(irq));
124065 +#endif
124066 + return E_OK;
124067 +}
124068 +
124069 +t_Error XX_FreeIntr(int irq)
124070 +{
124071 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
124072 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
124073 + XX_Free(p_IntrHndl);
124074 + interruptHandlers[irq] = 0;
124075 + return E_OK;
124076 +}
124077 +
124078 +t_Error XX_EnableIntr(int irq)
124079 +{
124080 + enable_irq(GetDeviceIrqNum(irq));
124081 + return E_OK;
124082 +}
124083 +
124084 +t_Error XX_DisableIntr(int irq)
124085 +{
124086 + disable_irq(GetDeviceIrqNum(irq));
124087 + return E_OK;
124088 +}
124089 +
124090 +
124091 +/*****************************************************************************/
124092 +/* Tasklet Service Routines */
124093 +/*****************************************************************************/
124094 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
124095 +typedef struct
124096 +{
124097 + t_Handle h_Data;
124098 + void (*f_Callback) (void *);
124099 + struct delayed_work dwork;
124100 +} t_Tasklet;
124101 +
124102 +static void GenericTaskletCallback(struct work_struct *p_Work)
124103 +{
124104 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
124105 +
124106 + p_Task->f_Callback(p_Task->h_Data);
124107 +}
124108 +#endif /* LINUX_VERSION_CODE */
124109 +
124110 +
124111 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
124112 +{
124113 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124114 + struct work_struct *p_Task;
124115 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
124116 + INIT_WORK(p_Task, routine, data);
124117 +#else
124118 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
124119 + p_Task->h_Data = data;
124120 + p_Task->f_Callback = routine;
124121 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
124122 +#endif /* LINUX_VERSION_CODE */
124123 +
124124 + return (t_TaskletHandle)p_Task;
124125 +}
124126 +
124127 +
124128 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
124129 +{
124130 + if (h_Tasklet)
124131 + XX_Free(h_Tasklet);
124132 +}
124133 +
124134 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
124135 +{
124136 + int ans;
124137 +
124138 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124139 + if (immediate)
124140 + ans = schedule_work(h_Tasklet);
124141 + else
124142 + ans = schedule_delayed_work(h_Tasklet, 1);
124143 +#else
124144 + if (immediate)
124145 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
124146 + else
124147 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
124148 +#endif /* LINUX_VERSION_CODE */
124149 +
124150 + return ans;
124151 +}
124152 +
124153 +void XX_FlushScheduledTasks(void)
124154 +{
124155 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124156 + flush_scheduled_tasks();
124157 +#else
124158 + flush_scheduled_work();
124159 +#endif /* LINUX_VERSION_CODE */
124160 +}
124161 +
124162 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
124163 +{
124164 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124165 + return (int)(((struct work_struct *)h_Tasklet)->pending);
124166 +#else
124167 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
124168 +#endif /* LINUX_VERSION_CODE */
124169 +}
124170 +
124171 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
124172 +{
124173 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124174 + ((struct tq_struct *)h_Tasklet)->data = data;
124175 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124176 + ((struct work_struct *)h_Tasklet)->data = data;
124177 +#else
124178 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
124179 +#endif /* LINUX_VERSION_CODE */
124180 +}
124181 +
124182 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
124183 +{
124184 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124185 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
124186 +#else
124187 + return ((t_Tasklet *)h_Tasklet)->h_Data;
124188 +#endif /* LINUX_VERSION_CODE */
124189 +}
124190 +
124191 +
124192 +/*****************************************************************************/
124193 +/* Spinlock Service Routines */
124194 +/*****************************************************************************/
124195 +
124196 +t_Handle XX_InitSpinlock(void)
124197 +{
124198 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
124199 + if (!p_Spinlock)
124200 + return NULL;
124201 +
124202 + spin_lock_init(p_Spinlock);
124203 +
124204 + return (t_Handle)p_Spinlock;
124205 +}
124206 +
124207 +void XX_FreeSpinlock(t_Handle h_Spinlock)
124208 +{
124209 + if (h_Spinlock)
124210 + XX_Free(h_Spinlock);
124211 +}
124212 +
124213 +void XX_LockSpinlock(t_Handle h_Spinlock)
124214 +{
124215 + spin_lock((spinlock_t *)h_Spinlock);
124216 +}
124217 +
124218 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
124219 +{
124220 + spin_unlock((spinlock_t *)h_Spinlock);
124221 +}
124222 +
124223 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
124224 +{
124225 + unsigned long intrFlags;
124226 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
124227 + return intrFlags;
124228 +}
124229 +
124230 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
124231 +{
124232 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
124233 +}
124234 +
124235 +
124236 +/*****************************************************************************/
124237 +/* Timers Service Routines */
124238 +/*****************************************************************************/
124239 +/* The time now is in mili sec. resolution */
124240 +uint32_t XX_CurrentTime(void)
124241 +{
124242 + return (jiffies*1000)/HZ;
124243 +}
124244 +
124245 +
124246 +t_Handle XX_CreateTimer(void)
124247 +{
124248 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
124249 + if (p_Timer)
124250 + {
124251 + memset(p_Timer, 0, sizeof(struct timer_list));
124252 + init_timer(p_Timer);
124253 + }
124254 + return (t_Handle)p_Timer;
124255 +}
124256 +
124257 +void XX_FreeTimer(t_Handle h_Timer)
124258 +{
124259 + if (h_Timer)
124260 + XX_Free(h_Timer);
124261 +}
124262 +
124263 +void XX_StartTimer(t_Handle h_Timer,
124264 + uint32_t msecs,
124265 + bool periodic,
124266 + void (*f_TimerExpired)(t_Handle),
124267 + t_Handle h_Arg)
124268 +{
124269 + int tmp_jiffies = (msecs*HZ)/1000;
124270 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124271 +
124272 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
124273 +
124274 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
124275 + p_Timer->data = (unsigned long)h_Arg;
124276 + if ((msecs*HZ)%1000)
124277 + tmp_jiffies++;
124278 + p_Timer->expires = (jiffies + tmp_jiffies);
124279 +
124280 + add_timer((struct timer_list *)h_Timer);
124281 +}
124282 +
124283 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
124284 +{
124285 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124286 +
124287 + p_Timer->data = (unsigned long)data;
124288 +}
124289 +
124290 +t_Handle XX_GetTimerData(t_Handle h_Timer)
124291 +{
124292 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124293 +
124294 + return (t_Handle)p_Timer->data;
124295 +}
124296 +
124297 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
124298 +{
124299 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124300 +
124301 + return (uint32_t)p_Timer->expires;
124302 +}
124303 +
124304 +void XX_StopTimer(t_Handle h_Timer)
124305 +{
124306 + del_timer((struct timer_list *)h_Timer);
124307 +}
124308 +
124309 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
124310 +{
124311 + int tmp_jiffies = (msecs*HZ)/1000;
124312 +
124313 + if ((msecs*HZ)%1000)
124314 + tmp_jiffies++;
124315 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
124316 +}
124317 +
124318 +int XX_TimerIsActive(t_Handle h_Timer)
124319 +{
124320 + return timer_pending((struct timer_list *)h_Timer);
124321 +}
124322 +
124323 +uint32_t XX_Sleep(uint32_t msecs)
124324 +{
124325 + int tmp_jiffies = (msecs*HZ)/1000;
124326 +
124327 + if ((msecs*HZ)%1000)
124328 + tmp_jiffies++;
124329 + return schedule_timeout(tmp_jiffies);
124330 +}
124331 +
124332 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
124333 +void XX_UDelay(uint32_t usecs)
124334 +{
124335 + udelay(usecs);
124336 +}
124337 +
124338 +/* TODO: verify that these are correct */
124339 +#define MSG_BODY_SIZE 512
124340 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
124341 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
124342 +t_Error XX_SendMessage(char *p_DestAddr,
124343 + uint32_t msgId,
124344 + uint8_t msgBody[MSG_BODY_SIZE],
124345 + t_MsgCompletionCB *f_CompletionCB,
124346 + t_Handle h_CBArg);
124347 +
124348 +typedef struct {
124349 + char *p_Addr;
124350 + t_MsgHandler *f_MsgHandlerCB;
124351 + t_Handle h_Mod;
124352 + t_List node;
124353 +} t_MsgHndlr;
124354 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
124355 +
124356 +LIST(msgHndlrList);
124357 +
124358 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
124359 +{
124360 + uint32_t intFlags;
124361 +
124362 + intFlags = XX_DisableAllIntr();
124363 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
124364 + XX_RestoreAllIntr(intFlags);
124365 +}
124366 +/* TODO: add this for multi-platform support
124367 +static t_MsgHndlr * DequeueMsgHndlr(void)
124368 +{
124369 + t_MsgHndlr *p_MsgHndlr = NULL;
124370 + uint32_t intFlags;
124371 +
124372 + intFlags = XX_DisableAllIntr();
124373 + if (!LIST_IsEmpty(&msgHndlrList))
124374 + {
124375 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
124376 + LIST_DelAndInit(&p_MsgHndlr->node);
124377 + }
124378 + XX_RestoreAllIntr(intFlags);
124379 +
124380 + return p_MsgHndlr;
124381 +}
124382 +*/
124383 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
124384 +{
124385 + t_MsgHndlr *p_MsgHndlr;
124386 + t_List *p_Pos;
124387 +
124388 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
124389 + {
124390 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
124391 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
124392 + return p_MsgHndlr;
124393 + }
124394 +
124395 + return NULL;
124396 +}
124397 +
124398 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124399 +{
124400 + t_MsgHndlr *p_MsgHndlr;
124401 + uint32_t len;
124402 +
124403 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124404 + if (!p_MsgHndlr)
124405 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
124406 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
124407 +
124408 + len = strlen(p_Addr);
124409 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
124410 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
124411 +
124412 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
124413 + p_MsgHndlr->h_Mod = h_Mod;
124414 + INIT_LIST(&p_MsgHndlr->node);
124415 + EnqueueMsgHndlr(p_MsgHndlr);
124416 +
124417 + return E_OK;
124418 +}
124419 +
124420 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
124421 +{
124422 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
124423 + if (!p_MsgHndlr)
124424 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124425 +
124426 + LIST_Del(&p_MsgHndlr->node);
124427 + XX_Free(p_MsgHndlr->p_Addr);
124428 + XX_Free(p_MsgHndlr);
124429 +
124430 + return E_OK;
124431 +}
124432 +
124433 +t_Error XX_SendMessage(char *p_DestAddr,
124434 + uint32_t msgId,
124435 + uint8_t msgBody[MSG_BODY_SIZE],
124436 + t_MsgCompletionCB *f_CompletionCB,
124437 + t_Handle h_CBArg)
124438 +{
124439 + t_Error ans;
124440 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124441 + if (!p_MsgHndlr)
124442 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124443 +
124444 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124445 +
124446 + if (f_CompletionCB)
124447 + f_CompletionCB(h_CBArg, msgBody);
124448 +
124449 + return ans;
124450 +}
124451 +
124452 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124453 + t_IpcMsgHandler *f_MsgHandler,
124454 + t_Handle h_Module,
124455 + uint32_t replyLength)
124456 +{
124457 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124458 + return E_OK;
124459 +}
124460 +
124461 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124462 +{
124463 + UNUSED(addr);
124464 + return E_OK;
124465 +}
124466 +
124467 +
124468 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124469 + uint8_t *p_Msg,
124470 + uint32_t msgLength,
124471 + uint8_t *p_Reply,
124472 + uint32_t *p_ReplyLength,
124473 + t_IpcMsgCompletion *f_Completion,
124474 + t_Handle h_Arg)
124475 +{
124476 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124477 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124478 + return E_OK;
124479 +}
124480 +
124481 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124482 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124483 +{
124484 + UNUSED(destAddr); UNUSED(srcAddr);
124485 + return E_OK;
124486 +}
124487 +
124488 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
124489 +uint32_t E500_GetId(void)
124490 +{
124491 + return raw_smp_processor_id();
124492 +}
124493 +
124494 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124495 +int GetDeviceIrqNum(int irq)
124496 +{
124497 + struct device_node *iPar;
124498 + struct irq_domain *irqHost;
124499 + uint32_t hwIrq;
124500 +
124501 + /* Get the interrupt controller */
124502 + iPar = of_find_node_by_name(NULL, "mpic");
124503 + hwIrq = 0;
124504 +
124505 + ASSERT_COND(iPar != NULL);
124506 + /* Get the irq host */
124507 + irqHost = irq_find_host(iPar);
124508 + of_node_put(iPar);
124509 +
124510 + /* Create irq mapping */
124511 + return irq_create_mapping(irqHost, hwIrq);
124512 +}
124513 +#else
124514 +#error "kernel not supported!!!"
124515 +#endif /* LINUX_VERSION_CODE */
124516 +
124517 +void * XX_PhysToVirt(physAddress_t addr)
124518 +{
124519 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124520 +}
124521 +
124522 +physAddress_t XX_VirtToPhys(void * addr)
124523 +{
124524 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124525 +}
124526 +
124527 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124528 +{
124529 + uintptr_t *returnCode, tmp;
124530 +
124531 + if (alignment < sizeof(uintptr_t))
124532 + alignment = sizeof(uintptr_t);
124533 + size += alignment + sizeof(returnCode);
124534 + tmp = (uintptr_t)xx_Malloc(size);
124535 + if (tmp == 0)
124536 + return NULL;
124537 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124538 + *(returnCode - 1) = tmp;
124539 +
124540 + return (void*)returnCode;
124541 +}
124542 +
124543 +void xx_FreeSmart(void *p)
124544 +{
124545 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124546 +}
124547 diff --git a/drivers/staging/fsl_qbman/Kconfig b/drivers/staging/fsl_qbman/Kconfig
124548 new file mode 100644
124549 index 00000000..93dcb7d3
124550 --- /dev/null
124551 +++ b/drivers/staging/fsl_qbman/Kconfig
124552 @@ -0,0 +1,228 @@
124553 +config FSL_SDK_DPA
124554 + bool "Freescale Datapath Queue and Buffer management"
124555 + depends on !FSL_DPAA
124556 + select FSL_QMAN_FQ_LOOKUP if PPC64
124557 + select FSL_QMAN_FQ_LOOKUP if ARM64
124558 +
124559 +
124560 +menu "Freescale Datapath QMan/BMan options"
124561 + depends on FSL_SDK_DPA
124562 +
124563 +config FSL_DPA_CHECKING
124564 + bool "additional driver checking"
124565 + default n
124566 + ---help---
124567 + Compiles in additional checks to sanity-check the drivers and any
124568 + use of it by other code. Not recommended for performance.
124569 +
124570 +config FSL_DPA_CAN_WAIT
124571 + bool
124572 + default y
124573 +
124574 +config FSL_DPA_CAN_WAIT_SYNC
124575 + bool
124576 + default y
124577 +
124578 +config FSL_DPA_PIRQ_FAST
124579 + bool
124580 + default y
124581 +
124582 +config FSL_DPA_PIRQ_SLOW
124583 + bool
124584 + default y
124585 +
124586 +config FSL_DPA_PORTAL_SHARE
124587 + bool
124588 + default y
124589 +
124590 +config FSL_SDK_BMAN
124591 + bool "Freescale Buffer Manager (BMan) support"
124592 + default y
124593 +
124594 +if FSL_SDK_BMAN
124595 +
124596 +config FSL_BMAN_CONFIG
124597 + bool "BMan device management"
124598 + default y
124599 + ---help---
124600 + If this linux image is running natively, you need this option. If this
124601 + linux image is running as a guest OS under the hypervisor, only one
124602 + guest OS ("the control plane") needs this option.
124603 +
124604 +config FSL_BMAN_TEST
124605 + tristate "BMan self-tests"
124606 + default n
124607 + ---help---
124608 + This option compiles self-test code for BMan.
124609 +
124610 +config FSL_BMAN_TEST_HIGH
124611 + bool "BMan high-level self-test"
124612 + depends on FSL_BMAN_TEST
124613 + default y
124614 + ---help---
124615 + This requires the presence of cpu-affine portals, and performs
124616 + high-level API testing with them (whichever portal(s) are affine to
124617 + the cpu(s) the test executes on).
124618 +
124619 +config FSL_BMAN_TEST_THRESH
124620 + bool "BMan threshold test"
124621 + depends on FSL_BMAN_TEST
124622 + default y
124623 + ---help---
124624 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
124625 + before multiple threads (one per cpu) create pool objects to track
124626 + depletion state changes. The pool is then drained to empty by a
124627 + "drainer" thread, and the other threads that they observe exactly
124628 + the depletion state changes that are expected.
124629 +
124630 +config FSL_BMAN_DEBUGFS
124631 + tristate "BMan debugfs interface"
124632 + depends on DEBUG_FS
124633 + default y
124634 + ---help---
124635 + This option compiles debugfs code for BMan.
124636 +
124637 +endif # FSL_SDK_BMAN
124638 +
124639 +config FSL_SDK_QMAN
124640 + bool "Freescale Queue Manager (QMan) support"
124641 + default y
124642 +
124643 +if FSL_SDK_QMAN
124644 +
124645 +config FSL_QMAN_POLL_LIMIT
124646 + int
124647 + default 32
124648 +
124649 +config FSL_QMAN_CONFIG
124650 + bool "QMan device management"
124651 + default y
124652 + ---help---
124653 + If this linux image is running natively, you need this option. If this
124654 + linux image is running as a guest OS under the hypervisor, only one
124655 + guest OS ("the control plane") needs this option.
124656 +
124657 +config FSL_QMAN_TEST
124658 + tristate "QMan self-tests"
124659 + default n
124660 + ---help---
124661 + This option compiles self-test code for QMan.
124662 +
124663 +config FSL_QMAN_TEST_STASH_POTATO
124664 + bool "QMan 'hot potato' data-stashing self-test"
124665 + depends on FSL_QMAN_TEST
124666 + default y
124667 + ---help---
124668 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124669 + across a series of FQs scheduled to different portals (and cpus), with
124670 + DQRR, data and context stashing always on.
124671 +
124672 +config FSL_QMAN_TEST_HIGH
124673 + bool "QMan high-level self-test"
124674 + depends on FSL_QMAN_TEST
124675 + default y
124676 + ---help---
124677 + This requires the presence of cpu-affine portals, and performs
124678 + high-level API testing with them (whichever portal(s) are affine to
124679 + the cpu(s) the test executes on).
124680 +
124681 +config FSL_QMAN_DEBUGFS
124682 + tristate "QMan debugfs interface"
124683 + depends on DEBUG_FS
124684 + default y
124685 + ---help---
124686 + This option compiles debugfs code for QMan.
124687 +
124688 +# H/w settings that can be hard-coded for now.
124689 +config FSL_QMAN_FQD_SZ
124690 + int "size of Frame Queue Descriptor region"
124691 + default 10
124692 + ---help---
124693 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124694 + ex: 10 => PAGE_SIZE * (2^10)
124695 + Note: Default device-trees now require minimum Kconfig setting of 10.
124696 +
124697 +config FSL_QMAN_PFDR_SZ
124698 + int "size of the PFDR pool"
124699 + default 13
124700 + ---help---
124701 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124702 + ex: 13 => PAGE_SIZE * (2^13)
124703 +
124704 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124705 +# ability to snart. Stash priority is 3, other priorities are 2.
124706 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124707 + int
124708 + depends on FSL_QMAN_CONFIG
124709 + default 4
124710 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124711 + int
124712 + depends on FSL_QMAN_CONFIG
124713 + default 3
124714 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124715 + int
124716 + depends on FSL_QMAN_CONFIG
124717 + default 2
124718 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124719 + int
124720 + depends on FSL_QMAN_CONFIG
124721 + default 2
124722 +
124723 +# portal interrupt settings
124724 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124725 + int
124726 + default 12
124727 +config FSL_QMAN_PIRQ_MR_ITHRESH
124728 + int
124729 + default 4
124730 +config FSL_QMAN_PIRQ_IPERIOD
124731 + int
124732 + default 100
124733 +
124734 +# 64 bit kernel support
124735 +config FSL_QMAN_FQ_LOOKUP
124736 + bool
124737 + default n
124738 +
124739 +config QMAN_CEETM_UPDATE_PERIOD
124740 + int "Token update period for shaping, in nanoseconds"
124741 + default 1000
124742 + ---help---
124743 + Traffic shaping works by performing token calculations (using
124744 + credits) on shaper instances periodically. This update period
124745 + sets the granularity for how often those token rate credit
124746 + updates are performed, and thus determines the accuracy and
124747 + range of traffic rates that can be configured by users. The
124748 + reference manual recommends a 1 microsecond period as providing
124749 + a good balance between granularity and range.
124750 +
124751 + Unless you know what you are doing, leave this value at its default.
124752 +
124753 +config FSL_QMAN_INIT_TIMEOUT
124754 + int "timeout for qman init stage, in seconds"
124755 + default 10
124756 + ---help---
124757 + The timeout setting to quit the initialization loop for non-control
124758 + partition in case the control partition fails to boot-up.
124759 +
124760 +endif # FSL_SDK_QMAN
124761 +
124762 +config FSL_USDPAA
124763 + bool "Freescale USDPAA process driver"
124764 + depends on FSL_SDK_DPA
124765 + default y
124766 + ---help---
124767 + This driver provides user-space access to kernel-managed
124768 + resource interfaces for USDPAA applications, on the assumption
124769 + that each process will open this device once. Specifically, this
124770 + device exposes functionality that would be awkward if exposed
124771 + via the portal devices - ie. this device exposes functionality
124772 + that is inherently process-wide rather than portal-specific.
124773 + This device is necessary for obtaining access to DMA memory and
124774 + for allocation of Qman and Bman resources. In short, if you wish
124775 + to use USDPAA applications, you need this.
124776 +
124777 + If unsure, say Y.
124778 +
124779 +
124780 +endmenu
124781 diff --git a/drivers/staging/fsl_qbman/Makefile b/drivers/staging/fsl_qbman/Makefile
124782 new file mode 100644
124783 index 00000000..777d7d34
124784 --- /dev/null
124785 +++ b/drivers/staging/fsl_qbman/Makefile
124786 @@ -0,0 +1,28 @@
124787 +subdir-ccflags-y := -Werror
124788 +
124789 +# Common
124790 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124791 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124792 +
124793 +# Bman
124794 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124795 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124796 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
124797 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
124798 +bman_tester-y = bman_test.o
124799 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
124800 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
124801 +bman_debugfs_interface-y = bman_debugfs.o
124802 +
124803 +# Qman
124804 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
124805 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
124806 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
124807 +qman_tester-y = qman_test.o
124808 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
124809 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
124810 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
124811 +qman_debugfs_interface-y = qman_debugfs.o
124812 +
124813 +# USDPAA
124814 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
124815 diff --git a/drivers/staging/fsl_qbman/bman_config.c b/drivers/staging/fsl_qbman/bman_config.c
124816 new file mode 100644
124817 index 00000000..bb397730
124818 --- /dev/null
124819 +++ b/drivers/staging/fsl_qbman/bman_config.c
124820 @@ -0,0 +1,720 @@
124821 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
124822 + *
124823 + * Redistribution and use in source and binary forms, with or without
124824 + * modification, are permitted provided that the following conditions are met:
124825 + * * Redistributions of source code must retain the above copyright
124826 + * notice, this list of conditions and the following disclaimer.
124827 + * * Redistributions in binary form must reproduce the above copyright
124828 + * notice, this list of conditions and the following disclaimer in the
124829 + * documentation and/or other materials provided with the distribution.
124830 + * * Neither the name of Freescale Semiconductor nor the
124831 + * names of its contributors may be used to endorse or promote products
124832 + * derived from this software without specific prior written permission.
124833 + *
124834 + *
124835 + * ALTERNATIVELY, this software may be distributed under the terms of the
124836 + * GNU General Public License ("GPL") as published by the Free Software
124837 + * Foundation, either version 2 of that License or (at your option) any
124838 + * later version.
124839 + *
124840 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124841 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124842 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124843 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124844 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124845 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124846 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124847 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124848 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124849 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124850 + */
124851 +
124852 +#include <asm/cacheflush.h>
124853 +#include "bman_private.h"
124854 +#include <linux/of_reserved_mem.h>
124855 +
124856 +/* Last updated for v00.79 of the BG */
124857 +
124858 +struct bman;
124859 +
124860 +/* Register offsets */
124861 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
124862 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
124863 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
124864 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
124865 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
124866 +#define REG_FBPR_FPC 0x0800
124867 +#define REG_STATE_IDLE 0x960
124868 +#define REG_STATE_STOP 0x964
124869 +#define REG_ECSR 0x0a00
124870 +#define REG_ECIR 0x0a04
124871 +#define REG_EADR 0x0a08
124872 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
124873 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
124874 +#define REG_IP_REV_1 0x0bf8
124875 +#define REG_IP_REV_2 0x0bfc
124876 +#define REG_FBPR_BARE 0x0c00
124877 +#define REG_FBPR_BAR 0x0c04
124878 +#define REG_FBPR_AR 0x0c10
124879 +#define REG_SRCIDR 0x0d04
124880 +#define REG_LIODNR 0x0d08
124881 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
124882 +
124883 +/* Used by all error interrupt registers except 'inhibit' */
124884 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
124885 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
124886 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
124887 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
124888 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
124889 +
124890 +/* BMAN_ECIR valid error bit */
124891 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
124892 +
124893 +union bman_ecir {
124894 + u32 ecir_raw;
124895 + struct {
124896 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124897 + u32 __reserved1:4;
124898 + u32 portal_num:4;
124899 + u32 __reserved2:12;
124900 + u32 numb:4;
124901 + u32 __reserved3:2;
124902 + u32 pid:6;
124903 +#else
124904 + u32 pid:6;
124905 + u32 __reserved3:2;
124906 + u32 numb:4;
124907 + u32 __reserved2:12;
124908 + u32 portal_num:4;
124909 + u32 __reserved1:4;
124910 +#endif
124911 + } __packed info;
124912 +};
124913 +
124914 +union bman_eadr {
124915 + u32 eadr_raw;
124916 + struct {
124917 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124918 + u32 __reserved1:5;
124919 + u32 memid:3;
124920 + u32 __reserved2:14;
124921 + u32 eadr:10;
124922 +#else
124923 + u32 eadr:10;
124924 + u32 __reserved2:14;
124925 + u32 memid:3;
124926 + u32 __reserved1:5;
124927 +#endif
124928 + } __packed info;
124929 +};
124930 +
124931 +struct bman_hwerr_txt {
124932 + u32 mask;
124933 + const char *txt;
124934 +};
124935 +
124936 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
124937 +
124938 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
124939 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
124940 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
124941 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
124942 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
124943 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
124944 +};
124945 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
124946 +
124947 +struct bman_error_info_mdata {
124948 + u16 addr_mask;
124949 + u16 bits;
124950 + const char *txt;
124951 +};
124952 +
124953 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
124954 +static const struct bman_error_info_mdata error_mdata[] = {
124955 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
124956 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
124957 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
124958 +};
124959 +#define BMAN_ERR_MDATA_COUNT \
124960 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
124961 +
124962 +/* Add this in Kconfig */
124963 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
124964 +
124965 +/**
124966 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
124967 + * @v: for accessors that write values, this is the 32-bit value
124968 + *
124969 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
124970 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
124971 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
124972 + * "write the enable register" rather than "enable the write register"!
124973 + */
124974 +#define bm_err_isr_status_read(bm) \
124975 + __bm_err_isr_read(bm, bm_isr_status)
124976 +#define bm_err_isr_status_clear(bm, m) \
124977 + __bm_err_isr_write(bm, bm_isr_status, m)
124978 +#define bm_err_isr_enable_read(bm) \
124979 + __bm_err_isr_read(bm, bm_isr_enable)
124980 +#define bm_err_isr_enable_write(bm, v) \
124981 + __bm_err_isr_write(bm, bm_isr_enable, v)
124982 +#define bm_err_isr_disable_read(bm) \
124983 + __bm_err_isr_read(bm, bm_isr_disable)
124984 +#define bm_err_isr_disable_write(bm, v) \
124985 + __bm_err_isr_write(bm, bm_isr_disable, v)
124986 +#define bm_err_isr_inhibit(bm) \
124987 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
124988 +#define bm_err_isr_uninhibit(bm) \
124989 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
124990 +
124991 +/*
124992 + * TODO: unimplemented registers
124993 + *
124994 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
124995 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
124996 + */
124997 +
124998 +/* Encapsulate "struct bman *" as a cast of the register space address. */
124999 +
125000 +static struct bman *bm_create(void *regs)
125001 +{
125002 + return (struct bman *)regs;
125003 +}
125004 +
125005 +static inline u32 __bm_in(struct bman *bm, u32 offset)
125006 +{
125007 + return in_be32((void *)bm + offset);
125008 +}
125009 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
125010 +{
125011 + out_be32((void *)bm + offset, val);
125012 +}
125013 +#define bm_in(reg) __bm_in(bm, REG_##reg)
125014 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
125015 +
125016 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
125017 +{
125018 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
125019 +}
125020 +
125021 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
125022 +{
125023 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
125024 +}
125025 +
125026 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
125027 +{
125028 + u32 v = bm_in(IP_REV_1);
125029 + *id = (v >> 16);
125030 + *major = (v >> 8) & 0xff;
125031 + *minor = v & 0xff;
125032 +}
125033 +
125034 +static u32 __generate_thresh(u32 val, int roundup)
125035 +{
125036 + u32 e = 0; /* co-efficient, exponent */
125037 + int oddbit = 0;
125038 + while (val > 0xff) {
125039 + oddbit = val & 1;
125040 + val >>= 1;
125041 + e++;
125042 + if (roundup && oddbit)
125043 + val++;
125044 + }
125045 + DPA_ASSERT(e < 0x10);
125046 + return val | (e << 8);
125047 +}
125048 +
125049 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
125050 + u32 hwdet, u32 hwdxt)
125051 +{
125052 + DPA_ASSERT(pool < bman_pool_max);
125053 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
125054 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
125055 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
125056 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
125057 +}
125058 +
125059 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
125060 +{
125061 + u32 exp = ilog2(size);
125062 + /* choke if size isn't within range */
125063 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
125064 + is_power_of_2(size));
125065 + /* choke if '[e]ba' has lower-alignment than 'size' */
125066 + DPA_ASSERT(!(ba & (size - 1)));
125067 + bm_out(FBPR_BARE, upper_32_bits(ba));
125068 + bm_out(FBPR_BAR, lower_32_bits(ba));
125069 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
125070 +}
125071 +
125072 +/*****************/
125073 +/* Config driver */
125074 +/*****************/
125075 +
125076 +/* TODO: Kconfig these? */
125077 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
125078 +
125079 +/* We support only one of these. */
125080 +static struct bman *bm;
125081 +static struct device_node *bm_node;
125082 +
125083 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
125084 + * during bman_init_ccsr(). */
125085 +static dma_addr_t fbpr_a;
125086 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
125087 +
125088 +static int bman_fbpr(struct reserved_mem *rmem)
125089 +{
125090 + fbpr_a = rmem->base;
125091 + fbpr_sz = rmem->size;
125092 +
125093 + WARN_ON(!(fbpr_a && fbpr_sz));
125094 +
125095 + return 0;
125096 +}
125097 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
125098 +
125099 +static int __init fsl_bman_init(struct device_node *node)
125100 +{
125101 + struct resource res;
125102 + u32 __iomem *regs;
125103 + const char *s;
125104 + int ret, standby = 0;
125105 + u16 id;
125106 + u8 major, minor;
125107 +
125108 + ret = of_address_to_resource(node, 0, &res);
125109 + if (ret) {
125110 + pr_err("Can't get %s property 'reg'\n",
125111 + node->full_name);
125112 + return ret;
125113 + }
125114 + s = of_get_property(node, "fsl,hv-claimable", &ret);
125115 + if (s && !strcmp(s, "standby"))
125116 + standby = 1;
125117 + /* Global configuration */
125118 + regs = ioremap(res.start, res.end - res.start + 1);
125119 + bm = bm_create(regs);
125120 + BUG_ON(!bm);
125121 + bm_node = node;
125122 + bm_get_version(bm, &id, &major, &minor);
125123 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
125124 + if ((major == 1) && (minor == 0)) {
125125 + bman_ip_rev = BMAN_REV10;
125126 + bman_pool_max = 64;
125127 + } else if ((major == 2) && (minor == 0)) {
125128 + bman_ip_rev = BMAN_REV20;
125129 + bman_pool_max = 8;
125130 + } else if ((major == 2) && (minor == 1)) {
125131 + bman_ip_rev = BMAN_REV21;
125132 + bman_pool_max = 64;
125133 + } else {
125134 + pr_warn("unknown Bman version, default to rev1.0\n");
125135 + }
125136 +
125137 + if (standby) {
125138 + pr_info(" -> in standby mode\n");
125139 + return 0;
125140 + }
125141 + return 0;
125142 +}
125143 +
125144 +int bman_have_ccsr(void)
125145 +{
125146 + return bm ? 1 : 0;
125147 +}
125148 +
125149 +int bm_pool_set(u32 bpid, const u32 *thresholds)
125150 +{
125151 + if (!bm)
125152 + return -ENODEV;
125153 + bm_set_pool(bm, bpid, thresholds[0],
125154 + thresholds[1], thresholds[2],
125155 + thresholds[3]);
125156 + return 0;
125157 +}
125158 +EXPORT_SYMBOL(bm_pool_set);
125159 +
125160 +__init int bman_init_early(void)
125161 +{
125162 + struct device_node *dn;
125163 + int ret;
125164 +
125165 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125166 + if (bm)
125167 + pr_err("%s: only one 'fsl,bman' allowed\n",
125168 + dn->full_name);
125169 + else {
125170 + if (!of_device_is_available(dn))
125171 + continue;
125172 +
125173 + ret = fsl_bman_init(dn);
125174 + BUG_ON(ret);
125175 + }
125176 + }
125177 + return 0;
125178 +}
125179 +postcore_initcall_sync(bman_init_early);
125180 +
125181 +
125182 +static void log_edata_bits(u32 bit_count)
125183 +{
125184 + u32 i, j, mask = 0xffffffff;
125185 +
125186 + pr_warn("Bman ErrInt, EDATA:\n");
125187 + i = bit_count/32;
125188 + if (bit_count%32) {
125189 + i++;
125190 + mask = ~(mask << bit_count%32);
125191 + }
125192 + j = 16-i;
125193 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
125194 + j++;
125195 + for (; j < 16; j++)
125196 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
125197 +}
125198 +
125199 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
125200 +{
125201 + union bman_ecir ecir_val;
125202 + union bman_eadr eadr_val;
125203 +
125204 + ecir_val.ecir_raw = bm_in(ECIR);
125205 + /* Is portal info valid */
125206 + if (ecsr_val & PORTAL_ECSR_ERR) {
125207 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
125208 + ecir_val.info.portal_num, ecir_val.info.numb,
125209 + ecir_val.info.pid);
125210 + }
125211 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
125212 + eadr_val.eadr_raw = bm_in(EADR);
125213 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
125214 + error_mdata[eadr_val.info.memid].txt,
125215 + error_mdata[eadr_val.info.memid].addr_mask
125216 + & eadr_val.info.eadr);
125217 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
125218 + }
125219 +}
125220 +
125221 +/* Bman interrupt handler */
125222 +static irqreturn_t bman_isr(int irq, void *ptr)
125223 +{
125224 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
125225 +
125226 + ier_val = bm_err_isr_enable_read(bm);
125227 + isr_val = bm_err_isr_status_read(bm);
125228 + ecsr_val = bm_in(ECSR);
125229 + isr_mask = isr_val & ier_val;
125230 +
125231 + if (!isr_mask)
125232 + return IRQ_NONE;
125233 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
125234 + if (bman_hwerr_txts[i].mask & isr_mask) {
125235 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
125236 + if (bman_hwerr_txts[i].mask & ecsr_val) {
125237 + log_additional_error_info(isr_mask, ecsr_val);
125238 + /* Re-arm error capture registers */
125239 + bm_out(ECSR, ecsr_val);
125240 + }
125241 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
125242 + pr_devel("Bman un-enabling error 0x%x\n",
125243 + bman_hwerr_txts[i].mask);
125244 + ier_val &= ~bman_hwerr_txts[i].mask;
125245 + bm_err_isr_enable_write(bm, ier_val);
125246 + }
125247 + }
125248 + }
125249 + bm_err_isr_status_clear(bm, isr_val);
125250 + return IRQ_HANDLED;
125251 +}
125252 +
125253 +static int __bind_irq(void)
125254 +{
125255 + int ret, err_irq;
125256 +
125257 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
125258 + if (err_irq == 0) {
125259 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
125260 + "interrupts");
125261 + return -ENODEV;
125262 + }
125263 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
125264 + if (ret) {
125265 + pr_err("request_irq() failed %d for '%s'\n", ret,
125266 + bm_node->full_name);
125267 + return -ENODEV;
125268 + }
125269 + /* Disable Buffer Pool State Change */
125270 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
125271 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
125272 + * to resource allocation during driver init). */
125273 + bm_err_isr_status_clear(bm, 0xffffffff);
125274 + /* Enable Error Interrupts */
125275 + bm_err_isr_enable_write(bm, 0xffffffff);
125276 + return 0;
125277 +}
125278 +
125279 +int bman_init_ccsr(struct device_node *node)
125280 +{
125281 + int ret;
125282 + if (!bman_have_ccsr())
125283 + return 0;
125284 + if (node != bm_node)
125285 + return -EINVAL;
125286 + /* FBPR memory */
125287 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
125288 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
125289 +
125290 + ret = __bind_irq();
125291 + if (ret)
125292 + return ret;
125293 + return 0;
125294 +}
125295 +
125296 +u32 bm_pool_free_buffers(u32 bpid)
125297 +{
125298 + return bm_in(POOL_CONTENT(bpid));
125299 +}
125300 +
125301 +#ifdef CONFIG_SYSFS
125302 +
125303 +#define DRV_NAME "fsl-bman"
125304 +#define SBEC_MAX_ID 1
125305 +#define SBEC_MIN_ID 0
125306 +
125307 +static ssize_t show_fbpr_fpc(struct device *dev,
125308 + struct device_attribute *dev_attr, char *buf)
125309 +{
125310 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
125311 +};
125312 +
125313 +static ssize_t show_pool_count(struct device *dev,
125314 + struct device_attribute *dev_attr, char *buf)
125315 +{
125316 + u32 data;
125317 + int i;
125318 +
125319 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
125320 + return -EINVAL;
125321 + data = bm_in(POOL_CONTENT(i));
125322 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
125323 +};
125324 +
125325 +static ssize_t show_err_isr(struct device *dev,
125326 + struct device_attribute *dev_attr, char *buf)
125327 +{
125328 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
125329 +};
125330 +
125331 +static ssize_t show_sbec(struct device *dev,
125332 + struct device_attribute *dev_attr, char *buf)
125333 +{
125334 + int i;
125335 +
125336 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
125337 + return -EINVAL;
125338 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
125339 + return -EINVAL;
125340 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
125341 +};
125342 +
125343 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
125344 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
125345 +
125346 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
125347 + * Initialize them when needed. */
125348 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
125349 +static struct device_attribute *dev_attr_buffer_pool_count;
125350 +
125351 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
125352 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
125353 +
125354 +static struct attribute *bman_dev_attributes[] = {
125355 + &dev_attr_fbpr_fpc.attr,
125356 + &dev_attr_err_isr.attr,
125357 + NULL
125358 +};
125359 +
125360 +static struct attribute *bman_dev_ecr_attributes[] = {
125361 + &dev_attr_sbec_0.attr,
125362 + &dev_attr_sbec_1.attr,
125363 + NULL
125364 +};
125365 +
125366 +static struct attribute **bman_dev_pool_count_attributes;
125367 +
125368 +
125369 +/* root level */
125370 +static const struct attribute_group bman_dev_attr_grp = {
125371 + .name = NULL,
125372 + .attrs = bman_dev_attributes
125373 +};
125374 +static const struct attribute_group bman_dev_ecr_grp = {
125375 + .name = "error_capture",
125376 + .attrs = bman_dev_ecr_attributes
125377 +};
125378 +static struct attribute_group bman_dev_pool_countent_grp = {
125379 + .name = "pool_count",
125380 +};
125381 +
125382 +static int of_fsl_bman_remove(struct platform_device *ofdev)
125383 +{
125384 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125385 + return 0;
125386 +};
125387 +
125388 +static int of_fsl_bman_probe(struct platform_device *ofdev)
125389 +{
125390 + int ret, i;
125391 +
125392 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125393 + if (ret)
125394 + goto done;
125395 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125396 + if (ret)
125397 + goto del_group_0;
125398 +
125399 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
125400 + GFP_KERNEL);
125401 + if (!name_attrs_pool_count) {
125402 + pr_err("Can't alloc name_attrs_pool_count\n");
125403 + goto del_group_1;
125404 + }
125405 +
125406 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
125407 + bman_pool_max, GFP_KERNEL);
125408 + if (!dev_attr_buffer_pool_count) {
125409 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
125410 + goto del_group_2;
125411 + }
125412 +
125413 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
125414 + (bman_pool_max + 1), GFP_KERNEL);
125415 + if (!bman_dev_pool_count_attributes) {
125416 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
125417 + goto del_group_3;
125418 + }
125419 +
125420 + for (i = 0; i < bman_pool_max; i++) {
125421 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
125422 + if (!ret)
125423 + goto del_group_4;
125424 + dev_attr_buffer_pool_count[i].attr.name =
125425 + (name_attrs_pool_count + i * 3);
125426 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
125427 + dev_attr_buffer_pool_count[i].show = show_pool_count;
125428 + bman_dev_pool_count_attributes[i] =
125429 + &dev_attr_buffer_pool_count[i].attr;
125430 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
125431 + }
125432 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
125433 +
125434 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
125435 +
125436 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
125437 + if (ret)
125438 + goto del_group_4;
125439 +
125440 + goto done;
125441 +
125442 +del_group_4:
125443 + kfree(bman_dev_pool_count_attributes);
125444 +del_group_3:
125445 + kfree(dev_attr_buffer_pool_count);
125446 +del_group_2:
125447 + kfree(name_attrs_pool_count);
125448 +del_group_1:
125449 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125450 +del_group_0:
125451 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125452 +done:
125453 + if (ret)
125454 + dev_err(&ofdev->dev,
125455 + "Cannot create dev attributes ret=%d\n", ret);
125456 + return ret;
125457 +};
125458 +
125459 +static struct of_device_id of_fsl_bman_ids[] = {
125460 + {
125461 + .compatible = "fsl,bman",
125462 + },
125463 + {}
125464 +};
125465 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
125466 +
125467 +#ifdef CONFIG_SUSPEND
125468 +static u32 saved_isdr;
125469 +
125470 +static int bman_pm_suspend_noirq(struct device *dev)
125471 +{
125472 + uint32_t idle_state;
125473 +
125474 + suspend_unused_bportal();
125475 + /* save isdr, disable all, clear isr */
125476 + saved_isdr = bm_err_isr_disable_read(bm);
125477 + bm_err_isr_disable_write(bm, 0xffffffff);
125478 + bm_err_isr_status_clear(bm, 0xffffffff);
125479 +
125480 + if (bman_ip_rev < BMAN_REV21) {
125481 +#ifdef CONFIG_PM_DEBUG
125482 + pr_info("Bman version doesn't have STATE_IDLE\n");
125483 +#endif
125484 + return 0;
125485 + }
125486 + idle_state = bm_in(STATE_IDLE);
125487 + if (!(idle_state & 0x1)) {
125488 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
125489 + bm_err_isr_disable_write(bm, saved_isdr);
125490 + resume_unused_bportal();
125491 + return -EBUSY;
125492 + }
125493 +#ifdef CONFIG_PM_DEBUG
125494 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
125495 +#endif
125496 + return 0;
125497 +}
125498 +
125499 +static int bman_pm_resume_noirq(struct device *dev)
125500 +{
125501 + /* restore isdr */
125502 + bm_err_isr_disable_write(bm, saved_isdr);
125503 + resume_unused_bportal();
125504 + return 0;
125505 +}
125506 +#else
125507 +#define bman_pm_suspend_noirq NULL
125508 +#define bman_pm_resume_noirq NULL
125509 +#endif
125510 +
125511 +static const struct dev_pm_ops bman_pm_ops = {
125512 + .suspend_noirq = bman_pm_suspend_noirq,
125513 + .resume_noirq = bman_pm_resume_noirq,
125514 +};
125515 +
125516 +static struct platform_driver of_fsl_bman_driver = {
125517 + .driver = {
125518 + .owner = THIS_MODULE,
125519 + .name = DRV_NAME,
125520 + .of_match_table = of_fsl_bman_ids,
125521 + .pm = &bman_pm_ops,
125522 + },
125523 + .probe = of_fsl_bman_probe,
125524 + .remove = of_fsl_bman_remove,
125525 +};
125526 +
125527 +static int bman_ctrl_init(void)
125528 +{
125529 + return platform_driver_register(&of_fsl_bman_driver);
125530 +}
125531 +
125532 +static void bman_ctrl_exit(void)
125533 +{
125534 + platform_driver_unregister(&of_fsl_bman_driver);
125535 +}
125536 +
125537 +module_init(bman_ctrl_init);
125538 +module_exit(bman_ctrl_exit);
125539 +
125540 +#endif /* CONFIG_SYSFS */
125541 diff --git a/drivers/staging/fsl_qbman/bman_debugfs.c b/drivers/staging/fsl_qbman/bman_debugfs.c
125542 new file mode 100644
125543 index 00000000..96909348
125544 --- /dev/null
125545 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
125546 @@ -0,0 +1,119 @@
125547 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
125548 + *
125549 + * Redistribution and use in source and binary forms, with or without
125550 + * modification, are permitted provided that the following conditions are met:
125551 + * * Redistributions of source code must retain the above copyright
125552 + * notice, this list of conditions and the following disclaimer.
125553 + * * Redistributions in binary form must reproduce the above copyright
125554 + * notice, this list of conditions and the following disclaimer in the
125555 + * documentation and/or other materials provided with the distribution.
125556 + * * Neither the name of Freescale Semiconductor nor the
125557 + * names of its contributors may be used to endorse or promote products
125558 + * derived from this software without specific prior written permission.
125559 + *
125560 + *
125561 + * ALTERNATIVELY, this software may be distributed under the terms of the
125562 + * GNU General Public License ("GPL") as published by the Free Software
125563 + * Foundation, either version 2 of that License or (at your option) any
125564 + * later version.
125565 + *
125566 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125567 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125568 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125569 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125570 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125571 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125572 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125573 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125574 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125575 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125576 + */
125577 +#include <linux/module.h>
125578 +#include <linux/fsl_bman.h>
125579 +#include <linux/debugfs.h>
125580 +#include <linux/seq_file.h>
125581 +#include <linux/uaccess.h>
125582 +
125583 +static struct dentry *dfs_root; /* debugfs root directory */
125584 +
125585 +/*******************************************************************************
125586 + * Query Buffer Pool State
125587 + ******************************************************************************/
125588 +static int query_bp_state_show(struct seq_file *file, void *offset)
125589 +{
125590 + int ret;
125591 + struct bm_pool_state state;
125592 + int i, j;
125593 + u32 mask;
125594 +
125595 + memset(&state, 0, sizeof(struct bm_pool_state));
125596 + ret = bman_query_pools(&state);
125597 + if (ret) {
125598 + seq_printf(file, "Error %d\n", ret);
125599 + return 0;
125600 + }
125601 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
125602 + for (i = 0; i < 2; i++) {
125603 + mask = 0x80000000;
125604 + for (j = 0; j < 32; j++) {
125605 + seq_printf(file,
125606 + " %-2u %-3s %-3s\n",
125607 + (i*32)+j,
125608 + (state.as.state.__state[i] & mask) ? "no" : "yes",
125609 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
125610 + mask >>= 1;
125611 + }
125612 + }
125613 + return 0;
125614 +}
125615 +
125616 +static int query_bp_state_open(struct inode *inode, struct file *file)
125617 +{
125618 + return single_open(file, query_bp_state_show, NULL);
125619 +}
125620 +
125621 +static const struct file_operations query_bp_state_fops = {
125622 + .owner = THIS_MODULE,
125623 + .open = query_bp_state_open,
125624 + .read = seq_read,
125625 + .release = single_release,
125626 +};
125627 +
125628 +static int __init bman_debugfs_module_init(void)
125629 +{
125630 + int ret = 0;
125631 + struct dentry *d;
125632 +
125633 + dfs_root = debugfs_create_dir("bman", NULL);
125634 +
125635 + if (dfs_root == NULL) {
125636 + ret = -ENOMEM;
125637 + pr_err("Cannot create bman debugfs dir\n");
125638 + goto _return;
125639 + }
125640 + d = debugfs_create_file("query_bp_state",
125641 + S_IRUGO,
125642 + dfs_root,
125643 + NULL,
125644 + &query_bp_state_fops);
125645 + if (d == NULL) {
125646 + ret = -ENOMEM;
125647 + pr_err("Cannot create query_bp_state\n");
125648 + goto _return;
125649 + }
125650 + return 0;
125651 +
125652 +_return:
125653 + debugfs_remove_recursive(dfs_root);
125654 + return ret;
125655 +}
125656 +
125657 +static void __exit bman_debugfs_module_exit(void)
125658 +{
125659 + debugfs_remove_recursive(dfs_root);
125660 +}
125661 +
125662 +
125663 +module_init(bman_debugfs_module_init);
125664 +module_exit(bman_debugfs_module_exit);
125665 +MODULE_LICENSE("Dual BSD/GPL");
125666 diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c
125667 new file mode 100644
125668 index 00000000..86fabef6
125669 --- /dev/null
125670 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125671 @@ -0,0 +1,575 @@
125672 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125673 + *
125674 + * Redistribution and use in source and binary forms, with or without
125675 + * modification, are permitted provided that the following conditions are met:
125676 + * * Redistributions of source code must retain the above copyright
125677 + * notice, this list of conditions and the following disclaimer.
125678 + * * Redistributions in binary form must reproduce the above copyright
125679 + * notice, this list of conditions and the following disclaimer in the
125680 + * documentation and/or other materials provided with the distribution.
125681 + * * Neither the name of Freescale Semiconductor nor the
125682 + * names of its contributors may be used to endorse or promote products
125683 + * derived from this software without specific prior written permission.
125684 + *
125685 + *
125686 + * ALTERNATIVELY, this software may be distributed under the terms of the
125687 + * GNU General Public License ("GPL") as published by the Free Software
125688 + * Foundation, either version 2 of that License or (at your option) any
125689 + * later version.
125690 + *
125691 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125692 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125693 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125694 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125695 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125696 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125697 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125698 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125699 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125700 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125701 + */
125702 +#include "bman_low.h"
125703 +#ifdef CONFIG_HOTPLUG_CPU
125704 +#include <linux/cpu.h>
125705 +#endif
125706 +/*
125707 + * Global variables of the max portal/pool number this bman version supported
125708 + */
125709 +u16 bman_ip_rev;
125710 +EXPORT_SYMBOL(bman_ip_rev);
125711 +u16 bman_pool_max;
125712 +EXPORT_SYMBOL(bman_pool_max);
125713 +static u16 bman_portal_max;
125714 +
125715 +/* After initialising cpus that own shared portal configs, we cache the
125716 + * resulting portals (ie. not just the configs) in this array. Then we
125717 + * initialise slave cpus that don't have their own portals, redirecting them to
125718 + * portals from this cache in a round-robin assignment. */
125719 +static struct bman_portal *shared_portals[NR_CPUS];
125720 +static int num_shared_portals;
125721 +static int shared_portals_idx;
125722 +static LIST_HEAD(unused_pcfgs);
125723 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125724 +static void *affine_bportals[NR_CPUS];
125725 +
125726 +static int __init fsl_bpool_init(struct device_node *node)
125727 +{
125728 + int ret;
125729 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125730 + if (!bpid || (ret != 4)) {
125731 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125732 + return -ENODEV;
125733 + }
125734 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125735 + if (thresh) {
125736 + if (ret != 16) {
125737 + pr_err("Invalid %s property '%s'\n",
125738 + node->full_name, "fsl,bpool-thresholds");
125739 + return -ENODEV;
125740 + }
125741 + }
125742 + if (thresh) {
125743 +#ifdef CONFIG_FSL_BMAN_CONFIG
125744 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125745 + if (ret)
125746 + pr_err("No CCSR node for %s property '%s'\n",
125747 + node->full_name, "fsl,bpool-thresholds");
125748 + return ret;
125749 +#else
125750 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125751 + node->full_name, "fsl,bpool-thresholds");
125752 +#endif
125753 + }
125754 + return 0;
125755 +}
125756 +
125757 +static int __init fsl_bpid_range_init(struct device_node *node)
125758 +{
125759 + int ret;
125760 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125761 + if (!range) {
125762 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125763 + node->full_name);
125764 + return -EINVAL;
125765 + }
125766 + if (ret != 8) {
125767 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125768 + node->full_name);
125769 + return -EINVAL;
125770 + }
125771 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125772 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125773 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125774 + return 0;
125775 +}
125776 +
125777 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125778 +{
125779 + struct bm_portal_config *pcfg;
125780 + const u32 *index;
125781 + int irq, ret;
125782 + resource_size_t len;
125783 +
125784 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125785 + if (!pcfg) {
125786 + pr_err("can't allocate portal config");
125787 + return NULL;
125788 + }
125789 +
125790 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125791 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125792 + bman_ip_rev = BMAN_REV10;
125793 + bman_pool_max = 64;
125794 + bman_portal_max = 10;
125795 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125796 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
125797 + bman_ip_rev = BMAN_REV20;
125798 + bman_pool_max = 8;
125799 + bman_portal_max = 3;
125800 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
125801 + bman_ip_rev = BMAN_REV21;
125802 + bman_pool_max = 64;
125803 + bman_portal_max = 50;
125804 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
125805 + bman_ip_rev = BMAN_REV21;
125806 + bman_pool_max = 64;
125807 + bman_portal_max = 25;
125808 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
125809 + bman_ip_rev = BMAN_REV21;
125810 + bman_pool_max = 64;
125811 + bman_portal_max = 18;
125812 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
125813 + bman_ip_rev = BMAN_REV21;
125814 + bman_pool_max = 64;
125815 + bman_portal_max = 10;
125816 + } else {
125817 + pr_warn("unknown BMan version in portal node,"
125818 + "default to rev1.0\n");
125819 + bman_ip_rev = BMAN_REV10;
125820 + bman_pool_max = 64;
125821 + bman_portal_max = 10;
125822 + }
125823 +
125824 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
125825 + &pcfg->addr_phys[DPA_PORTAL_CE]);
125826 + if (ret) {
125827 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
125828 + goto err;
125829 + }
125830 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
125831 + &pcfg->addr_phys[DPA_PORTAL_CI]);
125832 + if (ret) {
125833 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
125834 + goto err;
125835 + }
125836 +
125837 + index = of_get_property(node, "cell-index", &ret);
125838 + if (!index || (ret != 4)) {
125839 + pr_err("Can't get %s property '%s'\n", node->full_name,
125840 + "cell-index");
125841 + goto err;
125842 + }
125843 + if (be32_to_cpu(*index) >= bman_portal_max) {
125844 + pr_err("BMan portal cell index %d out of range, max %d\n",
125845 + be32_to_cpu(*index), bman_portal_max);
125846 + goto err;
125847 + }
125848 +
125849 + pcfg->public_cfg.cpu = -1;
125850 +
125851 + irq = irq_of_parse_and_map(node, 0);
125852 + if (irq == 0) {
125853 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
125854 + goto err;
125855 + }
125856 + pcfg->public_cfg.irq = irq;
125857 + pcfg->public_cfg.index = be32_to_cpu(*index);
125858 + bman_depletion_fill(&pcfg->public_cfg.mask);
125859 +
125860 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
125861 + if (len != (unsigned long)len)
125862 + goto err;
125863 +
125864 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
125865 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
125866 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125867 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
125868 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
125869 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125870 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
125871 +
125872 +#else
125873 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
125874 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125875 + (unsigned long)len,
125876 + 0);
125877 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
125878 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125879 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
125880 + _PAGE_GUARDED | _PAGE_NO_CACHE);
125881 +#endif
125882 + /* disable bp depletion */
125883 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
125884 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
125885 + return pcfg;
125886 +err:
125887 + kfree(pcfg);
125888 + return NULL;
125889 +}
125890 +
125891 +static struct bm_portal_config *get_pcfg(struct list_head *list)
125892 +{
125893 + struct bm_portal_config *pcfg;
125894 + if (list_empty(list))
125895 + return NULL;
125896 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
125897 + list_del(&pcfg->list);
125898 + return pcfg;
125899 +}
125900 +
125901 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
125902 + uint32_t idx)
125903 +{
125904 + struct bm_portal_config *pcfg;
125905 + if (list_empty(list))
125906 + return NULL;
125907 + list_for_each_entry(pcfg, list, list) {
125908 + if (pcfg->public_cfg.index == idx) {
125909 + list_del(&pcfg->list);
125910 + return pcfg;
125911 + }
125912 + }
125913 + return NULL;
125914 +}
125915 +
125916 +struct bm_portal_config *bm_get_unused_portal(void)
125917 +{
125918 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
125919 +}
125920 +
125921 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
125922 +{
125923 + struct bm_portal_config *ret;
125924 + spin_lock(&unused_pcfgs_lock);
125925 + if (idx == QBMAN_ANY_PORTAL_IDX)
125926 + ret = get_pcfg(&unused_pcfgs);
125927 + else
125928 + ret = get_pcfg_idx(&unused_pcfgs, idx);
125929 + spin_unlock(&unused_pcfgs_lock);
125930 + return ret;
125931 +}
125932 +
125933 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
125934 +{
125935 + spin_lock(&unused_pcfgs_lock);
125936 + list_add(&pcfg->list, &unused_pcfgs);
125937 + spin_unlock(&unused_pcfgs_lock);
125938 +}
125939 +
125940 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
125941 +{
125942 + struct bman_portal *p;
125943 + p = bman_create_affine_portal(pcfg);
125944 + if (p) {
125945 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
125946 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
125947 +#endif
125948 + pr_info("Bman portal %sinitialised, cpu %d\n",
125949 + pcfg->public_cfg.is_shared ? "(shared) " : "",
125950 + pcfg->public_cfg.cpu);
125951 + affine_bportals[pcfg->public_cfg.cpu] = p;
125952 + } else
125953 + pr_crit("Bman portal failure on cpu %d\n",
125954 + pcfg->public_cfg.cpu);
125955 + return p;
125956 +}
125957 +
125958 +static void init_slave(int cpu)
125959 +{
125960 + struct bman_portal *p;
125961 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
125962 + if (!p)
125963 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
125964 + else
125965 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
125966 + if (shared_portals_idx >= num_shared_portals)
125967 + shared_portals_idx = 0;
125968 + affine_bportals[cpu] = p;
125969 +}
125970 +
125971 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
125972 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
125973 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
125974 + * explicitly mark it or them for sharing.
125975 + * Eg;
125976 + * bportals=s0,1-3,s4
125977 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
125978 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
125979 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
125980 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
125981 + * 0's portal.) */
125982 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
125983 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
125984 +
125985 +static int __init parse_bportals(char *str)
125986 +{
125987 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
125988 + "bportals");
125989 +}
125990 +__setup("bportals=", parse_bportals);
125991 +
125992 +static int bman_offline_cpu(unsigned int cpu)
125993 +{
125994 + struct bman_portal *p;
125995 + const struct bm_portal_config *pcfg;
125996 + p = (struct bman_portal *)affine_bportals[cpu];
125997 + if (p) {
125998 + pcfg = bman_get_bm_portal_config(p);
125999 + if (pcfg)
126000 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
126001 + }
126002 + return 0;
126003 +}
126004 +
126005 +#ifdef CONFIG_HOTPLUG_CPU
126006 +static int bman_online_cpu(unsigned int cpu)
126007 +{
126008 + struct bman_portal *p;
126009 + const struct bm_portal_config *pcfg;
126010 + p = (struct bman_portal *)affine_bportals[cpu];
126011 + if (p) {
126012 + pcfg = bman_get_bm_portal_config(p);
126013 + if (pcfg)
126014 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
126015 + }
126016 + return 0;
126017 +}
126018 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
126019 + unsigned long action, void *hcpu)
126020 +{
126021 + unsigned int cpu = (unsigned long)hcpu;
126022 +
126023 + switch (action) {
126024 + case CPU_ONLINE:
126025 + case CPU_ONLINE_FROZEN:
126026 + bman_online_cpu(cpu);
126027 + break;
126028 + case CPU_DOWN_PREPARE:
126029 + case CPU_DOWN_PREPARE_FROZEN:
126030 + bman_offline_cpu(cpu);
126031 + default:
126032 + break;
126033 + }
126034 + return NOTIFY_OK;
126035 +}
126036 +
126037 +static struct notifier_block bman_hotplug_cpu_notifier = {
126038 + .notifier_call = bman_hotplug_cpu_callback,
126039 +};
126040 +#endif /* CONFIG_HOTPLUG_CPU */
126041 +
126042 +/* Initialise the Bman driver. The meat of this function deals with portals. The
126043 + * following describes the flow of portal-handling, the code "steps" refer to
126044 + * this description;
126045 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
126046 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
126047 + * bound).
126048 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
126049 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
126050 + * them to cpus, placing them in the relevant list and setting ::cpu as
126051 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
126052 + * assign portals to all online cpus at the time of driver initialisation.
126053 + * Any failure to allocate portals (when parsing the "want" lists or when
126054 + * using default behaviour) will be silently tolerated (the "fixup" logic in
126055 + * step 3 will determine what happens in this case).
126056 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
126057 + * sharing and sharing is required (because not all cpus have been assigned
126058 + * portals), then one portal will marked for sharing. Conversely if no
126059 + * sharing is required, any portals marked for sharing will not be shared. It
126060 + * may be that sharing occurs when it wasn't expected, if portal allocation
126061 + * failed to honour all the requested assignments (including the default
126062 + * assignments if no bootarg is present).
126063 + * 4. Unshared portals are initialised on their respective cpus.
126064 + * 5. Shared portals are initialised on their respective cpus.
126065 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
126066 + * which are selected in a round-robin fashion.
126067 + * Any portal configs left unused are available for USDPAA allocation.
126068 + */
126069 +__init int bman_init(void)
126070 +{
126071 + struct cpumask slave_cpus;
126072 + struct cpumask unshared_cpus = *cpu_none_mask;
126073 + struct cpumask shared_cpus = *cpu_none_mask;
126074 + LIST_HEAD(unshared_pcfgs);
126075 + LIST_HEAD(shared_pcfgs);
126076 + struct device_node *dn;
126077 + struct bm_portal_config *pcfg;
126078 + struct bman_portal *p;
126079 + int cpu, ret;
126080 + struct cpumask offline_cpus;
126081 +
126082 + /* Initialise the Bman (CCSR) device */
126083 + for_each_compatible_node(dn, NULL, "fsl,bman") {
126084 + if (!bman_init_ccsr(dn))
126085 + pr_info("Bman err interrupt handler present\n");
126086 + else
126087 + pr_err("Bman CCSR setup failed\n");
126088 + }
126089 + /* Initialise any declared buffer pools */
126090 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
126091 + ret = fsl_bpool_init(dn);
126092 + if (ret)
126093 + return ret;
126094 + }
126095 + /* Step 1. See comments at the beginning of the file. */
126096 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
126097 + if (!of_device_is_available(dn))
126098 + continue;
126099 + pcfg = parse_pcfg(dn);
126100 + if (pcfg)
126101 + list_add_tail(&pcfg->list, &unused_pcfgs);
126102 + }
126103 + /* Step 2. */
126104 + for_each_possible_cpu(cpu) {
126105 + if (cpumask_test_cpu(cpu, &want_shared)) {
126106 + pcfg = get_pcfg(&unused_pcfgs);
126107 + if (!pcfg)
126108 + break;
126109 + pcfg->public_cfg.cpu = cpu;
126110 + list_add_tail(&pcfg->list, &shared_pcfgs);
126111 + cpumask_set_cpu(cpu, &shared_cpus);
126112 + }
126113 + if (cpumask_test_cpu(cpu, &want_unshared)) {
126114 + if (cpumask_test_cpu(cpu, &shared_cpus))
126115 + continue;
126116 + pcfg = get_pcfg(&unused_pcfgs);
126117 + if (!pcfg)
126118 + break;
126119 + pcfg->public_cfg.cpu = cpu;
126120 + list_add_tail(&pcfg->list, &unshared_pcfgs);
126121 + cpumask_set_cpu(cpu, &unshared_cpus);
126122 + }
126123 + }
126124 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
126125 + /* Default, give an unshared portal to each online cpu */
126126 + for_each_online_cpu(cpu) {
126127 + pcfg = get_pcfg(&unused_pcfgs);
126128 + if (!pcfg)
126129 + break;
126130 + pcfg->public_cfg.cpu = cpu;
126131 + list_add_tail(&pcfg->list, &unshared_pcfgs);
126132 + cpumask_set_cpu(cpu, &unshared_cpus);
126133 + }
126134 + }
126135 + /* Step 3. */
126136 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
126137 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
126138 + if (cpumask_empty(&slave_cpus)) {
126139 + /* No sharing required */
126140 + if (!list_empty(&shared_pcfgs)) {
126141 + /* Migrate "shared" to "unshared" */
126142 + cpumask_or(&unshared_cpus, &unshared_cpus,
126143 + &shared_cpus);
126144 + cpumask_clear(&shared_cpus);
126145 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
126146 + INIT_LIST_HEAD(&shared_pcfgs);
126147 + }
126148 + } else {
126149 + /* Sharing required */
126150 + if (list_empty(&shared_pcfgs)) {
126151 + /* Migrate one "unshared" to "shared" */
126152 + pcfg = get_pcfg(&unshared_pcfgs);
126153 + if (!pcfg) {
126154 + pr_crit("No BMan portals available!\n");
126155 + return 0;
126156 + }
126157 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
126158 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
126159 + list_add_tail(&pcfg->list, &shared_pcfgs);
126160 + }
126161 + }
126162 + /* Step 4. */
126163 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
126164 + pcfg->public_cfg.is_shared = 0;
126165 + p = init_pcfg(pcfg);
126166 + if (!p) {
126167 + pr_crit("Unable to initialize bman portal\n");
126168 + return 0;
126169 + }
126170 + }
126171 + /* Step 5. */
126172 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
126173 + pcfg->public_cfg.is_shared = 1;
126174 + p = init_pcfg(pcfg);
126175 + if (p)
126176 + shared_portals[num_shared_portals++] = p;
126177 + }
126178 + /* Step 6. */
126179 + if (!cpumask_empty(&slave_cpus))
126180 + for_each_cpu(cpu, &slave_cpus)
126181 + init_slave(cpu);
126182 + pr_info("Bman portals initialised\n");
126183 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
126184 + for_each_cpu(cpu, &offline_cpus)
126185 + bman_offline_cpu(cpu);
126186 +#ifdef CONFIG_HOTPLUG_CPU
126187 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
126188 +#endif
126189 + return 0;
126190 +}
126191 +
126192 +__init int bman_resource_init(void)
126193 +{
126194 + struct device_node *dn;
126195 + int ret;
126196 +
126197 + /* Initialise BPID allocation ranges */
126198 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
126199 + ret = fsl_bpid_range_init(dn);
126200 + if (ret)
126201 + return ret;
126202 + }
126203 + return 0;
126204 +}
126205 +
126206 +#ifdef CONFIG_SUSPEND
126207 +void suspend_unused_bportal(void)
126208 +{
126209 + struct bm_portal_config *pcfg;
126210 +
126211 + if (list_empty(&unused_pcfgs))
126212 + return;
126213 +
126214 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126215 +#ifdef CONFIG_PM_DEBUG
126216 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
126217 +#endif
126218 + /* save isdr, disable all via isdr, clear isr */
126219 + pcfg->saved_isdr =
126220 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126221 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126222 + 0xe08);
126223 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126224 + 0xe00);
126225 + }
126226 + return;
126227 +}
126228 +
126229 +void resume_unused_bportal(void)
126230 +{
126231 + struct bm_portal_config *pcfg;
126232 +
126233 + if (list_empty(&unused_pcfgs))
126234 + return;
126235 +
126236 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126237 +#ifdef CONFIG_PM_DEBUG
126238 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
126239 +#endif
126240 + /* restore isdr */
126241 + __raw_writel(pcfg->saved_isdr,
126242 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126243 + }
126244 + return;
126245 +}
126246 +#endif
126247 diff --git a/drivers/staging/fsl_qbman/bman_high.c b/drivers/staging/fsl_qbman/bman_high.c
126248 new file mode 100644
126249 index 00000000..c066602d
126250 --- /dev/null
126251 +++ b/drivers/staging/fsl_qbman/bman_high.c
126252 @@ -0,0 +1,1145 @@
126253 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
126254 + *
126255 + * Redistribution and use in source and binary forms, with or without
126256 + * modification, are permitted provided that the following conditions are met:
126257 + * * Redistributions of source code must retain the above copyright
126258 + * notice, this list of conditions and the following disclaimer.
126259 + * * Redistributions in binary form must reproduce the above copyright
126260 + * notice, this list of conditions and the following disclaimer in the
126261 + * documentation and/or other materials provided with the distribution.
126262 + * * Neither the name of Freescale Semiconductor nor the
126263 + * names of its contributors may be used to endorse or promote products
126264 + * derived from this software without specific prior written permission.
126265 + *
126266 + *
126267 + * ALTERNATIVELY, this software may be distributed under the terms of the
126268 + * GNU General Public License ("GPL") as published by the Free Software
126269 + * Foundation, either version 2 of that License or (at your option) any
126270 + * later version.
126271 + *
126272 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126273 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126274 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126275 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126276 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126277 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126278 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126279 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126280 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126281 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126282 + */
126283 +
126284 +#include "bman_low.h"
126285 +
126286 +/* Compilation constants */
126287 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
126288 +#define IRQNAME "BMan portal %d"
126289 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
126290 +
126291 +struct bman_portal {
126292 + struct bm_portal p;
126293 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
126294 + struct bman_depletion *pools;
126295 + int thresh_set;
126296 + unsigned long irq_sources;
126297 + u32 slowpoll; /* only used when interrupts are off */
126298 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126299 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
126300 +#endif
126301 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126302 + raw_spinlock_t sharing_lock; /* only used if is_shared */
126303 + int is_shared;
126304 + struct bman_portal *sharing_redirect;
126305 +#endif
126306 + /* When the cpu-affine portal is activated, this is non-NULL */
126307 + const struct bm_portal_config *config;
126308 + /* This is needed for power management */
126309 + struct platform_device *pdev;
126310 + /* 64-entry hash-table of pool objects that are tracking depletion
126311 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
126312 + * we're not fussy about cache-misses and so forth - whereas the above
126313 + * members should all fit in one cacheline.
126314 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
126315 + * you'll never guess the hash-function ... */
126316 + struct bman_pool *cb[64];
126317 + char irqname[MAX_IRQNAME];
126318 + /* Track if the portal was alloced by the driver */
126319 + u8 alloced;
126320 + /* power management data */
126321 + u32 save_isdr;
126322 +};
126323 +
126324 +/* For an explanation of the locking, redirection, or affine-portal logic,
126325 + * please consult the Qman driver for details. This is the same, only simpler
126326 + * (no fiddly Qman-specific bits.) */
126327 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126328 +#define PORTAL_IRQ_LOCK(p, irqflags) \
126329 + do { \
126330 + if ((p)->is_shared) \
126331 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
126332 + else \
126333 + local_irq_save(irqflags); \
126334 + } while (0)
126335 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
126336 + do { \
126337 + if ((p)->is_shared) \
126338 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
126339 + irqflags); \
126340 + else \
126341 + local_irq_restore(irqflags); \
126342 + } while (0)
126343 +#else
126344 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
126345 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
126346 +#endif
126347 +
126348 +static cpumask_t affine_mask;
126349 +static DEFINE_SPINLOCK(affine_mask_lock);
126350 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
126351 +static inline struct bman_portal *get_raw_affine_portal(void)
126352 +{
126353 + return &get_cpu_var(bman_affine_portal);
126354 +}
126355 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126356 +static inline struct bman_portal *get_affine_portal(void)
126357 +{
126358 + struct bman_portal *p = get_raw_affine_portal();
126359 + if (p->sharing_redirect)
126360 + return p->sharing_redirect;
126361 + return p;
126362 +}
126363 +#else
126364 +#define get_affine_portal() get_raw_affine_portal()
126365 +#endif
126366 +static inline void put_affine_portal(void)
126367 +{
126368 + put_cpu_var(bman_affine_portal);
126369 +}
126370 +static inline struct bman_portal *get_poll_portal(void)
126371 +{
126372 + return &get_cpu_var(bman_affine_portal);
126373 +}
126374 +#define put_poll_portal()
126375 +
126376 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
126377 + * more than one such object per Bman buffer pool, eg. if different users of the
126378 + * pool are operating via different portals. */
126379 +struct bman_pool {
126380 + struct bman_pool_params params;
126381 + /* Used for hash-table admin when using depletion notifications. */
126382 + struct bman_portal *portal;
126383 + struct bman_pool *next;
126384 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
126385 + struct bm_buffer *sp;
126386 + unsigned int sp_fill;
126387 +#ifdef CONFIG_FSL_DPA_CHECKING
126388 + atomic_t in_use;
126389 +#endif
126390 +};
126391 +
126392 +/* (De)Registration of depletion notification callbacks */
126393 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
126394 +{
126395 + __maybe_unused unsigned long irqflags;
126396 + pool->portal = portal;
126397 + PORTAL_IRQ_LOCK(portal, irqflags);
126398 + pool->next = portal->cb[pool->params.bpid];
126399 + portal->cb[pool->params.bpid] = pool;
126400 + if (!pool->next)
126401 + /* First object for that bpid on this portal, enable the BSCN
126402 + * mask bit. */
126403 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
126404 + PORTAL_IRQ_UNLOCK(portal, irqflags);
126405 +}
126406 +static void depletion_unlink(struct bman_pool *pool)
126407 +{
126408 + struct bman_pool *it, *last = NULL;
126409 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
126410 + __maybe_unused unsigned long irqflags;
126411 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
126412 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
126413 + while (it != pool) {
126414 + last = it;
126415 + it = it->next;
126416 + }
126417 + if (!last)
126418 + *base = pool->next;
126419 + else
126420 + last->next = pool->next;
126421 + if (!last && !pool->next) {
126422 + /* Last object for that bpid on this portal, disable the BSCN
126423 + * mask bit. */
126424 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
126425 + /* And "forget" that we last saw this pool as depleted */
126426 + bman_depletion_unset(&pool->portal->pools[1],
126427 + pool->params.bpid);
126428 + }
126429 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
126430 +}
126431 +
126432 +/* In the case that the application's core loop calls qman_poll() and
126433 + * bman_poll(), we ought to balance how often we incur the overheads of the
126434 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
126435 + * constant is used when the last slow-poll detected no work to do, and the busy
126436 + * decrementer constant when the last slow-poll had work to do. */
126437 +#define SLOW_POLL_IDLE 1000
126438 +#define SLOW_POLL_BUSY 10
126439 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
126440 +
126441 +/* Portal interrupt handler */
126442 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
126443 +{
126444 + struct bman_portal *p = ptr;
126445 + u32 clear = p->irq_sources;
126446 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
126447 + clear |= __poll_portal_slow(p, is);
126448 + bm_isr_status_clear(&p->p, clear);
126449 + return IRQ_HANDLED;
126450 +}
126451 +
126452 +#ifdef CONFIG_SUSPEND
126453 +static int _bman_portal_suspend_noirq(struct device *dev)
126454 +{
126455 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126456 +#ifdef CONFIG_PM_DEBUG
126457 + struct platform_device *pdev = to_platform_device(dev);
126458 +#endif
126459 + p->save_isdr = bm_isr_disable_read(&p->p);
126460 + bm_isr_disable_write(&p->p, 0xffffffff);
126461 + bm_isr_status_clear(&p->p, 0xffffffff);
126462 +#ifdef CONFIG_PM_DEBUG
126463 + pr_info("Suspend for %s\n", pdev->name);
126464 +#endif
126465 + return 0;
126466 +}
126467 +
126468 +static int _bman_portal_resume_noirq(struct device *dev)
126469 +{
126470 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126471 +
126472 + /* restore isdr */
126473 + bm_isr_disable_write(&p->p, p->save_isdr);
126474 + return 0;
126475 +}
126476 +#else
126477 +#define _bman_portal_suspend_noirq NULL
126478 +#define _bman_portal_resume_noirq NULL
126479 +#endif
126480 +
126481 +struct dev_pm_domain bman_portal_device_pm_domain = {
126482 + .ops = {
126483 + USE_PLATFORM_PM_SLEEP_OPS
126484 + .suspend_noirq = _bman_portal_suspend_noirq,
126485 + .resume_noirq = _bman_portal_resume_noirq,
126486 + }
126487 +};
126488 +
126489 +struct bman_portal *bman_create_portal(
126490 + struct bman_portal *portal,
126491 + const struct bm_portal_config *config)
126492 +{
126493 + struct bm_portal *__p;
126494 + const struct bman_depletion *pools = &config->public_cfg.mask;
126495 + int ret;
126496 + u8 bpid = 0;
126497 + char buf[16];
126498 +
126499 + if (!portal) {
126500 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
126501 + if (!portal)
126502 + return portal;
126503 + portal->alloced = 1;
126504 + } else
126505 + portal->alloced = 0;
126506 +
126507 + __p = &portal->p;
126508 +
126509 + /* prep the low-level portal struct with the mapped addresses from the
126510 + * config, everything that follows depends on it and "config" is more
126511 + * for (de)reference... */
126512 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
126513 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
126514 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
126515 + pr_err("Bman RCR initialisation failed\n");
126516 + goto fail_rcr;
126517 + }
126518 + if (bm_mc_init(__p)) {
126519 + pr_err("Bman MC initialisation failed\n");
126520 + goto fail_mc;
126521 + }
126522 + if (bm_isr_init(__p)) {
126523 + pr_err("Bman ISR initialisation failed\n");
126524 + goto fail_isr;
126525 + }
126526 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
126527 + if (!portal->pools)
126528 + goto fail_pools;
126529 + portal->pools[0] = *pools;
126530 + bman_depletion_init(portal->pools + 1);
126531 + while (bpid < bman_pool_max) {
126532 + /* Default to all BPIDs disabled, we enable as required at
126533 + * run-time. */
126534 + bm_isr_bscn_mask(__p, bpid, 0);
126535 + bpid++;
126536 + }
126537 + portal->slowpoll = 0;
126538 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126539 + portal->rcri_owned = NULL;
126540 +#endif
126541 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126542 + raw_spin_lock_init(&portal->sharing_lock);
126543 + portal->is_shared = config->public_cfg.is_shared;
126544 + portal->sharing_redirect = NULL;
126545 +#endif
126546 + sprintf(buf, "bportal-%u", config->public_cfg.index);
126547 + portal->pdev = platform_device_alloc(buf, -1);
126548 + if (!portal->pdev)
126549 + goto fail_devalloc;
126550 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
126551 + portal->pdev->dev.platform_data = portal;
126552 + ret = platform_device_add(portal->pdev);
126553 + if (ret)
126554 + goto fail_devadd;
126555 + memset(&portal->cb, 0, sizeof(portal->cb));
126556 + /* Write-to-clear any stale interrupt status bits */
126557 + bm_isr_disable_write(__p, 0xffffffff);
126558 + portal->irq_sources = 0;
126559 + bm_isr_enable_write(__p, portal->irq_sources);
126560 + bm_isr_status_clear(__p, 0xffffffff);
126561 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
126562 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
126563 + portal)) {
126564 + pr_err("request_irq() failed\n");
126565 + goto fail_irq;
126566 + }
126567 + if ((config->public_cfg.cpu != -1) &&
126568 + irq_can_set_affinity(config->public_cfg.irq) &&
126569 + irq_set_affinity(config->public_cfg.irq,
126570 + cpumask_of(config->public_cfg.cpu))) {
126571 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
126572 + goto fail_affinity;
126573 + }
126574 +
126575 + /* Need RCR to be empty before continuing */
126576 + ret = bm_rcr_get_fill(__p);
126577 + if (ret) {
126578 + pr_err("Bman RCR unclean\n");
126579 + goto fail_rcr_empty;
126580 + }
126581 + /* Success */
126582 + portal->config = config;
126583 +
126584 + bm_isr_disable_write(__p, 0);
126585 + bm_isr_uninhibit(__p);
126586 + return portal;
126587 +fail_rcr_empty:
126588 +fail_affinity:
126589 + free_irq(config->public_cfg.irq, portal);
126590 +fail_irq:
126591 + platform_device_del(portal->pdev);
126592 +fail_devadd:
126593 + platform_device_put(portal->pdev);
126594 +fail_devalloc:
126595 + kfree(portal->pools);
126596 +fail_pools:
126597 + bm_isr_finish(__p);
126598 +fail_isr:
126599 + bm_mc_finish(__p);
126600 +fail_mc:
126601 + bm_rcr_finish(__p);
126602 +fail_rcr:
126603 + if (portal->alloced)
126604 + kfree(portal);
126605 + return NULL;
126606 +}
126607 +
126608 +struct bman_portal *bman_create_affine_portal(
126609 + const struct bm_portal_config *config)
126610 +{
126611 + struct bman_portal *portal;
126612 +
126613 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
126614 + portal = bman_create_portal(portal, config);
126615 + if (portal) {
126616 + spin_lock(&affine_mask_lock);
126617 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
126618 + spin_unlock(&affine_mask_lock);
126619 + }
126620 + return portal;
126621 +}
126622 +
126623 +
126624 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
126625 + int cpu)
126626 +{
126627 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126628 + struct bman_portal *p;
126629 + p = &per_cpu(bman_affine_portal, cpu);
126630 + BUG_ON(p->config);
126631 + BUG_ON(p->is_shared);
126632 + BUG_ON(!redirect->config->public_cfg.is_shared);
126633 + p->irq_sources = 0;
126634 + p->sharing_redirect = redirect;
126635 + return p;
126636 +#else
126637 + BUG();
126638 + return NULL;
126639 +#endif
126640 +}
126641 +
126642 +void bman_destroy_portal(struct bman_portal *bm)
126643 +{
126644 + const struct bm_portal_config *pcfg;
126645 + pcfg = bm->config;
126646 + bm_rcr_cce_update(&bm->p);
126647 + bm_rcr_cce_update(&bm->p);
126648 +
126649 + free_irq(pcfg->public_cfg.irq, bm);
126650 +
126651 + kfree(bm->pools);
126652 + bm_isr_finish(&bm->p);
126653 + bm_mc_finish(&bm->p);
126654 + bm_rcr_finish(&bm->p);
126655 + bm->config = NULL;
126656 + if (bm->alloced)
126657 + kfree(bm);
126658 +}
126659 +
126660 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126661 +{
126662 + struct bman_portal *bm = get_raw_affine_portal();
126663 + const struct bm_portal_config *pcfg;
126664 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126665 + if (bm->sharing_redirect) {
126666 + bm->sharing_redirect = NULL;
126667 + put_affine_portal();
126668 + return NULL;
126669 + }
126670 + bm->is_shared = 0;
126671 +#endif
126672 + pcfg = bm->config;
126673 + bman_destroy_portal(bm);
126674 + spin_lock(&affine_mask_lock);
126675 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126676 + spin_unlock(&affine_mask_lock);
126677 + put_affine_portal();
126678 + return pcfg;
126679 +}
126680 +
126681 +/* When release logic waits on available RCR space, we need a global waitqueue
126682 + * in the case of "affine" use (as the waits wake on different cpus which means
126683 + * different portals - so we can't wait on any per-portal waitqueue). */
126684 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126685 +
126686 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126687 +{
126688 + struct bman_depletion tmp;
126689 + u32 ret = is;
126690 +
126691 + /* There is a gotcha to be aware of. If we do the query before clearing
126692 + * the status register, we may miss state changes that occur between the
126693 + * two. If we write to clear the status register before the query, the
126694 + * cache-enabled query command may overtake the status register write
126695 + * unless we use a heavyweight sync (which we don't want). Instead, we
126696 + * write-to-clear the status register then *read it back* before doing
126697 + * the query, hence the odd while loop with the 'is' accumulation. */
126698 + if (is & BM_PIRQ_BSCN) {
126699 + struct bm_mc_result *mcr;
126700 + __maybe_unused unsigned long irqflags;
126701 + unsigned int i, j;
126702 + u32 __is;
126703 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126704 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126705 + is |= __is;
126706 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126707 + }
126708 + is &= ~BM_PIRQ_BSCN;
126709 + PORTAL_IRQ_LOCK(p, irqflags);
126710 + bm_mc_start(&p->p);
126711 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126712 + while (!(mcr = bm_mc_result(&p->p)))
126713 + cpu_relax();
126714 + tmp = mcr->query.ds.state;
126715 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126716 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126717 + PORTAL_IRQ_UNLOCK(p, irqflags);
126718 + for (i = 0; i < 2; i++) {
126719 + int idx = i * 32;
126720 + /* tmp is a mask of currently-depleted pools.
126721 + * pools[0] is mask of those we care about.
126722 + * pools[1] is our previous view (we only want to
126723 + * be told about changes). */
126724 + tmp.__state[i] &= p->pools[0].__state[i];
126725 + if (tmp.__state[i] == p->pools[1].__state[i])
126726 + /* fast-path, nothing to see, move along */
126727 + continue;
126728 + for (j = 0; j <= 31; j++, idx++) {
126729 + struct bman_pool *pool = p->cb[idx];
126730 + int b4 = bman_depletion_get(&p->pools[1], idx);
126731 + int af = bman_depletion_get(&tmp, idx);
126732 + if (b4 == af)
126733 + continue;
126734 + while (pool) {
126735 + pool->params.cb(p, pool,
126736 + pool->params.cb_ctx, af);
126737 + pool = pool->next;
126738 + }
126739 + }
126740 + }
126741 + p->pools[1] = tmp;
126742 + }
126743 +
126744 + if (is & BM_PIRQ_RCRI) {
126745 + __maybe_unused unsigned long irqflags;
126746 + PORTAL_IRQ_LOCK(p, irqflags);
126747 + bm_rcr_cce_update(&p->p);
126748 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126749 + /* If waiting for sync, we only cancel the interrupt threshold
126750 + * when the ring utilisation hits zero. */
126751 + if (p->rcri_owned) {
126752 + if (!bm_rcr_get_fill(&p->p)) {
126753 + p->rcri_owned = NULL;
126754 + bm_rcr_set_ithresh(&p->p, 0);
126755 + }
126756 + } else
126757 +#endif
126758 + bm_rcr_set_ithresh(&p->p, 0);
126759 + PORTAL_IRQ_UNLOCK(p, irqflags);
126760 + wake_up(&affine_queue);
126761 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126762 + is &= ~BM_PIRQ_RCRI;
126763 + }
126764 +
126765 + /* There should be no status register bits left undefined */
126766 + DPA_ASSERT(!is);
126767 + return ret;
126768 +}
126769 +
126770 +const struct bman_portal_config *bman_get_portal_config(void)
126771 +{
126772 + struct bman_portal *p = get_affine_portal();
126773 + const struct bman_portal_config *ret = &p->config->public_cfg;
126774 + put_affine_portal();
126775 + return ret;
126776 +}
126777 +EXPORT_SYMBOL(bman_get_portal_config);
126778 +
126779 +u32 bman_irqsource_get(void)
126780 +{
126781 + struct bman_portal *p = get_raw_affine_portal();
126782 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126783 + put_affine_portal();
126784 + return ret;
126785 +}
126786 +EXPORT_SYMBOL(bman_irqsource_get);
126787 +
126788 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126789 +{
126790 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126791 + if (p->sharing_redirect)
126792 + return -EINVAL;
126793 + else
126794 +#endif
126795 + {
126796 + __maybe_unused unsigned long irqflags;
126797 + PORTAL_IRQ_LOCK(p, irqflags);
126798 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
126799 + bm_isr_enable_write(&p->p, p->irq_sources);
126800 + PORTAL_IRQ_UNLOCK(p, irqflags);
126801 + }
126802 + return 0;
126803 +}
126804 +EXPORT_SYMBOL(bman_p_irqsource_add);
126805 +
126806 +int bman_irqsource_add(__maybe_unused u32 bits)
126807 +{
126808 + struct bman_portal *p = get_raw_affine_portal();
126809 + int ret = 0;
126810 + ret = bman_p_irqsource_add(p, bits);
126811 + put_affine_portal();
126812 + return ret;
126813 +}
126814 +EXPORT_SYMBOL(bman_irqsource_add);
126815 +
126816 +int bman_irqsource_remove(u32 bits)
126817 +{
126818 + struct bman_portal *p = get_raw_affine_portal();
126819 + __maybe_unused unsigned long irqflags;
126820 + u32 ier;
126821 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126822 + if (p->sharing_redirect) {
126823 + put_affine_portal();
126824 + return -EINVAL;
126825 + }
126826 +#endif
126827 + /* Our interrupt handler only processes+clears status register bits that
126828 + * are in p->irq_sources. As we're trimming that mask, if one of them
126829 + * were to assert in the status register just before we remove it from
126830 + * the enable register, there would be an interrupt-storm when we
126831 + * release the IRQ lock. So we wait for the enable register update to
126832 + * take effect in h/w (by reading it back) and then clear all other bits
126833 + * in the status register. Ie. we clear them from ISR once it's certain
126834 + * IER won't allow them to reassert. */
126835 + PORTAL_IRQ_LOCK(p, irqflags);
126836 + bits &= BM_PIRQ_VISIBLE;
126837 + clear_bits(bits, &p->irq_sources);
126838 + bm_isr_enable_write(&p->p, p->irq_sources);
126839 + ier = bm_isr_enable_read(&p->p);
126840 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
126841 + * data-dependency, ie. to protect against re-ordering. */
126842 + bm_isr_status_clear(&p->p, ~ier);
126843 + PORTAL_IRQ_UNLOCK(p, irqflags);
126844 + put_affine_portal();
126845 + return 0;
126846 +}
126847 +EXPORT_SYMBOL(bman_irqsource_remove);
126848 +
126849 +const cpumask_t *bman_affine_cpus(void)
126850 +{
126851 + return &affine_mask;
126852 +}
126853 +EXPORT_SYMBOL(bman_affine_cpus);
126854 +
126855 +u32 bman_poll_slow(void)
126856 +{
126857 + struct bman_portal *p = get_poll_portal();
126858 + u32 ret;
126859 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126860 + if (unlikely(p->sharing_redirect))
126861 + ret = (u32)-1;
126862 + else
126863 +#endif
126864 + {
126865 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126866 + ret = __poll_portal_slow(p, is);
126867 + bm_isr_status_clear(&p->p, ret);
126868 + }
126869 + put_poll_portal();
126870 + return ret;
126871 +}
126872 +EXPORT_SYMBOL(bman_poll_slow);
126873 +
126874 +/* Legacy wrapper */
126875 +void bman_poll(void)
126876 +{
126877 + struct bman_portal *p = get_poll_portal();
126878 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126879 + if (unlikely(p->sharing_redirect))
126880 + goto done;
126881 +#endif
126882 + if (!(p->slowpoll--)) {
126883 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126884 + u32 active = __poll_portal_slow(p, is);
126885 + if (active)
126886 + p->slowpoll = SLOW_POLL_BUSY;
126887 + else
126888 + p->slowpoll = SLOW_POLL_IDLE;
126889 + }
126890 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126891 +done:
126892 +#endif
126893 + put_poll_portal();
126894 +}
126895 +EXPORT_SYMBOL(bman_poll);
126896 +
126897 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
126898 +
126899 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
126900 +{
126901 + struct bman_pool *pool = NULL;
126902 + u32 bpid;
126903 +
126904 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
126905 + int ret = bman_alloc_bpid(&bpid);
126906 + if (ret)
126907 + return NULL;
126908 + } else {
126909 + if (params->bpid >= bman_pool_max)
126910 + return NULL;
126911 + bpid = params->bpid;
126912 + }
126913 +#ifdef CONFIG_FSL_BMAN_CONFIG
126914 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
126915 + int ret = bm_pool_set(bpid, params->thresholds);
126916 + if (ret)
126917 + goto err;
126918 + }
126919 +#else
126920 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126921 + goto err;
126922 +#endif
126923 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
126924 + if (!pool)
126925 + goto err;
126926 + pool->sp = NULL;
126927 + pool->sp_fill = 0;
126928 + pool->params = *params;
126929 +#ifdef CONFIG_FSL_DPA_CHECKING
126930 + atomic_set(&pool->in_use, 1);
126931 +#endif
126932 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126933 + pool->params.bpid = bpid;
126934 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
126935 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
126936 + GFP_KERNEL);
126937 + if (!pool->sp)
126938 + goto err;
126939 + }
126940 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
126941 + struct bman_portal *p = get_affine_portal();
126942 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
126943 + pr_err("Depletion events disabled for bpid %d\n", bpid);
126944 + goto err;
126945 + }
126946 + depletion_link(p, pool);
126947 + put_affine_portal();
126948 + }
126949 + return pool;
126950 +err:
126951 +#ifdef CONFIG_FSL_BMAN_CONFIG
126952 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126953 + bm_pool_set(bpid, zero_thresholds);
126954 +#endif
126955 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126956 + bman_release_bpid(bpid);
126957 + if (pool) {
126958 + kfree(pool->sp);
126959 + kfree(pool);
126960 + }
126961 + return NULL;
126962 +}
126963 +EXPORT_SYMBOL(bman_new_pool);
126964 +
126965 +void bman_free_pool(struct bman_pool *pool)
126966 +{
126967 +#ifdef CONFIG_FSL_BMAN_CONFIG
126968 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
126969 + bm_pool_set(pool->params.bpid, zero_thresholds);
126970 +#endif
126971 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
126972 + depletion_unlink(pool);
126973 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
126974 + if (pool->sp_fill)
126975 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
126976 + pool->sp_fill, pool->params.bpid);
126977 + kfree(pool->sp);
126978 + pool->sp = NULL;
126979 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
126980 + }
126981 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126982 + bman_release_bpid(pool->params.bpid);
126983 + kfree(pool);
126984 +}
126985 +EXPORT_SYMBOL(bman_free_pool);
126986 +
126987 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
126988 +{
126989 + return &pool->params;
126990 +}
126991 +EXPORT_SYMBOL(bman_get_params);
126992 +
126993 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
126994 +{
126995 + if (avail)
126996 + bm_rcr_cce_prefetch(&p->p);
126997 + else
126998 + bm_rcr_cce_update(&p->p);
126999 +}
127000 +
127001 +int bman_rcr_is_empty(void)
127002 +{
127003 + __maybe_unused unsigned long irqflags;
127004 + struct bman_portal *p = get_affine_portal();
127005 + u8 avail;
127006 +
127007 + PORTAL_IRQ_LOCK(p, irqflags);
127008 + update_rcr_ci(p, 0);
127009 + avail = bm_rcr_get_fill(&p->p);
127010 + PORTAL_IRQ_UNLOCK(p, irqflags);
127011 + put_affine_portal();
127012 + return avail == 0;
127013 +}
127014 +EXPORT_SYMBOL(bman_rcr_is_empty);
127015 +
127016 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
127017 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127018 + __maybe_unused struct bman_pool *pool,
127019 +#endif
127020 + __maybe_unused unsigned long *irqflags,
127021 + __maybe_unused u32 flags)
127022 +{
127023 + struct bm_rcr_entry *r;
127024 + u8 avail;
127025 +
127026 + *p = get_affine_portal();
127027 + PORTAL_IRQ_LOCK(*p, (*irqflags));
127028 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127029 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127030 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127031 + if ((*p)->rcri_owned) {
127032 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
127033 + put_affine_portal();
127034 + return NULL;
127035 + }
127036 + (*p)->rcri_owned = pool;
127037 + }
127038 +#endif
127039 + avail = bm_rcr_get_avail(&(*p)->p);
127040 + if (avail < 2)
127041 + update_rcr_ci(*p, avail);
127042 + r = bm_rcr_start(&(*p)->p);
127043 + if (unlikely(!r)) {
127044 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127045 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127046 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
127047 + (*p)->rcri_owned = NULL;
127048 +#endif
127049 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
127050 + put_affine_portal();
127051 + }
127052 + return r;
127053 +}
127054 +
127055 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127056 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
127057 + struct bman_pool *pool,
127058 + __maybe_unused unsigned long *irqflags,
127059 + u32 flags)
127060 +{
127061 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
127062 + if (!rcr)
127063 + bm_rcr_set_ithresh(&(*p)->p, 1);
127064 + return rcr;
127065 +}
127066 +
127067 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
127068 + struct bman_pool *pool,
127069 + __maybe_unused unsigned long *irqflags,
127070 + u32 flags)
127071 +{
127072 + struct bm_rcr_entry *rcr;
127073 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127074 + pool = NULL;
127075 +#endif
127076 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
127077 + /* NB: return NULL if signal occurs before completion. Signal
127078 + * can occur during return. Caller must check for signal */
127079 + wait_event_interruptible(affine_queue,
127080 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
127081 + else
127082 + wait_event(affine_queue,
127083 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
127084 + return rcr;
127085 +}
127086 +#endif
127087 +
127088 +static inline int __bman_release(struct bman_pool *pool,
127089 + const struct bm_buffer *bufs, u8 num, u32 flags)
127090 +{
127091 + struct bman_portal *p;
127092 + struct bm_rcr_entry *r;
127093 + __maybe_unused unsigned long irqflags;
127094 + u32 i = num - 1;
127095 +
127096 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127097 + if (flags & BMAN_RELEASE_FLAG_WAIT)
127098 + r = wait_rel_start(&p, pool, &irqflags, flags);
127099 + else
127100 + r = try_rel_start(&p, pool, &irqflags, flags);
127101 +#else
127102 + r = try_rel_start(&p, &irqflags, flags);
127103 +#endif
127104 + if (!r)
127105 + return -EBUSY;
127106 + /* We can copy all but the first entry, as this can trigger badness
127107 + * with the valid-bit. Use the overlay to mask the verb byte. */
127108 + r->bufs[0].opaque =
127109 + ((cpu_to_be64((bufs[0].opaque |
127110 + ((u64)pool->params.bpid<<48))
127111 + & 0x00ffffffffffffff)));
127112 + if (i) {
127113 + for (i = 1; i < num; i++)
127114 + r->bufs[i].opaque =
127115 + cpu_to_be64(bufs[i].opaque);
127116 + }
127117 +
127118 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
127119 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
127120 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127121 + /* if we wish to sync we need to set the threshold after h/w sees the
127122 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
127123 + * accesses, this requires a heavy-weight sync. */
127124 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127125 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127126 + hwsync();
127127 + bm_rcr_set_ithresh(&p->p, 1);
127128 + }
127129 +#endif
127130 + PORTAL_IRQ_UNLOCK(p, irqflags);
127131 + put_affine_portal();
127132 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127133 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127134 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127135 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
127136 + /* NB: return success even if signal occurs before
127137 + * condition is true. pvb_commit guarantees success */
127138 + wait_event_interruptible(affine_queue,
127139 + (p->rcri_owned != pool));
127140 + else
127141 + wait_event(affine_queue, (p->rcri_owned != pool));
127142 + }
127143 +#endif
127144 + return 0;
127145 +}
127146 +
127147 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
127148 + u32 flags)
127149 +{
127150 + int ret;
127151 +#ifdef CONFIG_FSL_DPA_CHECKING
127152 + if (!num || (num > 8))
127153 + return -EINVAL;
127154 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
127155 + return -EINVAL;
127156 +#endif
127157 + /* Without stockpile, this API is a pass-through to the h/w operation */
127158 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
127159 + return __bman_release(pool, bufs, num, flags);
127160 +#ifdef CONFIG_FSL_DPA_CHECKING
127161 + if (!atomic_dec_and_test(&pool->in_use)) {
127162 + pr_crit("Parallel attempts to enter bman_released() detected.");
127163 + panic("only one instance of bman_released/acquired allowed");
127164 + }
127165 +#endif
127166 + /* Two movements of buffers are possible, and can occur in either order.
127167 + * A: moving buffers from the caller to the stockpile.
127168 + * B: moving buffers from the stockpile to hardware.
127169 + * Order 1: if there is already enough space in the stockpile for A
127170 + * then we want to do A first, and only do B if we trigger the
127171 + * stockpile-high threshold.
127172 + * Order 2: if there is not enough space in the stockpile for A, then
127173 + * we want to do B first, then do A if B had succeeded. However in this
127174 + * case B is dependent on how many buffers the user needs to release,
127175 + * not the stockpile-high threshold.
127176 + * Due to the different handling of B between the two cases, putting A
127177 + * and B in a while() loop would require quite obscure logic, so handle
127178 + * the different sequences explicitly. */
127179 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
127180 + /* Order 1: do A */
127181 + copy_words(pool->sp + pool->sp_fill, bufs,
127182 + sizeof(struct bm_buffer) * num);
127183 + pool->sp_fill += num;
127184 + /* do B relative to STOCKPILE_HIGH */
127185 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
127186 + ret = __bman_release(pool,
127187 + pool->sp + (pool->sp_fill - 8), 8,
127188 + flags);
127189 + if (ret >= 0)
127190 + pool->sp_fill -= 8;
127191 + }
127192 + } else {
127193 + /* Order 2: do B relative to 'num' */
127194 + do {
127195 + ret = __bman_release(pool,
127196 + pool->sp + (pool->sp_fill - 8), 8,
127197 + flags);
127198 + if (ret < 0)
127199 + /* failure */
127200 + goto release_done;
127201 + pool->sp_fill -= 8;
127202 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
127203 + /* do A */
127204 + copy_words(pool->sp + pool->sp_fill, bufs,
127205 + sizeof(struct bm_buffer) * num);
127206 + pool->sp_fill += num;
127207 + }
127208 + /* success */
127209 + ret = 0;
127210 +release_done:
127211 +#ifdef CONFIG_FSL_DPA_CHECKING
127212 + atomic_inc(&pool->in_use);
127213 +#endif
127214 + return ret;
127215 +}
127216 +EXPORT_SYMBOL(bman_release);
127217 +
127218 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
127219 + u8 num)
127220 +{
127221 + struct bman_portal *p = get_affine_portal();
127222 + struct bm_mc_command *mcc;
127223 + struct bm_mc_result *mcr;
127224 + __maybe_unused unsigned long irqflags;
127225 + int ret, i;
127226 +
127227 + PORTAL_IRQ_LOCK(p, irqflags);
127228 + mcc = bm_mc_start(&p->p);
127229 + mcc->acquire.bpid = pool->params.bpid;
127230 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
127231 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
127232 + while (!(mcr = bm_mc_result(&p->p)))
127233 + cpu_relax();
127234 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
127235 + if (bufs) {
127236 + for (i = 0; i < num; i++)
127237 + bufs[i].opaque =
127238 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
127239 + }
127240 + PORTAL_IRQ_UNLOCK(p, irqflags);
127241 + put_affine_portal();
127242 + if (ret != num)
127243 + ret = -ENOMEM;
127244 + return ret;
127245 +}
127246 +
127247 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
127248 + u32 flags)
127249 +{
127250 + int ret;
127251 +#ifdef CONFIG_FSL_DPA_CHECKING
127252 + if (!num || (num > 8))
127253 + return -EINVAL;
127254 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
127255 + return -EINVAL;
127256 +#endif
127257 + /* Without stockpile, this API is a pass-through to the h/w operation */
127258 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
127259 + return __bman_acquire(pool, bufs, num);
127260 +#ifdef CONFIG_FSL_DPA_CHECKING
127261 + if (!atomic_dec_and_test(&pool->in_use)) {
127262 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
127263 + panic("only one instance of bman_released/acquired allowed");
127264 + }
127265 +#endif
127266 + /* Two movements of buffers are possible, and can occur in either order.
127267 + * A: moving buffers from stockpile to the caller.
127268 + * B: moving buffers from hardware to the stockpile.
127269 + * Order 1: if there are already enough buffers in the stockpile for A
127270 + * then we want to do A first, and only do B if we trigger the
127271 + * stockpile-low threshold.
127272 + * Order 2: if there are not enough buffers in the stockpile for A,
127273 + * then we want to do B first, then do A if B had succeeded. However in
127274 + * this case B is dependent on how many buffers the user needs, not the
127275 + * stockpile-low threshold.
127276 + * Due to the different handling of B between the two cases, putting A
127277 + * and B in a while() loop would require quite obscure logic, so handle
127278 + * the different sequences explicitly. */
127279 + if (num <= pool->sp_fill) {
127280 + /* Order 1: do A */
127281 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127282 + sizeof(struct bm_buffer) * num);
127283 + pool->sp_fill -= num;
127284 + /* do B relative to STOCKPILE_LOW */
127285 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
127286 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127287 + if (ret < 0)
127288 + ret = __bman_acquire(pool,
127289 + pool->sp + pool->sp_fill, 1);
127290 + if (ret < 0)
127291 + break;
127292 + pool->sp_fill += ret;
127293 + }
127294 + } else {
127295 + /* Order 2: do B relative to 'num' */
127296 + do {
127297 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127298 + if (ret < 0)
127299 + ret = __bman_acquire(pool,
127300 + pool->sp + pool->sp_fill, 1);
127301 + if (ret < 0)
127302 + /* failure */
127303 + goto acquire_done;
127304 + pool->sp_fill += ret;
127305 + } while (pool->sp_fill < num);
127306 + /* do A */
127307 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127308 + sizeof(struct bm_buffer) * num);
127309 + pool->sp_fill -= num;
127310 + }
127311 + /* success */
127312 + ret = num;
127313 +acquire_done:
127314 +#ifdef CONFIG_FSL_DPA_CHECKING
127315 + atomic_inc(&pool->in_use);
127316 +#endif
127317 + return ret;
127318 +}
127319 +EXPORT_SYMBOL(bman_acquire);
127320 +
127321 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
127322 +{
127323 + u8 num;
127324 + int ret;
127325 +
127326 + while (pool->sp_fill) {
127327 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
127328 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
127329 + num, flags);
127330 + if (ret)
127331 + return ret;
127332 + pool->sp_fill -= num;
127333 + }
127334 + return 0;
127335 +}
127336 +EXPORT_SYMBOL(bman_flush_stockpile);
127337 +
127338 +int bman_query_pools(struct bm_pool_state *state)
127339 +{
127340 + struct bman_portal *p = get_affine_portal();
127341 + struct bm_mc_result *mcr;
127342 + __maybe_unused unsigned long irqflags;
127343 +
127344 + PORTAL_IRQ_LOCK(p, irqflags);
127345 + bm_mc_start(&p->p);
127346 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
127347 + while (!(mcr = bm_mc_result(&p->p)))
127348 + cpu_relax();
127349 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
127350 + *state = mcr->query;
127351 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
127352 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
127353 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
127354 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
127355 + PORTAL_IRQ_UNLOCK(p, irqflags);
127356 + put_affine_portal();
127357 + return 0;
127358 +}
127359 +EXPORT_SYMBOL(bman_query_pools);
127360 +
127361 +#ifdef CONFIG_FSL_BMAN_CONFIG
127362 +u32 bman_query_free_buffers(struct bman_pool *pool)
127363 +{
127364 + return bm_pool_free_buffers(pool->params.bpid);
127365 +}
127366 +EXPORT_SYMBOL(bman_query_free_buffers);
127367 +
127368 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
127369 +{
127370 + u32 bpid;
127371 +
127372 + bpid = bman_get_params(pool)->bpid;
127373 +
127374 + return bm_pool_set(bpid, thresholds);
127375 +}
127376 +EXPORT_SYMBOL(bman_update_pool_thresholds);
127377 +#endif
127378 +
127379 +int bman_shutdown_pool(u32 bpid)
127380 +{
127381 + struct bman_portal *p = get_affine_portal();
127382 + __maybe_unused unsigned long irqflags;
127383 + int ret;
127384 +
127385 + PORTAL_IRQ_LOCK(p, irqflags);
127386 + ret = bm_shutdown_pool(&p->p, bpid);
127387 + PORTAL_IRQ_UNLOCK(p, irqflags);
127388 + put_affine_portal();
127389 + return ret;
127390 +}
127391 +EXPORT_SYMBOL(bman_shutdown_pool);
127392 +
127393 +const struct bm_portal_config *bman_get_bm_portal_config(
127394 + struct bman_portal *portal)
127395 +{
127396 + return portal->sharing_redirect ? NULL : portal->config;
127397 +}
127398 diff --git a/drivers/staging/fsl_qbman/bman_low.h b/drivers/staging/fsl_qbman/bman_low.h
127399 new file mode 100644
127400 index 00000000..3da70571
127401 --- /dev/null
127402 +++ b/drivers/staging/fsl_qbman/bman_low.h
127403 @@ -0,0 +1,565 @@
127404 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127405 + *
127406 + * Redistribution and use in source and binary forms, with or without
127407 + * modification, are permitted provided that the following conditions are met:
127408 + * * Redistributions of source code must retain the above copyright
127409 + * notice, this list of conditions and the following disclaimer.
127410 + * * Redistributions in binary form must reproduce the above copyright
127411 + * notice, this list of conditions and the following disclaimer in the
127412 + * documentation and/or other materials provided with the distribution.
127413 + * * Neither the name of Freescale Semiconductor nor the
127414 + * names of its contributors may be used to endorse or promote products
127415 + * derived from this software without specific prior written permission.
127416 + *
127417 + *
127418 + * ALTERNATIVELY, this software may be distributed under the terms of the
127419 + * GNU General Public License ("GPL") as published by the Free Software
127420 + * Foundation, either version 2 of that License or (at your option) any
127421 + * later version.
127422 + *
127423 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127424 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127425 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127426 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127427 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127428 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127429 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127430 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127431 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127432 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127433 + */
127434 +
127435 +#include "bman_private.h"
127436 +
127437 +/***************************/
127438 +/* Portal register assists */
127439 +/***************************/
127440 +
127441 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127442 +
127443 +/* Cache-inhibited register offsets */
127444 +#define BM_REG_RCR_PI_CINH 0x0000
127445 +#define BM_REG_RCR_CI_CINH 0x0004
127446 +#define BM_REG_RCR_ITR 0x0008
127447 +#define BM_REG_CFG 0x0100
127448 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
127449 +#define BM_REG_ISR 0x0e00
127450 +#define BM_REG_IIR 0x0e0c
127451 +
127452 +/* Cache-enabled register offsets */
127453 +#define BM_CL_CR 0x0000
127454 +#define BM_CL_RR0 0x0100
127455 +#define BM_CL_RR1 0x0140
127456 +#define BM_CL_RCR 0x1000
127457 +#define BM_CL_RCR_PI_CENA 0x3000
127458 +#define BM_CL_RCR_CI_CENA 0x3100
127459 +
127460 +#endif
127461 +
127462 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127463 +
127464 +/* Cache-inhibited register offsets */
127465 +#define BM_REG_RCR_PI_CINH 0x3000
127466 +#define BM_REG_RCR_CI_CINH 0x3100
127467 +#define BM_REG_RCR_ITR 0x3200
127468 +#define BM_REG_CFG 0x3300
127469 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
127470 +#define BM_REG_ISR 0x3e00
127471 +#define BM_REG_IIR 0x3ec0
127472 +
127473 +/* Cache-enabled register offsets */
127474 +#define BM_CL_CR 0x0000
127475 +#define BM_CL_RR0 0x0100
127476 +#define BM_CL_RR1 0x0140
127477 +#define BM_CL_RCR 0x1000
127478 +#define BM_CL_RCR_PI_CENA 0x3000
127479 +#define BM_CL_RCR_CI_CENA 0x3100
127480 +
127481 +#endif
127482 +
127483 +/* BTW, the drivers (and h/w programming model) already obtain the required
127484 + * synchronisation for portal accesses via lwsync(), hwsync(), and
127485 + * data-dependencies. Use of barrier()s or other order-preserving primitives
127486 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
127487 + * simply ensure that the compiler treats the portal registers as volatile (ie.
127488 + * non-coherent). */
127489 +
127490 +/* Cache-inhibited register access. */
127491 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
127492 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
127493 + (bm)->addr_ci + (o));
127494 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
127495 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
127496 +
127497 +/* Cache-enabled (index) register access */
127498 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
127499 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
127500 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
127501 +#define __bm_cl_out(bm, o, val) \
127502 + do { \
127503 + u32 *__tmpclout = (bm)->addr_ce + (o); \
127504 + __raw_writel(cpu_to_be32(val), __tmpclout); \
127505 + dcbf(__tmpclout); \
127506 + } while (0)
127507 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
127508 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
127509 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
127510 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
127511 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
127512 +#define bm_cl_invalidate(reg)\
127513 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
127514 +
127515 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
127516 + * analysis, look at using the "extra" bit in the ring index registers to avoid
127517 + * cyclic issues. */
127518 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
127519 +{
127520 + /* 'first' is included, 'last' is excluded */
127521 + if (first <= last)
127522 + return last - first;
127523 + return ringsize + last - first;
127524 +}
127525 +
127526 +/* Portal modes.
127527 + * Enum types;
127528 + * pmode == production mode
127529 + * cmode == consumption mode,
127530 + * Enum values use 3 letter codes. First letter matches the portal mode,
127531 + * remaining two letters indicate;
127532 + * ci == cache-inhibited portal register
127533 + * ce == cache-enabled portal register
127534 + * vb == in-band valid-bit (cache-enabled)
127535 + */
127536 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
127537 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
127538 + bm_rcr_pce = 1, /* PI index, cache-enabled */
127539 + bm_rcr_pvb = 2 /* valid-bit */
127540 +};
127541 +enum bm_rcr_cmode { /* s/w-only */
127542 + bm_rcr_cci, /* CI index, cache-inhibited */
127543 + bm_rcr_cce /* CI index, cache-enabled */
127544 +};
127545 +
127546 +
127547 +/* ------------------------- */
127548 +/* --- Portal structures --- */
127549 +
127550 +#define BM_RCR_SIZE 8
127551 +
127552 +struct bm_rcr {
127553 + struct bm_rcr_entry *ring, *cursor;
127554 + u8 ci, available, ithresh, vbit;
127555 +#ifdef CONFIG_FSL_DPA_CHECKING
127556 + u32 busy;
127557 + enum bm_rcr_pmode pmode;
127558 + enum bm_rcr_cmode cmode;
127559 +#endif
127560 +};
127561 +
127562 +struct bm_mc {
127563 + struct bm_mc_command *cr;
127564 + struct bm_mc_result *rr;
127565 + u8 rridx, vbit;
127566 +#ifdef CONFIG_FSL_DPA_CHECKING
127567 + enum {
127568 + /* Can only be _mc_start()ed */
127569 + mc_idle,
127570 + /* Can only be _mc_commit()ed or _mc_abort()ed */
127571 + mc_user,
127572 + /* Can only be _mc_retry()ed */
127573 + mc_hw
127574 + } state;
127575 +#endif
127576 +};
127577 +
127578 +struct bm_addr {
127579 + void __iomem *addr_ce; /* cache-enabled */
127580 + void __iomem *addr_ci; /* cache-inhibited */
127581 +};
127582 +
127583 +struct bm_portal {
127584 + struct bm_addr addr;
127585 + struct bm_rcr rcr;
127586 + struct bm_mc mc;
127587 + struct bm_portal_config config;
127588 +} ____cacheline_aligned;
127589 +
127590 +
127591 +/* --------------- */
127592 +/* --- RCR API --- */
127593 +
127594 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
127595 +#define RCR_CARRYCLEAR(p) \
127596 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
127597 +
127598 +/* Bit-wise logic to convert a ring pointer to a ring index */
127599 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
127600 +{
127601 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
127602 +}
127603 +
127604 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
127605 +static inline void RCR_INC(struct bm_rcr *rcr)
127606 +{
127607 + /* NB: this is odd-looking, but experiments show that it generates
127608 + * fast code with essentially no branching overheads. We increment to
127609 + * the next RCR pointer and handle overflow and 'vbit'. */
127610 + struct bm_rcr_entry *partial = rcr->cursor + 1;
127611 + rcr->cursor = RCR_CARRYCLEAR(partial);
127612 + if (partial != rcr->cursor)
127613 + rcr->vbit ^= BM_RCR_VERB_VBIT;
127614 +}
127615 +
127616 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
127617 + __maybe_unused enum bm_rcr_cmode cmode)
127618 +{
127619 + /* This use of 'register', as well as all other occurrences, is because
127620 + * it has been observed to generate much faster code with gcc than is
127621 + * otherwise the case. */
127622 + register struct bm_rcr *rcr = &portal->rcr;
127623 + u32 cfg;
127624 + u8 pi;
127625 +
127626 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
127627 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127628 +
127629 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127630 + rcr->cursor = rcr->ring + pi;
127631 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
127632 + rcr->available = BM_RCR_SIZE - 1
127633 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
127634 + rcr->ithresh = bm_in(RCR_ITR);
127635 +#ifdef CONFIG_FSL_DPA_CHECKING
127636 + rcr->busy = 0;
127637 + rcr->pmode = pmode;
127638 + rcr->cmode = cmode;
127639 +#endif
127640 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
127641 + bm_out(CFG, cfg);
127642 + return 0;
127643 +}
127644 +
127645 +static inline void bm_rcr_finish(struct bm_portal *portal)
127646 +{
127647 + register struct bm_rcr *rcr = &portal->rcr;
127648 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127649 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127650 + DPA_ASSERT(!rcr->busy);
127651 + if (pi != RCR_PTR2IDX(rcr->cursor))
127652 + pr_crit("losing uncommited RCR entries\n");
127653 + if (ci != rcr->ci)
127654 + pr_crit("missing existing RCR completions\n");
127655 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
127656 + pr_crit("RCR destroyed unquiesced\n");
127657 +}
127658 +
127659 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127660 +{
127661 + register struct bm_rcr *rcr = &portal->rcr;
127662 + DPA_ASSERT(!rcr->busy);
127663 + if (!rcr->available)
127664 + return NULL;
127665 +#ifdef CONFIG_FSL_DPA_CHECKING
127666 + rcr->busy = 1;
127667 +#endif
127668 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127669 + dcbz_64(rcr->cursor);
127670 +#endif
127671 + return rcr->cursor;
127672 +}
127673 +
127674 +static inline void bm_rcr_abort(struct bm_portal *portal)
127675 +{
127676 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127677 + DPA_ASSERT(rcr->busy);
127678 +#ifdef CONFIG_FSL_DPA_CHECKING
127679 + rcr->busy = 0;
127680 +#endif
127681 +}
127682 +
127683 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127684 + struct bm_portal *portal, u8 myverb)
127685 +{
127686 + register struct bm_rcr *rcr = &portal->rcr;
127687 + DPA_ASSERT(rcr->busy);
127688 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127689 + if (rcr->available == 1)
127690 + return NULL;
127691 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127692 + dcbf_64(rcr->cursor);
127693 + RCR_INC(rcr);
127694 + rcr->available--;
127695 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127696 + dcbz_64(rcr->cursor);
127697 +#endif
127698 + return rcr->cursor;
127699 +}
127700 +
127701 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127702 +{
127703 + register struct bm_rcr *rcr = &portal->rcr;
127704 + DPA_ASSERT(rcr->busy);
127705 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127706 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127707 + RCR_INC(rcr);
127708 + rcr->available--;
127709 + hwsync();
127710 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127711 +#ifdef CONFIG_FSL_DPA_CHECKING
127712 + rcr->busy = 0;
127713 +#endif
127714 +}
127715 +
127716 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127717 +{
127718 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127719 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127720 + bm_cl_invalidate(RCR_PI);
127721 + bm_cl_touch_rw(RCR_PI);
127722 +}
127723 +
127724 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127725 +{
127726 + register struct bm_rcr *rcr = &portal->rcr;
127727 + DPA_ASSERT(rcr->busy);
127728 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127729 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127730 + RCR_INC(rcr);
127731 + rcr->available--;
127732 + lwsync();
127733 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127734 +#ifdef CONFIG_FSL_DPA_CHECKING
127735 + rcr->busy = 0;
127736 +#endif
127737 +}
127738 +
127739 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127740 +{
127741 + register struct bm_rcr *rcr = &portal->rcr;
127742 + struct bm_rcr_entry *rcursor;
127743 + DPA_ASSERT(rcr->busy);
127744 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127745 + lwsync();
127746 + rcursor = rcr->cursor;
127747 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127748 + dcbf_64(rcursor);
127749 + RCR_INC(rcr);
127750 + rcr->available--;
127751 +#ifdef CONFIG_FSL_DPA_CHECKING
127752 + rcr->busy = 0;
127753 +#endif
127754 +}
127755 +
127756 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127757 +{
127758 + register struct bm_rcr *rcr = &portal->rcr;
127759 + u8 diff, old_ci = rcr->ci;
127760 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127761 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127762 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127763 + rcr->available += diff;
127764 + return diff;
127765 +}
127766 +
127767 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127768 +{
127769 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127770 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127771 + bm_cl_touch_ro(RCR_CI);
127772 +}
127773 +
127774 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127775 +{
127776 + register struct bm_rcr *rcr = &portal->rcr;
127777 + u8 diff, old_ci = rcr->ci;
127778 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127779 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127780 + bm_cl_invalidate(RCR_CI);
127781 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127782 + rcr->available += diff;
127783 + return diff;
127784 +}
127785 +
127786 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127787 +{
127788 + register struct bm_rcr *rcr = &portal->rcr;
127789 + return rcr->ithresh;
127790 +}
127791 +
127792 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127793 +{
127794 + register struct bm_rcr *rcr = &portal->rcr;
127795 + rcr->ithresh = ithresh;
127796 + bm_out(RCR_ITR, ithresh);
127797 +}
127798 +
127799 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
127800 +{
127801 + register struct bm_rcr *rcr = &portal->rcr;
127802 + return rcr->available;
127803 +}
127804 +
127805 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
127806 +{
127807 + register struct bm_rcr *rcr = &portal->rcr;
127808 + return BM_RCR_SIZE - 1 - rcr->available;
127809 +}
127810 +
127811 +
127812 +/* ------------------------------ */
127813 +/* --- Management command API --- */
127814 +
127815 +static inline int bm_mc_init(struct bm_portal *portal)
127816 +{
127817 + register struct bm_mc *mc = &portal->mc;
127818 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
127819 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
127820 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
127821 + BM_MCC_VERB_VBIT) ? 0 : 1;
127822 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
127823 +#ifdef CONFIG_FSL_DPA_CHECKING
127824 + mc->state = mc_idle;
127825 +#endif
127826 + return 0;
127827 +}
127828 +
127829 +static inline void bm_mc_finish(struct bm_portal *portal)
127830 +{
127831 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127832 + DPA_ASSERT(mc->state == mc_idle);
127833 +#ifdef CONFIG_FSL_DPA_CHECKING
127834 + if (mc->state != mc_idle)
127835 + pr_crit("Losing incomplete MC command\n");
127836 +#endif
127837 +}
127838 +
127839 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
127840 +{
127841 + register struct bm_mc *mc = &portal->mc;
127842 + DPA_ASSERT(mc->state == mc_idle);
127843 +#ifdef CONFIG_FSL_DPA_CHECKING
127844 + mc->state = mc_user;
127845 +#endif
127846 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127847 + dcbz_64(mc->cr);
127848 +#endif
127849 + return mc->cr;
127850 +}
127851 +
127852 +static inline void bm_mc_abort(struct bm_portal *portal)
127853 +{
127854 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127855 + DPA_ASSERT(mc->state == mc_user);
127856 +#ifdef CONFIG_FSL_DPA_CHECKING
127857 + mc->state = mc_idle;
127858 +#endif
127859 +}
127860 +
127861 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
127862 +{
127863 + register struct bm_mc *mc = &portal->mc;
127864 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127865 + DPA_ASSERT(mc->state == mc_user);
127866 + lwsync();
127867 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
127868 + dcbf(mc->cr);
127869 + dcbit_ro(rr);
127870 +#ifdef CONFIG_FSL_DPA_CHECKING
127871 + mc->state = mc_hw;
127872 +#endif
127873 +}
127874 +
127875 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
127876 +{
127877 + register struct bm_mc *mc = &portal->mc;
127878 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127879 + DPA_ASSERT(mc->state == mc_hw);
127880 + /* The inactive response register's verb byte always returns zero until
127881 + * its command is submitted and completed. This includes the valid-bit,
127882 + * in case you were wondering... */
127883 + if (!__raw_readb(&rr->verb)) {
127884 + dcbit_ro(rr);
127885 + return NULL;
127886 + }
127887 + mc->rridx ^= 1;
127888 + mc->vbit ^= BM_MCC_VERB_VBIT;
127889 +#ifdef CONFIG_FSL_DPA_CHECKING
127890 + mc->state = mc_idle;
127891 +#endif
127892 + return rr;
127893 +}
127894 +
127895 +
127896 +/* ------------------------------------- */
127897 +/* --- Portal interrupt register API --- */
127898 +
127899 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
127900 +{
127901 + return 0;
127902 +}
127903 +
127904 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
127905 +{
127906 +}
127907 +
127908 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
127909 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
127910 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
127911 + int enable)
127912 +{
127913 + u32 val;
127914 + DPA_ASSERT(bpid < bman_pool_max);
127915 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
127916 + val = __bm_in(&portal->addr, SCN_REG(bpid));
127917 + if (enable)
127918 + val |= SCN_BIT(bpid);
127919 + else
127920 + val &= ~SCN_BIT(bpid);
127921 + __bm_out(&portal->addr, SCN_REG(bpid), val);
127922 +}
127923 +
127924 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
127925 +{
127926 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127927 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
127928 +#else
127929 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
127930 +#endif
127931 +}
127932 +
127933 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
127934 + u32 val)
127935 +{
127936 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127937 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
127938 +#else
127939 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
127940 +#endif
127941 +}
127942 +
127943 +/* Buffer Pool Cleanup */
127944 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
127945 +{
127946 + struct bm_mc_command *bm_cmd;
127947 + struct bm_mc_result *bm_res;
127948 +
127949 + int aq_count = 0;
127950 + bool stop = false;
127951 + while (!stop) {
127952 + /* Acquire buffers until empty */
127953 + bm_cmd = bm_mc_start(p);
127954 + bm_cmd->acquire.bpid = bpid;
127955 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
127956 + while (!(bm_res = bm_mc_result(p)))
127957 + cpu_relax();
127958 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
127959 + /* Pool is empty */
127960 + /* TBD : Should we do a few extra iterations in
127961 + case some other some blocks keep buffers 'on deck',
127962 + which may also be problematic */
127963 + stop = true;
127964 + } else
127965 + ++aq_count;
127966 + }
127967 + return 0;
127968 +}
127969 diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h
127970 new file mode 100644
127971 index 00000000..64eefe7d
127972 --- /dev/null
127973 +++ b/drivers/staging/fsl_qbman/bman_private.h
127974 @@ -0,0 +1,166 @@
127975 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127976 + *
127977 + * Redistribution and use in source and binary forms, with or without
127978 + * modification, are permitted provided that the following conditions are met:
127979 + * * Redistributions of source code must retain the above copyright
127980 + * notice, this list of conditions and the following disclaimer.
127981 + * * Redistributions in binary form must reproduce the above copyright
127982 + * notice, this list of conditions and the following disclaimer in the
127983 + * documentation and/or other materials provided with the distribution.
127984 + * * Neither the name of Freescale Semiconductor nor the
127985 + * names of its contributors may be used to endorse or promote products
127986 + * derived from this software without specific prior written permission.
127987 + *
127988 + *
127989 + * ALTERNATIVELY, this software may be distributed under the terms of the
127990 + * GNU General Public License ("GPL") as published by the Free Software
127991 + * Foundation, either version 2 of that License or (at your option) any
127992 + * later version.
127993 + *
127994 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127995 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127996 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127997 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127998 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127999 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128000 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128001 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128002 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128003 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128004 + */
128005 +
128006 +#include "dpa_sys.h"
128007 +#include <linux/fsl_bman.h>
128008 +
128009 +/* Revision info (for errata and feature handling) */
128010 +#define BMAN_REV10 0x0100
128011 +#define BMAN_REV20 0x0200
128012 +#define BMAN_REV21 0x0201
128013 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
128014 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
128015 +
128016 +/*
128017 + * Global variables of the max portal/pool number this bman version supported
128018 + */
128019 +extern u16 bman_pool_max;
128020 +
128021 +/* used by CCSR and portal interrupt code */
128022 +enum bm_isr_reg {
128023 + bm_isr_status = 0,
128024 + bm_isr_enable = 1,
128025 + bm_isr_disable = 2,
128026 + bm_isr_inhibit = 3
128027 +};
128028 +
128029 +struct bm_portal_config {
128030 + /* Corenet portal addresses;
128031 + * [0]==cache-enabled, [1]==cache-inhibited. */
128032 + __iomem void *addr_virt[2];
128033 + struct resource addr_phys[2];
128034 + /* Allow these to be joined in lists */
128035 + struct list_head list;
128036 + /* User-visible portal configuration settings */
128037 + struct bman_portal_config public_cfg;
128038 + /* power management saved data */
128039 + u32 saved_isdr;
128040 +};
128041 +
128042 +#ifdef CONFIG_FSL_BMAN_CONFIG
128043 +/* Hooks from bman_driver.c to bman_config.c */
128044 +int bman_init_ccsr(struct device_node *node);
128045 +#endif
128046 +
128047 +/* Hooks from bman_driver.c in to bman_high.c */
128048 +struct bman_portal *bman_create_portal(
128049 + struct bman_portal *portal,
128050 + const struct bm_portal_config *config);
128051 +struct bman_portal *bman_create_affine_portal(
128052 + const struct bm_portal_config *config);
128053 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
128054 + int cpu);
128055 +void bman_destroy_portal(struct bman_portal *bm);
128056 +
128057 +const struct bm_portal_config *bman_destroy_affine_portal(void);
128058 +
128059 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
128060 +struct bm_portal_config *bm_get_unused_portal(void);
128061 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
128062 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
128063 +void bm_set_liodns(struct bm_portal_config *pcfg);
128064 +
128065 +/* Pool logic in the portal driver, during initialisation, needs to know if
128066 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
128067 +#ifdef CONFIG_FSL_BMAN_CONFIG
128068 +int bman_have_ccsr(void);
128069 +#else
128070 +#define bman_have_ccsr() 0
128071 +#endif
128072 +
128073 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
128074 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
128075 + * might fail (if the buffer pool is depleted). So this value provides some
128076 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
128077 + * are requested at once or if h/w has been tested a couple of times without
128078 + * luck. The _HIGH value: when bman_release() is called and the stockpile
128079 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
128080 + * the release ring is full). So this value provides some "stagger" so that
128081 + * ring-access is retried a couple of times prior to the API returning a
128082 + * failure. The following *must* be true;
128083 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
128084 + * (to avoid thrashing)
128085 + * BMAN_STOCKPILE_SZ >= 16
128086 + * (as the release logic expects to either send 8 buffers to hw prior to
128087 + * adding the given buffers to the stockpile or add the buffers to the
128088 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
128089 + * success/fail.)
128090 + */
128091 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
128092 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
128093 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
128094 +
128095 +/*************************************************/
128096 +/* BMan s/w corenet portal, low-level i/face */
128097 +/*************************************************/
128098 +
128099 +/* Used by all portal interrupt registers except 'inhibit'
128100 + * This mask contains all the "irqsource" bits visible to API users
128101 + */
128102 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
128103 +
128104 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
128105 + * the disable register" rather than "disable the ability to write". */
128106 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
128107 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
128108 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
128109 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
128110 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
128111 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
128112 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
128113 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
128114 +
128115 +#ifdef CONFIG_FSL_BMAN_CONFIG
128116 +/* Set depletion thresholds associated with a buffer pool. Requires that the
128117 + * operating system have access to Bman CCSR (ie. compiled in support and
128118 + * run-time access courtesy of the device-tree). */
128119 +int bm_pool_set(u32 bpid, const u32 *thresholds);
128120 +#define BM_POOL_THRESH_SW_ENTER 0
128121 +#define BM_POOL_THRESH_SW_EXIT 1
128122 +#define BM_POOL_THRESH_HW_ENTER 2
128123 +#define BM_POOL_THRESH_HW_EXIT 3
128124 +
128125 +/* Read the free buffer count for a given buffer */
128126 +u32 bm_pool_free_buffers(u32 bpid);
128127 +
128128 +__init int bman_init(void);
128129 +__init int bman_resource_init(void);
128130 +
128131 +const struct bm_portal_config *bman_get_bm_portal_config(
128132 + struct bman_portal *portal);
128133 +
128134 +/* power management */
128135 +#ifdef CONFIG_SUSPEND
128136 +void suspend_unused_bportal(void);
128137 +void resume_unused_bportal(void);
128138 +#endif
128139 +
128140 +#endif /* CONFIG_FSL_BMAN_CONFIG */
128141 diff --git a/drivers/staging/fsl_qbman/bman_test.c b/drivers/staging/fsl_qbman/bman_test.c
128142 new file mode 100644
128143 index 00000000..db5b7fd3
128144 --- /dev/null
128145 +++ b/drivers/staging/fsl_qbman/bman_test.c
128146 @@ -0,0 +1,56 @@
128147 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128148 + *
128149 + * Redistribution and use in source and binary forms, with or without
128150 + * modification, are permitted provided that the following conditions are met:
128151 + * * Redistributions of source code must retain the above copyright
128152 + * notice, this list of conditions and the following disclaimer.
128153 + * * Redistributions in binary form must reproduce the above copyright
128154 + * notice, this list of conditions and the following disclaimer in the
128155 + * documentation and/or other materials provided with the distribution.
128156 + * * Neither the name of Freescale Semiconductor nor the
128157 + * names of its contributors may be used to endorse or promote products
128158 + * derived from this software without specific prior written permission.
128159 + *
128160 + *
128161 + * ALTERNATIVELY, this software may be distributed under the terms of the
128162 + * GNU General Public License ("GPL") as published by the Free Software
128163 + * Foundation, either version 2 of that License or (at your option) any
128164 + * later version.
128165 + *
128166 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128167 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128168 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128169 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128170 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128171 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128172 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128173 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128174 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128175 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128176 + */
128177 +
128178 +#include "bman_test.h"
128179 +
128180 +MODULE_AUTHOR("Geoff Thorpe");
128181 +MODULE_LICENSE("Dual BSD/GPL");
128182 +MODULE_DESCRIPTION("Bman testing");
128183 +
128184 +static int test_init(void)
128185 +{
128186 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
128187 + int loop = 1;
128188 + while (loop--)
128189 + bman_test_high();
128190 +#endif
128191 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
128192 + bman_test_thresh();
128193 +#endif
128194 + return 0;
128195 +}
128196 +
128197 +static void test_exit(void)
128198 +{
128199 +}
128200 +
128201 +module_init(test_init);
128202 +module_exit(test_exit);
128203 diff --git a/drivers/staging/fsl_qbman/bman_test.h b/drivers/staging/fsl_qbman/bman_test.h
128204 new file mode 100644
128205 index 00000000..fcd65056
128206 --- /dev/null
128207 +++ b/drivers/staging/fsl_qbman/bman_test.h
128208 @@ -0,0 +1,44 @@
128209 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128210 + *
128211 + * Redistribution and use in source and binary forms, with or without
128212 + * modification, are permitted provided that the following conditions are met:
128213 + * * Redistributions of source code must retain the above copyright
128214 + * notice, this list of conditions and the following disclaimer.
128215 + * * Redistributions in binary form must reproduce the above copyright
128216 + * notice, this list of conditions and the following disclaimer in the
128217 + * documentation and/or other materials provided with the distribution.
128218 + * * Neither the name of Freescale Semiconductor nor the
128219 + * names of its contributors may be used to endorse or promote products
128220 + * derived from this software without specific prior written permission.
128221 + *
128222 + *
128223 + * ALTERNATIVELY, this software may be distributed under the terms of the
128224 + * GNU General Public License ("GPL") as published by the Free Software
128225 + * Foundation, either version 2 of that License or (at your option) any
128226 + * later version.
128227 + *
128228 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128229 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128230 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128231 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128232 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128233 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128234 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128235 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128236 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128237 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128238 + */
128239 +
128240 +#include <linux/kernel.h>
128241 +#include <linux/errno.h>
128242 +#include <linux/io.h>
128243 +#include <linux/slab.h>
128244 +#include <linux/module.h>
128245 +#include <linux/interrupt.h>
128246 +#include <linux/delay.h>
128247 +#include <linux/kthread.h>
128248 +
128249 +#include <linux/fsl_bman.h>
128250 +
128251 +void bman_test_high(void);
128252 +void bman_test_thresh(void);
128253 diff --git a/drivers/staging/fsl_qbman/bman_test_high.c b/drivers/staging/fsl_qbman/bman_test_high.c
128254 new file mode 100644
128255 index 00000000..1617a531
128256 --- /dev/null
128257 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
128258 @@ -0,0 +1,183 @@
128259 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128260 + *
128261 + * Redistribution and use in source and binary forms, with or without
128262 + * modification, are permitted provided that the following conditions are met:
128263 + * * Redistributions of source code must retain the above copyright
128264 + * notice, this list of conditions and the following disclaimer.
128265 + * * Redistributions in binary form must reproduce the above copyright
128266 + * notice, this list of conditions and the following disclaimer in the
128267 + * documentation and/or other materials provided with the distribution.
128268 + * * Neither the name of Freescale Semiconductor nor the
128269 + * names of its contributors may be used to endorse or promote products
128270 + * derived from this software without specific prior written permission.
128271 + *
128272 + *
128273 + * ALTERNATIVELY, this software may be distributed under the terms of the
128274 + * GNU General Public License ("GPL") as published by the Free Software
128275 + * Foundation, either version 2 of that License or (at your option) any
128276 + * later version.
128277 + *
128278 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128279 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128280 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128281 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128282 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128283 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128284 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128285 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128286 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128287 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128288 + */
128289 +
128290 +#include "bman_test.h"
128291 +#include "bman_private.h"
128292 +
128293 +/*************/
128294 +/* constants */
128295 +/*************/
128296 +
128297 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
128298 +#define POOL_OPAQUE ((void *)0xdeadabba)
128299 +#define NUM_BUFS 93
128300 +#define LOOPS 3
128301 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
128302 +
128303 +/***************/
128304 +/* global vars */
128305 +/***************/
128306 +
128307 +static struct bman_pool *pool;
128308 +static int depleted;
128309 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
128310 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
128311 +static int bufs_received;
128312 +
128313 +/* Predeclare the callback so we can instantiate pool parameters */
128314 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
128315 +
128316 +/**********************/
128317 +/* internal functions */
128318 +/**********************/
128319 +
128320 +static void bufs_init(void)
128321 +{
128322 + int i;
128323 + for (i = 0; i < NUM_BUFS; i++)
128324 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
128325 + bufs_received = 0;
128326 +}
128327 +
128328 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
128329 +{
128330 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
128331 +
128332 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
128333 + * LS-bits of buffer addresses, masking off the upper 8-bits on
128334 + * release commands. The API provides for 48-bit addresses
128335 + * because some SoCs support all 48-bits. When generating
128336 + * garbage addresses for testing, we either need to zero the
128337 + * upper 8-bits when releasing to Bman (otherwise we'll be
128338 + * disappointed when the buffers we acquire back from Bman
128339 + * don't match), or we need to mask the upper 8-bits off when
128340 + * comparing. We do the latter.
128341 + */
128342 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128343 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128344 + return -1;
128345 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128346 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128347 + return 1;
128348 + } else {
128349 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
128350 + return -1;
128351 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
128352 + return 1;
128353 + }
128354 +
128355 + return 0;
128356 +}
128357 +
128358 +static void bufs_confirm(void)
128359 +{
128360 + int i, j;
128361 + for (i = 0; i < NUM_BUFS; i++) {
128362 + int matches = 0;
128363 + for (j = 0; j < NUM_BUFS; j++)
128364 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
128365 + matches++;
128366 + BUG_ON(matches != 1);
128367 + }
128368 +}
128369 +
128370 +/********/
128371 +/* test */
128372 +/********/
128373 +
128374 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
128375 + void *pool_ctx, int __depleted)
128376 +{
128377 + BUG_ON(__pool != pool);
128378 + BUG_ON(pool_ctx != POOL_OPAQUE);
128379 + depleted = __depleted;
128380 +}
128381 +
128382 +void bman_test_high(void)
128383 +{
128384 + struct bman_pool_params pparams = {
128385 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
128386 + .cb = depletion_cb,
128387 + .cb_ctx = POOL_OPAQUE,
128388 + };
128389 + int i, loops = LOOPS;
128390 + struct bm_buffer tmp_buf;
128391 +
128392 + bufs_init();
128393 +
128394 + pr_info("BMAN: --- starting high-level test ---\n");
128395 +
128396 + pool = bman_new_pool(&pparams);
128397 + BUG_ON(!pool);
128398 +
128399 + /*******************/
128400 + /* Release buffers */
128401 + /*******************/
128402 +do_loop:
128403 + i = 0;
128404 + while (i < NUM_BUFS) {
128405 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
128406 + int num = 8;
128407 + if ((i + num) > NUM_BUFS)
128408 + num = NUM_BUFS - i;
128409 + if ((i + num) == NUM_BUFS)
128410 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
128411 + if (bman_release(pool, bufs_in + i, num, flags))
128412 + panic("bman_release() failed\n");
128413 + i += num;
128414 + }
128415 +
128416 + /*******************/
128417 + /* Acquire buffers */
128418 + /*******************/
128419 + while (i > 0) {
128420 + int tmp, num = 8;
128421 + if (num > i)
128422 + num = i;
128423 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
128424 + BUG_ON(tmp != num);
128425 + i -= num;
128426 + }
128427 +
128428 + i = bman_acquire(pool, &tmp_buf, 1, 0);
128429 + BUG_ON(i > 0);
128430 +
128431 + bufs_confirm();
128432 +
128433 + if (--loops)
128434 + goto do_loop;
128435 +
128436 + /************/
128437 + /* Clean up */
128438 + /************/
128439 + bman_free_pool(pool);
128440 + pr_info("BMAN: --- finished high-level test ---\n");
128441 +}
128442 diff --git a/drivers/staging/fsl_qbman/bman_test_thresh.c b/drivers/staging/fsl_qbman/bman_test_thresh.c
128443 new file mode 100644
128444 index 00000000..67093693
128445 --- /dev/null
128446 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
128447 @@ -0,0 +1,196 @@
128448 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
128449 + *
128450 + * Redistribution and use in source and binary forms, with or without
128451 + * modification, are permitted provided that the following conditions are met:
128452 + * * Redistributions of source code must retain the above copyright
128453 + * notice, this list of conditions and the following disclaimer.
128454 + * * Redistributions in binary form must reproduce the above copyright
128455 + * notice, this list of conditions and the following disclaimer in the
128456 + * documentation and/or other materials provided with the distribution.
128457 + * * Neither the name of Freescale Semiconductor nor the
128458 + * names of its contributors may be used to endorse or promote products
128459 + * derived from this software without specific prior written permission.
128460 + *
128461 + *
128462 + * ALTERNATIVELY, this software may be distributed under the terms of the
128463 + * GNU General Public License ("GPL") as published by the Free Software
128464 + * Foundation, either version 2 of that License or (at your option) any
128465 + * later version.
128466 + *
128467 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128468 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128469 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128470 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128471 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128472 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128473 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128474 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128475 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128476 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128477 + */
128478 +
128479 +#include "bman_test.h"
128480 +
128481 +/* Test constants */
128482 +#define TEST_NUMBUFS 129728
128483 +#define TEST_EXIT 129536
128484 +#define TEST_ENTRY 129024
128485 +
128486 +struct affine_test_data {
128487 + struct task_struct *t;
128488 + int cpu;
128489 + int expect_affinity;
128490 + int drain;
128491 + int num_enter;
128492 + int num_exit;
128493 + struct list_head node;
128494 + struct completion wakethread;
128495 + struct completion wakeparent;
128496 +};
128497 +
128498 +static void cb_depletion(struct bman_portal *portal,
128499 + struct bman_pool *pool,
128500 + void *opaque,
128501 + int depleted)
128502 +{
128503 + struct affine_test_data *data = opaque;
128504 + int c = smp_processor_id();
128505 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
128506 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
128507 + /* We should be executing on the CPU of the thread that owns the pool if
128508 + * and that CPU has an affine portal (ie. it isn't slaved). */
128509 + BUG_ON((c != data->cpu) && data->expect_affinity);
128510 + BUG_ON((c == data->cpu) && !data->expect_affinity);
128511 + if (depleted)
128512 + data->num_enter++;
128513 + else
128514 + data->num_exit++;
128515 +}
128516 +
128517 +/* Params used to set up a pool, this also dynamically allocates a BPID */
128518 +static const struct bman_pool_params params_nocb = {
128519 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
128520 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
128521 +};
128522 +
128523 +/* Params used to set up each cpu's pool with callbacks enabled */
128524 +static struct bman_pool_params params_cb = {
128525 + .bpid = 0, /* will be replaced to match pool_nocb */
128526 + .flags = BMAN_POOL_FLAG_DEPLETION,
128527 + .cb = cb_depletion
128528 +};
128529 +
128530 +static struct bman_pool *pool_nocb;
128531 +static LIST_HEAD(threads);
128532 +
128533 +static int affine_test(void *__data)
128534 +{
128535 + struct bman_pool *pool;
128536 + struct affine_test_data *data = __data;
128537 + struct bman_pool_params my_params = params_cb;
128538 +
128539 + pr_info("thread %d: starting\n", data->cpu);
128540 + /* create the pool */
128541 + my_params.cb_ctx = data;
128542 + pool = bman_new_pool(&my_params);
128543 + BUG_ON(!pool);
128544 + complete(&data->wakeparent);
128545 + wait_for_completion(&data->wakethread);
128546 + init_completion(&data->wakethread);
128547 +
128548 + /* if we're the drainer, we get signalled for that */
128549 + if (data->drain) {
128550 + struct bm_buffer buf;
128551 + int ret;
128552 + pr_info("thread %d: draining...\n", data->cpu);
128553 + do {
128554 + ret = bman_acquire(pool, &buf, 1, 0);
128555 + } while (ret > 0);
128556 + pr_info("thread %d: draining done.\n", data->cpu);
128557 + complete(&data->wakeparent);
128558 + wait_for_completion(&data->wakethread);
128559 + init_completion(&data->wakethread);
128560 + }
128561 +
128562 + /* cleanup */
128563 + bman_free_pool(pool);
128564 + while (!kthread_should_stop())
128565 + cpu_relax();
128566 + pr_info("thread %d: exiting\n", data->cpu);
128567 + return 0;
128568 +}
128569 +
128570 +static struct affine_test_data *start_affine_test(int cpu, int drain)
128571 +{
128572 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
128573 +
128574 + if (!data)
128575 + return NULL;
128576 + data->cpu = cpu;
128577 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
128578 + data->drain = drain;
128579 + data->num_enter = 0;
128580 + data->num_exit = 0;
128581 + init_completion(&data->wakethread);
128582 + init_completion(&data->wakeparent);
128583 + list_add_tail(&data->node, &threads);
128584 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
128585 + BUG_ON(IS_ERR(data->t));
128586 + kthread_bind(data->t, cpu);
128587 + wake_up_process(data->t);
128588 + return data;
128589 +}
128590 +
128591 +void bman_test_thresh(void)
128592 +{
128593 + int loop = TEST_NUMBUFS;
128594 + int ret, num_cpus = 0;
128595 + struct affine_test_data *data, *drainer = NULL;
128596 +
128597 + pr_info("bman_test_thresh: start\n");
128598 +
128599 + /* allocate a BPID and seed it */
128600 + pool_nocb = bman_new_pool(&params_nocb);
128601 + BUG_ON(!pool_nocb);
128602 + while (loop--) {
128603 + struct bm_buffer buf;
128604 + bm_buffer_set64(&buf, 0x0badbeef + loop);
128605 + ret = bman_release(pool_nocb, &buf, 1,
128606 + BMAN_RELEASE_FLAG_WAIT);
128607 + BUG_ON(ret);
128608 + }
128609 + while (!bman_rcr_is_empty())
128610 + cpu_relax();
128611 + pr_info("bman_test_thresh: buffers are in\n");
128612 +
128613 + /* create threads and wait for them to create pools */
128614 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
128615 + for_each_cpu(loop, cpu_online_mask) {
128616 + data = start_affine_test(loop, drainer ? 0 : 1);
128617 + BUG_ON(!data);
128618 + if (!drainer)
128619 + drainer = data;
128620 + num_cpus++;
128621 + wait_for_completion(&data->wakeparent);
128622 + }
128623 +
128624 + /* signal the drainer to start draining */
128625 + complete(&drainer->wakethread);
128626 + wait_for_completion(&drainer->wakeparent);
128627 + init_completion(&drainer->wakeparent);
128628 +
128629 + /* tear down */
128630 + list_for_each_entry_safe(data, drainer, &threads, node) {
128631 + complete(&data->wakethread);
128632 + ret = kthread_stop(data->t);
128633 + BUG_ON(ret);
128634 + list_del(&data->node);
128635 + /* check that we get the expected callbacks (and no others) */
128636 + BUG_ON(data->num_enter != 1);
128637 + BUG_ON(data->num_exit != 0);
128638 + kfree(data);
128639 + }
128640 + bman_free_pool(pool_nocb);
128641 +
128642 + pr_info("bman_test_thresh: done\n");
128643 +}
128644 diff --git a/drivers/staging/fsl_qbman/dpa_alloc.c b/drivers/staging/fsl_qbman/dpa_alloc.c
128645 new file mode 100644
128646 index 00000000..44db3e1e
128647 --- /dev/null
128648 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
128649 @@ -0,0 +1,706 @@
128650 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
128651 + *
128652 + * Redistribution and use in source and binary forms, with or without
128653 + * modification, are permitted provided that the following conditions are met:
128654 + * * Redistributions of source code must retain the above copyright
128655 + * notice, this list of conditions and the following disclaimer.
128656 + * * Redistributions in binary form must reproduce the above copyright
128657 + * notice, this list of conditions and the following disclaimer in the
128658 + * documentation and/or other materials provided with the distribution.
128659 + * * Neither the name of Freescale Semiconductor nor the
128660 + * names of its contributors may be used to endorse or promote products
128661 + * derived from this software without specific prior written permission.
128662 + *
128663 + *
128664 + * ALTERNATIVELY, this software may be distributed under the terms of the
128665 + * GNU General Public License ("GPL") as published by the Free Software
128666 + * Foundation, either version 2 of that License or (at your option) any
128667 + * later version.
128668 + *
128669 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128670 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128671 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128672 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128673 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128674 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128675 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128676 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128677 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128678 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128679 + */
128680 +
128681 +#include "dpa_sys.h"
128682 +#include <linux/fsl_qman.h>
128683 +#include <linux/fsl_bman.h>
128684 +
128685 +/* Qman and Bman APIs are front-ends to the common code; */
128686 +
128687 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128688 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128689 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128690 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128691 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128692 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128693 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128694 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128695 +
128696 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128697 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128698 + * OOS state (better to leak a h/w resource than to crash). This function
128699 + * returns the number of invalid IDs that were not released. */
128700 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128701 + int (*is_valid)(u32 id))
128702 +{
128703 + int valid_mode = 0;
128704 + u32 loop = id, total_invalid = 0;
128705 + while (loop < (id + count)) {
128706 + int isvalid = is_valid ? is_valid(loop) : 1;
128707 + if (!valid_mode) {
128708 + /* We're looking for a valid ID to terminate an invalid
128709 + * range */
128710 + if (isvalid) {
128711 + /* We finished a range of invalid IDs, a valid
128712 + * range is now underway */
128713 + valid_mode = 1;
128714 + count -= (loop - id);
128715 + id = loop;
128716 + } else
128717 + total_invalid++;
128718 + } else {
128719 + /* We're looking for an invalid ID to terminate a
128720 + * valid range */
128721 + if (!isvalid) {
128722 + /* Release the range of valid IDs, an unvalid
128723 + * range is now underway */
128724 + if (loop > id)
128725 + dpa_alloc_free(alloc, id, loop - id);
128726 + valid_mode = 0;
128727 + }
128728 + }
128729 + loop++;
128730 + }
128731 + /* Release any unterminated range of valid IDs */
128732 + if (valid_mode && count)
128733 + dpa_alloc_free(alloc, id, count);
128734 + return total_invalid;
128735 +}
128736 +
128737 +/* BPID allocator front-end */
128738 +
128739 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128740 +{
128741 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128742 +}
128743 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128744 +
128745 +static int bp_cleanup(u32 bpid)
128746 +{
128747 + return bman_shutdown_pool(bpid) == 0;
128748 +}
128749 +void bman_release_bpid_range(u32 bpid, u32 count)
128750 +{
128751 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128752 + if (total_invalid)
128753 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128754 + bpid, bpid + count - 1, count, total_invalid);
128755 +}
128756 +EXPORT_SYMBOL(bman_release_bpid_range);
128757 +
128758 +void bman_seed_bpid_range(u32 bpid, u32 count)
128759 +{
128760 + dpa_alloc_seed(&bpalloc, bpid, count);
128761 +}
128762 +EXPORT_SYMBOL(bman_seed_bpid_range);
128763 +
128764 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128765 +{
128766 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128767 +}
128768 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128769 +
128770 +
128771 +/* FQID allocator front-end */
128772 +
128773 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128774 +{
128775 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128776 +}
128777 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128778 +
128779 +static int fq_cleanup(u32 fqid)
128780 +{
128781 + return qman_shutdown_fq(fqid) == 0;
128782 +}
128783 +void qman_release_fqid_range(u32 fqid, u32 count)
128784 +{
128785 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128786 + if (total_invalid)
128787 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128788 + fqid, fqid + count - 1, count, total_invalid);
128789 +}
128790 +EXPORT_SYMBOL(qman_release_fqid_range);
128791 +
128792 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128793 +{
128794 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128795 +}
128796 +EXPORT_SYMBOL(qman_reserve_fqid_range);
128797 +
128798 +void qman_seed_fqid_range(u32 fqid, u32 count)
128799 +{
128800 + dpa_alloc_seed(&fqalloc, fqid, count);
128801 +}
128802 +EXPORT_SYMBOL(qman_seed_fqid_range);
128803 +
128804 +/* Pool-channel allocator front-end */
128805 +
128806 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
128807 +{
128808 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
128809 +}
128810 +EXPORT_SYMBOL(qman_alloc_pool_range);
128811 +
128812 +static int qpool_cleanup(u32 qp)
128813 +{
128814 + /* We query all FQDs starting from
128815 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128816 + * whose destination channel is the pool-channel being released.
128817 + * When a non-OOS FQD is found we attempt to clean it up */
128818 + struct qman_fq fq = {
128819 + .fqid = 1
128820 + };
128821 + int err;
128822 + do {
128823 + struct qm_mcr_queryfq_np np;
128824 + err = qman_query_fq_np(&fq, &np);
128825 + if (err)
128826 + /* FQID range exceeded, found no problems */
128827 + return 1;
128828 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128829 + struct qm_fqd fqd;
128830 + err = qman_query_fq(&fq, &fqd);
128831 + BUG_ON(err);
128832 + if (fqd.dest.channel == qp) {
128833 + /* The channel is the FQ's target, clean it */
128834 + if (qman_shutdown_fq(fq.fqid) != 0)
128835 + /* Couldn't shut down the FQ
128836 + so the pool must be leaked */
128837 + return 0;
128838 + }
128839 + }
128840 + /* Move to the next FQID */
128841 + fq.fqid++;
128842 + } while (1);
128843 +}
128844 +void qman_release_pool_range(u32 qp, u32 count)
128845 +{
128846 + u32 total_invalid = release_id_range(&qpalloc, qp,
128847 + count, qpool_cleanup);
128848 + if (total_invalid) {
128849 + /* Pool channels are almost always used individually */
128850 + if (count == 1)
128851 + pr_err("Pool channel 0x%x had %d leaks\n",
128852 + qp, total_invalid);
128853 + else
128854 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
128855 + qp, qp + count - 1, count, total_invalid);
128856 + }
128857 +}
128858 +EXPORT_SYMBOL(qman_release_pool_range);
128859 +
128860 +
128861 +void qman_seed_pool_range(u32 poolid, u32 count)
128862 +{
128863 + dpa_alloc_seed(&qpalloc, poolid, count);
128864 +
128865 +}
128866 +EXPORT_SYMBOL(qman_seed_pool_range);
128867 +
128868 +int qman_reserve_pool_range(u32 poolid, u32 count)
128869 +{
128870 + return dpa_alloc_reserve(&qpalloc, poolid, count);
128871 +}
128872 +EXPORT_SYMBOL(qman_reserve_pool_range);
128873 +
128874 +
128875 +/* CGR ID allocator front-end */
128876 +
128877 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
128878 +{
128879 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
128880 +}
128881 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
128882 +
128883 +static int cqr_cleanup(u32 cgrid)
128884 +{
128885 + /* We query all FQDs starting from
128886 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128887 + * whose CGR is the CGR being released.
128888 + */
128889 + struct qman_fq fq = {
128890 + .fqid = 1
128891 + };
128892 + int err;
128893 + do {
128894 + struct qm_mcr_queryfq_np np;
128895 + err = qman_query_fq_np(&fq, &np);
128896 + if (err)
128897 + /* FQID range exceeded, found no problems */
128898 + return 1;
128899 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128900 + struct qm_fqd fqd;
128901 + err = qman_query_fq(&fq, &fqd);
128902 + BUG_ON(err);
128903 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
128904 + (fqd.cgid == cgrid)) {
128905 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
128906 + " CGR will be leaked\n",
128907 + cgrid, fq.fqid);
128908 + return 1;
128909 + }
128910 + }
128911 + /* Move to the next FQID */
128912 + fq.fqid++;
128913 + } while (1);
128914 +}
128915 +
128916 +void qman_release_cgrid_range(u32 cgrid, u32 count)
128917 +{
128918 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
128919 + count, cqr_cleanup);
128920 + if (total_invalid)
128921 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
128922 + cgrid, cgrid + count - 1, count, total_invalid);
128923 +}
128924 +EXPORT_SYMBOL(qman_release_cgrid_range);
128925 +
128926 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
128927 +{
128928 + dpa_alloc_seed(&cgralloc, cgrid, count);
128929 +
128930 +}
128931 +EXPORT_SYMBOL(qman_seed_cgrid_range);
128932 +
128933 +/* CEETM CHANNEL ID allocator front-end */
128934 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
128935 + int partial)
128936 +{
128937 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
128938 +}
128939 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
128940 +
128941 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
128942 + int partial)
128943 +{
128944 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
128945 +}
128946 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
128947 +
128948 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
128949 +{
128950 + u32 total_invalid;
128951 +
128952 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
128953 + NULL);
128954 + if (total_invalid)
128955 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128956 + channelid, channelid + count - 1, count, total_invalid);
128957 +}
128958 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
128959 +
128960 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
128961 +{
128962 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
128963 +
128964 +}
128965 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
128966 +
128967 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
128968 +{
128969 + u32 total_invalid;
128970 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
128971 + NULL);
128972 + if (total_invalid)
128973 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128974 + channelid, channelid + count - 1, count, total_invalid);
128975 +}
128976 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
128977 +
128978 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
128979 +{
128980 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
128981 +
128982 +}
128983 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
128984 +
128985 +/* CEETM LFQID allocator front-end */
128986 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
128987 + int partial)
128988 +{
128989 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
128990 +}
128991 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
128992 +
128993 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
128994 + int partial)
128995 +{
128996 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
128997 +}
128998 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
128999 +
129000 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
129001 +{
129002 + u32 total_invalid;
129003 +
129004 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
129005 + NULL);
129006 + if (total_invalid)
129007 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
129008 + lfqid, lfqid + count - 1, count, total_invalid);
129009 +}
129010 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
129011 +
129012 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
129013 +{
129014 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
129015 +
129016 +}
129017 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
129018 +
129019 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
129020 +{
129021 + u32 total_invalid;
129022 +
129023 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
129024 + NULL);
129025 + if (total_invalid)
129026 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
129027 + lfqid, lfqid + count - 1, count, total_invalid);
129028 +}
129029 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
129030 +
129031 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
129032 +{
129033 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
129034 +
129035 +}
129036 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
129037 +
129038 +
129039 +/* Everything else is the common backend to all the allocators */
129040 +
129041 +/* The allocator is a (possibly-empty) list of these; */
129042 +struct alloc_node {
129043 + struct list_head list;
129044 + u32 base;
129045 + u32 num;
129046 + /* refcount and is_alloced are only set
129047 + when the node is in the used list */
129048 + unsigned int refcount;
129049 + int is_alloced;
129050 +};
129051 +
129052 +/* #define DPA_ALLOC_DEBUG */
129053 +
129054 +#ifdef DPA_ALLOC_DEBUG
129055 +#define DPRINT pr_info
129056 +static void DUMP(struct dpa_alloc *alloc)
129057 +{
129058 + int off = 0;
129059 + char buf[256];
129060 + struct alloc_node *p;
129061 + pr_info("Free Nodes\n");
129062 + list_for_each_entry(p, &alloc->free, list) {
129063 + if (off < 255)
129064 + off += snprintf(buf + off, 255-off, "{%d,%d}",
129065 + p->base, p->base + p->num - 1);
129066 + }
129067 + pr_info("%s\n", buf);
129068 +
129069 + off = 0;
129070 + pr_info("Used Nodes\n");
129071 + list_for_each_entry(p, &alloc->used, list) {
129072 + if (off < 255)
129073 + off += snprintf(buf + off, 255-off, "{%d,%d}",
129074 + p->base, p->base + p->num - 1);
129075 + }
129076 + pr_info("%s\n", buf);
129077 +
129078 +
129079 +
129080 +}
129081 +#else
129082 +#define DPRINT(x...)
129083 +#define DUMP(a)
129084 +#endif
129085 +
129086 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
129087 + int partial)
129088 +{
129089 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
129090 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
129091 + struct alloc_node *margin_left, *margin_right;
129092 +
129093 + *result = (u32)-1;
129094 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
129095 + DUMP(alloc);
129096 + /* If 'align' is 0, it should behave as though it was 1 */
129097 + if (!align)
129098 + align = 1;
129099 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
129100 + if (!margin_left)
129101 + goto err;
129102 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
129103 + if (!margin_right) {
129104 + kfree(margin_left);
129105 + goto err;
129106 + }
129107 + spin_lock_irq(&alloc->lock);
129108 + list_for_each_entry(i, &alloc->free, list) {
129109 + base = (i->base + align - 1) / align;
129110 + base *= align;
129111 + if ((base - i->base) >= i->num)
129112 + /* alignment is impossible, regardless of count */
129113 + continue;
129114 + num = i->num - (base - i->base);
129115 + if (num >= count) {
129116 + /* this one will do nicely */
129117 + num = count;
129118 + goto done;
129119 + }
129120 + if (num > next_best_num) {
129121 + next_best = i;
129122 + next_best_base = base;
129123 + next_best_num = num;
129124 + }
129125 + }
129126 + if (partial && next_best) {
129127 + i = next_best;
129128 + base = next_best_base;
129129 + num = next_best_num;
129130 + } else
129131 + i = NULL;
129132 +done:
129133 + if (i) {
129134 + if (base != i->base) {
129135 + margin_left->base = i->base;
129136 + margin_left->num = base - i->base;
129137 + list_add_tail(&margin_left->list, &i->list);
129138 + } else
129139 + kfree(margin_left);
129140 + if ((base + num) < (i->base + i->num)) {
129141 + margin_right->base = base + num;
129142 + margin_right->num = (i->base + i->num) -
129143 + (base + num);
129144 + list_add(&margin_right->list, &i->list);
129145 + } else
129146 + kfree(margin_right);
129147 + list_del(&i->list);
129148 + kfree(i);
129149 + *result = base;
129150 + } else {
129151 + spin_unlock_irq(&alloc->lock);
129152 + kfree(margin_left);
129153 + kfree(margin_right);
129154 + }
129155 +
129156 +err:
129157 + DPRINT("returning %d\n", i ? num : -ENOMEM);
129158 + DUMP(alloc);
129159 + if (!i)
129160 + return -ENOMEM;
129161 +
129162 + /* Add the allocation to the used list with a refcount of 1 */
129163 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
129164 + if (!used_node) {
129165 + spin_unlock_irq(&alloc->lock);
129166 + return -ENOMEM;
129167 + }
129168 + used_node->base = *result;
129169 + used_node->num = num;
129170 + used_node->refcount = 1;
129171 + used_node->is_alloced = 1;
129172 + list_add_tail(&used_node->list, &alloc->used);
129173 + spin_unlock_irq(&alloc->lock);
129174 + return (int)num;
129175 +}
129176 +
129177 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
129178 + * forcing error-handling on to users in the deallocation path. */
129179 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
129180 +{
129181 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
129182 + BUG_ON(!node);
129183 + DPRINT("release_range(%d,%d)\n", base_id, count);
129184 + DUMP(alloc);
129185 + BUG_ON(!count);
129186 + spin_lock_irq(&alloc->lock);
129187 +
129188 +
129189 + node->base = base_id;
129190 + node->num = count;
129191 + list_for_each_entry(i, &alloc->free, list) {
129192 + if (i->base >= node->base) {
129193 + /* BUG_ON(any overlapping) */
129194 + BUG_ON(i->base < (node->base + node->num));
129195 + list_add_tail(&node->list, &i->list);
129196 + goto done;
129197 + }
129198 + }
129199 + list_add_tail(&node->list, &alloc->free);
129200 +done:
129201 + /* Merge to the left */
129202 + i = list_entry(node->list.prev, struct alloc_node, list);
129203 + if (node->list.prev != &alloc->free) {
129204 + BUG_ON((i->base + i->num) > node->base);
129205 + if ((i->base + i->num) == node->base) {
129206 + node->base = i->base;
129207 + node->num += i->num;
129208 + list_del(&i->list);
129209 + kfree(i);
129210 + }
129211 + }
129212 + /* Merge to the right */
129213 + i = list_entry(node->list.next, struct alloc_node, list);
129214 + if (node->list.next != &alloc->free) {
129215 + BUG_ON((node->base + node->num) > i->base);
129216 + if ((node->base + node->num) == i->base) {
129217 + node->num += i->num;
129218 + list_del(&i->list);
129219 + kfree(i);
129220 + }
129221 + }
129222 + spin_unlock_irq(&alloc->lock);
129223 + DUMP(alloc);
129224 +}
129225 +
129226 +
129227 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
129228 +{
129229 + struct alloc_node *i = NULL;
129230 + spin_lock_irq(&alloc->lock);
129231 +
129232 + /* First find the node in the used list and decrement its ref count */
129233 + list_for_each_entry(i, &alloc->used, list) {
129234 + if (i->base == base_id && i->num == count) {
129235 + --i->refcount;
129236 + if (i->refcount == 0) {
129237 + list_del(&i->list);
129238 + spin_unlock_irq(&alloc->lock);
129239 + if (i->is_alloced)
129240 + _dpa_alloc_free(alloc, base_id, count);
129241 + kfree(i);
129242 + return;
129243 + }
129244 + spin_unlock_irq(&alloc->lock);
129245 + return;
129246 + }
129247 + }
129248 + /* Couldn't find the allocation */
129249 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
129250 + base_id, count);
129251 + spin_unlock_irq(&alloc->lock);
129252 +}
129253 +
129254 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
129255 +{
129256 + /* Same as free but no previous allocation checking is needed */
129257 + _dpa_alloc_free(alloc, base_id, count);
129258 +}
129259 +
129260 +
129261 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
129262 +{
129263 + struct alloc_node *i = NULL, *used_node;
129264 +
129265 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
129266 + DUMP(alloc);
129267 +
129268 + spin_lock_irq(&alloc->lock);
129269 +
129270 + /* Check for the node in the used list.
129271 + If found, increase it's refcount */
129272 + list_for_each_entry(i, &alloc->used, list) {
129273 + if ((i->base == base) && (i->num == num)) {
129274 + ++i->refcount;
129275 + spin_unlock_irq(&alloc->lock);
129276 + return 0;
129277 + }
129278 + if ((base >= i->base) && (base < (i->base + i->num))) {
129279 + /* This is an attempt to reserve a region that was
129280 + already reserved or alloced with a different
129281 + base or num */
129282 + pr_err("Cannot reserve %d - %d, it overlaps with"
129283 + " existing reservation from %d - %d\n",
129284 + base, base + num - 1, i->base,
129285 + i->base + i->num - 1);
129286 + spin_unlock_irq(&alloc->lock);
129287 + return -1;
129288 + }
129289 + }
129290 + /* Check to make sure this ID isn't in the free list */
129291 + list_for_each_entry(i, &alloc->free, list) {
129292 + if ((base >= i->base) && (base < (i->base + i->num))) {
129293 + /* yep, the reservation is within this node */
129294 + pr_err("Cannot reserve %d - %d, it overlaps with"
129295 + " free range %d - %d and must be alloced\n",
129296 + base, base + num - 1,
129297 + i->base, i->base + i->num - 1);
129298 + spin_unlock_irq(&alloc->lock);
129299 + return -1;
129300 + }
129301 + }
129302 + /* Add the allocation to the used list with a refcount of 1 */
129303 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
129304 + if (!used_node) {
129305 + spin_unlock_irq(&alloc->lock);
129306 + return -ENOMEM;
129307 +
129308 + }
129309 + used_node->base = base;
129310 + used_node->num = num;
129311 + used_node->refcount = 1;
129312 + used_node->is_alloced = 0;
129313 + list_add_tail(&used_node->list, &alloc->used);
129314 + spin_unlock_irq(&alloc->lock);
129315 + return 0;
129316 +}
129317 +
129318 +
129319 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
129320 +{
129321 + struct alloc_node *i = NULL;
129322 + DPRINT("alloc_pop()\n");
129323 + DUMP(alloc);
129324 + spin_lock_irq(&alloc->lock);
129325 + if (!list_empty(&alloc->free)) {
129326 + i = list_entry(alloc->free.next, struct alloc_node, list);
129327 + list_del(&i->list);
129328 + }
129329 + spin_unlock_irq(&alloc->lock);
129330 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
129331 + DUMP(alloc);
129332 + if (!i)
129333 + return -ENOMEM;
129334 + *result = i->base;
129335 + *count = i->num;
129336 + kfree(i);
129337 + return 0;
129338 +}
129339 +
129340 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
129341 +{
129342 + struct alloc_node *i = NULL;
129343 + int res = 0;
129344 + DPRINT("alloc_check()\n");
129345 + spin_lock_irq(&list_head->lock);
129346 +
129347 + list_for_each_entry(i, &list_head->free, list) {
129348 + if ((item >= i->base) && (item < (i->base + i->num))) {
129349 + res = 1;
129350 + break;
129351 + }
129352 + }
129353 + spin_unlock_irq(&list_head->lock);
129354 + return res;
129355 +}
129356 diff --git a/drivers/staging/fsl_qbman/dpa_sys.h b/drivers/staging/fsl_qbman/dpa_sys.h
129357 new file mode 100644
129358 index 00000000..e144f5a4
129359 --- /dev/null
129360 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
129361 @@ -0,0 +1,259 @@
129362 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
129363 + *
129364 + * Redistribution and use in source and binary forms, with or without
129365 + * modification, are permitted provided that the following conditions are met:
129366 + * * Redistributions of source code must retain the above copyright
129367 + * notice, this list of conditions and the following disclaimer.
129368 + * * Redistributions in binary form must reproduce the above copyright
129369 + * notice, this list of conditions and the following disclaimer in the
129370 + * documentation and/or other materials provided with the distribution.
129371 + * * Neither the name of Freescale Semiconductor nor the
129372 + * names of its contributors may be used to endorse or promote products
129373 + * derived from this software without specific prior written permission.
129374 + *
129375 + *
129376 + * ALTERNATIVELY, this software may be distributed under the terms of the
129377 + * GNU General Public License ("GPL") as published by the Free Software
129378 + * Foundation, either version 2 of that License or (at your option) any
129379 + * later version.
129380 + *
129381 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129382 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129383 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129384 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129385 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129386 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129387 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129388 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129389 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129390 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129391 + */
129392 +
129393 +#ifndef DPA_SYS_H
129394 +#define DPA_SYS_H
129395 +
129396 +#include <linux/kernel.h>
129397 +#include <linux/errno.h>
129398 +#include <linux/io.h>
129399 +#include <linux/dma-mapping.h>
129400 +#include <linux/bootmem.h>
129401 +#include <linux/slab.h>
129402 +#include <linux/module.h>
129403 +#include <linux/init.h>
129404 +#include <linux/interrupt.h>
129405 +#include <linux/delay.h>
129406 +#include <linux/of_platform.h>
129407 +#include <linux/of_address.h>
129408 +#include <linux/of_irq.h>
129409 +#include <linux/kthread.h>
129410 +#include <linux/memblock.h>
129411 +#include <linux/completion.h>
129412 +#include <linux/log2.h>
129413 +#include <linux/types.h>
129414 +#include <linux/ioctl.h>
129415 +#include <linux/miscdevice.h>
129416 +#include <linux/uaccess.h>
129417 +#include <linux/debugfs.h>
129418 +#include <linux/seq_file.h>
129419 +#include <linux/device.h>
129420 +#include <linux/uio_driver.h>
129421 +#include <linux/smp.h>
129422 +#include <linux/fsl_hypervisor.h>
129423 +#include <linux/vmalloc.h>
129424 +#include <linux/ctype.h>
129425 +#include <linux/math64.h>
129426 +#include <linux/bitops.h>
129427 +
129428 +#include <linux/fsl_usdpaa.h>
129429 +
129430 +/* When copying aligned words or shorts, try to avoid memcpy() */
129431 +#define CONFIG_TRY_BETTER_MEMCPY
129432 +
129433 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
129434 +#define DPA_PORTAL_CE 0
129435 +#define DPA_PORTAL_CI 1
129436 +
129437 +/***********************/
129438 +/* Misc inline assists */
129439 +/***********************/
129440 +
129441 +#if defined CONFIG_PPC32
129442 +#include "dpa_sys_ppc32.h"
129443 +#elif defined CONFIG_PPC64
129444 +#include "dpa_sys_ppc64.h"
129445 +#elif defined CONFIG_ARM
129446 +#include "dpa_sys_arm.h"
129447 +#elif defined CONFIG_ARM64
129448 +#include "dpa_sys_arm64.h"
129449 +#endif
129450 +
129451 +
129452 +#ifdef CONFIG_FSL_DPA_CHECKING
129453 +#define DPA_ASSERT(x) \
129454 + do { \
129455 + if (!(x)) { \
129456 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
129457 + __stringify_1(x)); \
129458 + dump_stack(); \
129459 + panic("assertion failure"); \
129460 + } \
129461 + } while (0)
129462 +#else
129463 +#define DPA_ASSERT(x)
129464 +#endif
129465 +
129466 +/* memcpy() stuff - when you know alignments in advance */
129467 +#ifdef CONFIG_TRY_BETTER_MEMCPY
129468 +static inline void copy_words(void *dest, const void *src, size_t sz)
129469 +{
129470 + u32 *__dest = dest;
129471 + const u32 *__src = src;
129472 + size_t __sz = sz >> 2;
129473 + BUG_ON((unsigned long)dest & 0x3);
129474 + BUG_ON((unsigned long)src & 0x3);
129475 + BUG_ON(sz & 0x3);
129476 + while (__sz--)
129477 + *(__dest++) = *(__src++);
129478 +}
129479 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
129480 +{
129481 + u16 *__dest = dest;
129482 + const u16 *__src = src;
129483 + size_t __sz = sz >> 1;
129484 + BUG_ON((unsigned long)dest & 0x1);
129485 + BUG_ON((unsigned long)src & 0x1);
129486 + BUG_ON(sz & 0x1);
129487 + while (__sz--)
129488 + *(__dest++) = *(__src++);
129489 +}
129490 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
129491 +{
129492 + u8 *__dest = dest;
129493 + const u8 *__src = src;
129494 + while (sz--)
129495 + *(__dest++) = *(__src++);
129496 +}
129497 +#else
129498 +#define copy_words memcpy
129499 +#define copy_shorts memcpy
129500 +#define copy_bytes memcpy
129501 +#endif
129502 +
129503 +/************/
129504 +/* RB-trees */
129505 +/************/
129506 +
129507 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
129508 + * non-linux systems. This also encapsulates the extra plumbing that linux code
129509 + * usually provides when using RB-trees. This encapsulation assumes that the
129510 + * data type held by the tree is u32. */
129511 +
129512 +struct dpa_rbtree {
129513 + struct rb_root root;
129514 +};
129515 +#define DPA_RBTREE { .root = RB_ROOT }
129516 +
129517 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
129518 +{
129519 + tree->root = RB_ROOT;
129520 +}
129521 +
129522 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
129523 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
129524 +{ \
129525 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
129526 + while (*p) { \
129527 + u32 item; \
129528 + parent = *p; \
129529 + item = rb_entry(parent, type, node_field)->val_field; \
129530 + if (obj->val_field < item) \
129531 + p = &parent->rb_left; \
129532 + else if (obj->val_field > item) \
129533 + p = &parent->rb_right; \
129534 + else \
129535 + return -EBUSY; \
129536 + } \
129537 + rb_link_node(&obj->node_field, parent, p); \
129538 + rb_insert_color(&obj->node_field, &tree->root); \
129539 + return 0; \
129540 +} \
129541 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
129542 +{ \
129543 + rb_erase(&obj->node_field, &tree->root); \
129544 +} \
129545 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
129546 +{ \
129547 + type *ret; \
129548 + struct rb_node *p = tree->root.rb_node; \
129549 + while (p) { \
129550 + ret = rb_entry(p, type, node_field); \
129551 + if (val < ret->val_field) \
129552 + p = p->rb_left; \
129553 + else if (val > ret->val_field) \
129554 + p = p->rb_right; \
129555 + else \
129556 + return ret; \
129557 + } \
129558 + return NULL; \
129559 +}
129560 +
129561 +/************/
129562 +/* Bootargs */
129563 +/************/
129564 +
129565 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
129566 + * though; a comma-separated list of items, each item being a cpu index and/or a
129567 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
129568 + * that the portal associated with that cpu should be shared. See bman_driver.c
129569 + * for more specifics. */
129570 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
129571 +{
129572 + *cpu = 0;
129573 + if (!isdigit(**s))
129574 + return -EINVAL;
129575 + while (isdigit(**s))
129576 + *cpu = *cpu * 10 + (*((*s)++) - '0');
129577 + return 0;
129578 +}
129579 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
129580 + struct cpumask *want_unshared,
129581 + const char *argname)
129582 +{
129583 + const char *s = str;
129584 + unsigned int shared, cpu1, cpu2, loop;
129585 +
129586 +keep_going:
129587 + if (*s == 's') {
129588 + shared = 1;
129589 + s++;
129590 + } else
129591 + shared = 0;
129592 + if (__parse_portals_cpu(&s, &cpu1))
129593 + goto err;
129594 + if (*s == '-') {
129595 + s++;
129596 + if (__parse_portals_cpu(&s, &cpu2))
129597 + goto err;
129598 + if (cpu2 < cpu1)
129599 + goto err;
129600 + } else
129601 + cpu2 = cpu1;
129602 + for (loop = cpu1; loop <= cpu2; loop++)
129603 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
129604 + if (*s == ',') {
129605 + s++;
129606 + goto keep_going;
129607 + } else if ((*s == '\0') || isspace(*s))
129608 + return 0;
129609 +err:
129610 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
129611 + (unsigned long)s - (unsigned long)str);
129612 + return -EINVAL;
129613 +}
129614 +#ifdef CONFIG_FSL_USDPAA
129615 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
129616 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
129617 + enum usdpaa_portal_type ptype, unsigned int *irq,
129618 + void **iir_reg);
129619 +#endif
129620 +#endif /* DPA_SYS_H */
129621 diff --git a/drivers/staging/fsl_qbman/dpa_sys_arm.h b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129622 new file mode 100644
129623 index 00000000..17c5500e
129624 --- /dev/null
129625 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129626 @@ -0,0 +1,95 @@
129627 +/* Copyright 2016 Freescale Semiconductor, Inc.
129628 + *
129629 + * Redistribution and use in source and binary forms, with or without
129630 + * modification, are permitted provided that the following conditions are met:
129631 + * * Redistributions of source code must retain the above copyright
129632 + * notice, this list of conditions and the following disclaimer.
129633 + * * Redistributions in binary form must reproduce the above copyright
129634 + * notice, this list of conditions and the following disclaimer in the
129635 + * documentation and/or other materials provided with the distribution.
129636 + * * Neither the name of Freescale Semiconductor nor the
129637 + * names of its contributors may be used to endorse or promote products
129638 + * derived from this software without specific prior written permission.
129639 + *
129640 + *
129641 + * ALTERNATIVELY, this software may be distributed under the terms of the
129642 + * GNU General Public License ("GPL") as published by the Free Software
129643 + * Foundation, either version 2 of that License or (at your option) any
129644 + * later version.
129645 + *
129646 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129647 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129648 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129649 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129650 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129651 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129652 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129653 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129654 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129655 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129656 + */
129657 +
129658 +#ifndef DPA_SYS_ARM_H
129659 +#define DPA_SYS_ARM_H
129660 +
129661 +#include <asm/cacheflush.h>
129662 +#include <asm/barrier.h>
129663 +
129664 +/* Implementation of ARM specific routines */
129665 +
129666 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129667 + * barriers and that dcb*() won't fall victim to compiler or execution
129668 + * reordering with respect to other code/instructions that manipulate the same
129669 + * cacheline. */
129670 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129671 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129672 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
129673 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
129674 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
129675 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
129676 +
129677 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
129678 +
129679 +#define dcbf_64(p) \
129680 + do { \
129681 + dcbf((u32)p); \
129682 + } while (0)
129683 +/* Commonly used combo */
129684 +#define dcbit_ro(p) \
129685 + do { \
129686 + dcbi((u32)p); \
129687 + dcbt_ro((u32)p); \
129688 + } while (0)
129689 +
129690 +static inline u64 mfatb(void)
129691 +{
129692 + return get_cycles();
129693 +}
129694 +
129695 +static inline u32 in_be32(volatile void *addr)
129696 +{
129697 + return be32_to_cpu(*((volatile u32 *) addr));
129698 +}
129699 +
129700 +static inline void out_be32(void *addr, u32 val)
129701 +{
129702 + *((u32 *) addr) = cpu_to_be32(val);
129703 +}
129704 +
129705 +
129706 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129707 +{
129708 + *p |= mask;
129709 +}
129710 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129711 +{
129712 + *p &= ~mask;
129713 +}
129714 +
129715 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129716 +{
129717 + __cpuc_flush_dcache_area((void *) start, stop - start);
129718 +}
129719 +
129720 +#define hard_smp_processor_id() raw_smp_processor_id()
129721 +#endif
129722 diff --git a/drivers/staging/fsl_qbman/dpa_sys_arm64.h b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129723 new file mode 100644
129724 index 00000000..247c8d97
129725 --- /dev/null
129726 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129727 @@ -0,0 +1,102 @@
129728 +/* Copyright 2014 Freescale Semiconductor, Inc.
129729 + *
129730 + * Redistribution and use in source and binary forms, with or without
129731 + * modification, are permitted provided that the following conditions are met:
129732 + * * Redistributions of source code must retain the above copyright
129733 + * notice, this list of conditions and the following disclaimer.
129734 + * * Redistributions in binary form must reproduce the above copyright
129735 + * notice, this list of conditions and the following disclaimer in the
129736 + * documentation and/or other materials provided with the distribution.
129737 + * * Neither the name of Freescale Semiconductor nor the
129738 + * names of its contributors may be used to endorse or promote products
129739 + * derived from this software without specific prior written permission.
129740 + *
129741 + *
129742 + * ALTERNATIVELY, this software may be distributed under the terms of the
129743 + * GNU General Public License ("GPL") as published by the Free Software
129744 + * Foundation, either version 2 of that License or (at your option) any
129745 + * later version.
129746 + *
129747 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129748 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129749 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129750 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129751 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129752 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129753 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129754 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129755 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129756 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129757 + */
129758 +
129759 +#ifndef DPA_SYS_ARM64_H
129760 +#define DPA_SYS_ARM64_H
129761 +
129762 +#include <asm/cacheflush.h>
129763 +#include <asm/barrier.h>
129764 +
129765 +/* Implementation of ARM 64 bit specific routines */
129766 +
129767 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129768 + * barriers and that dcb*() won't fall victim to compiler or execution
129769 + * reordering with respect to other code/instructions that manipulate the same
129770 + * cacheline. */
129771 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129772 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129773 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129774 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129775 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129776 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129777 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129778 +
129779 +#define dcbz_64(p) \
129780 + do { \
129781 + dcbz(p); \
129782 + } while (0)
129783 +
129784 +#define dcbf_64(p) \
129785 + do { \
129786 + dcbf(p); \
129787 + } while (0)
129788 +/* Commonly used combo */
129789 +#define dcbit_ro(p) \
129790 + do { \
129791 + dcbi(p); \
129792 + dcbt_ro(p); \
129793 + } while (0)
129794 +
129795 +static inline u64 mfatb(void)
129796 +{
129797 + return get_cycles();
129798 +}
129799 +
129800 +static inline u32 in_be32(volatile void *addr)
129801 +{
129802 + return be32_to_cpu(*((volatile u32 *) addr));
129803 +}
129804 +
129805 +static inline void out_be32(void *addr, u32 val)
129806 +{
129807 + *((u32 *) addr) = cpu_to_be32(val);
129808 +}
129809 +
129810 +
129811 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129812 +{
129813 + *p |= mask;
129814 +}
129815 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129816 +{
129817 + *p &= ~mask;
129818 +}
129819 +
129820 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129821 +{
129822 + __flush_dcache_area((void *) start, stop - start);
129823 +}
129824 +
129825 +#define hard_smp_processor_id() raw_smp_processor_id()
129826 +
129827 +
129828 +
129829 +#endif
129830 diff --git a/drivers/staging/fsl_qbman/dpa_sys_ppc32.h b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129831 new file mode 100644
129832 index 00000000..874616df
129833 --- /dev/null
129834 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129835 @@ -0,0 +1,70 @@
129836 +/* Copyright 2014 Freescale Semiconductor, Inc.
129837 + *
129838 + * Redistribution and use in source and binary forms, with or without
129839 + * modification, are permitted provided that the following conditions are met:
129840 + * * Redistributions of source code must retain the above copyright
129841 + * notice, this list of conditions and the following disclaimer.
129842 + * * Redistributions in binary form must reproduce the above copyright
129843 + * notice, this list of conditions and the following disclaimer in the
129844 + * documentation and/or other materials provided with the distribution.
129845 + * * Neither the name of Freescale Semiconductor nor the
129846 + * names of its contributors may be used to endorse or promote products
129847 + * derived from this software without specific prior written permission.
129848 + *
129849 + *
129850 + * ALTERNATIVELY, this software may be distributed under the terms of the
129851 + * GNU General Public License ("GPL") as published by the Free Software
129852 + * Foundation, either version 2 of that License or (at your option) any
129853 + * later version.
129854 + *
129855 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129856 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129857 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129858 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129859 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129860 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129861 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129862 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129863 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129864 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129865 + */
129866 +
129867 +#ifndef DPA_SYS_PPC32_H
129868 +#define DPA_SYS_PPC32_H
129869 +
129870 +/* Implementation of PowerPC 32 bit specific routines */
129871 +
129872 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129873 + * barriers and that dcb*() won't fall victim to compiler or execution
129874 + * reordering with respect to other code/instructions that manipulate the same
129875 + * cacheline. */
129876 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129877 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129878 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129879 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129880 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129881 +#define dcbi(p) dcbf(p)
129882 +
129883 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
129884 +#define dcbz_64(p) dcbzl(p)
129885 +#define dcbf_64(p) dcbf(p)
129886 +
129887 +/* Commonly used combo */
129888 +#define dcbit_ro(p) \
129889 + do { \
129890 + dcbi(p); \
129891 + dcbt_ro(p); \
129892 + } while (0)
129893 +
129894 +static inline u64 mfatb(void)
129895 +{
129896 + u32 hi, lo, chk;
129897 + do {
129898 + hi = mfspr(SPRN_ATBU);
129899 + lo = mfspr(SPRN_ATBL);
129900 + chk = mfspr(SPRN_ATBU);
129901 + } while (unlikely(hi != chk));
129902 + return ((u64)hi << 32) | (u64)lo;
129903 +}
129904 +
129905 +#endif
129906 diff --git a/drivers/staging/fsl_qbman/dpa_sys_ppc64.h b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129907 new file mode 100644
129908 index 00000000..d9803199
129909 --- /dev/null
129910 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129911 @@ -0,0 +1,79 @@
129912 +/* Copyright 2014 Freescale Semiconductor, Inc.
129913 + *
129914 + * Redistribution and use in source and binary forms, with or without
129915 + * modification, are permitted provided that the following conditions are met:
129916 + * * Redistributions of source code must retain the above copyright
129917 + * notice, this list of conditions and the following disclaimer.
129918 + * * Redistributions in binary form must reproduce the above copyright
129919 + * notice, this list of conditions and the following disclaimer in the
129920 + * documentation and/or other materials provided with the distribution.
129921 + * * Neither the name of Freescale Semiconductor nor the
129922 + * names of its contributors may be used to endorse or promote products
129923 + * derived from this software without specific prior written permission.
129924 + *
129925 + *
129926 + * ALTERNATIVELY, this software may be distributed under the terms of the
129927 + * GNU General Public License ("GPL") as published by the Free Software
129928 + * Foundation, either version 2 of that License or (at your option) any
129929 + * later version.
129930 + *
129931 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129932 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129933 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129934 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129935 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129936 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129937 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129938 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129939 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129940 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129941 + */
129942 +
129943 +#ifndef DPA_SYS_PPC64_H
129944 +#define DPA_SYS_PPC64_H
129945 +
129946 +/* Implementation of PowerPC 64 bit specific routines */
129947 +
129948 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129949 + * barriers and that dcb*() won't fall victim to compiler or execution
129950 + * reordering with respect to other code/instructions that manipulate the same
129951 + * cacheline. */
129952 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129953 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129954 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129955 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129956 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129957 +#define dcbi(p) dcbf(p)
129958 +
129959 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
129960 +#define dcbz_64(p) \
129961 + do { \
129962 + dcbz((void*)p + 32); \
129963 + dcbz(p); \
129964 + } while (0)
129965 +#define dcbf_64(p) \
129966 + do { \
129967 + dcbf((void*)p + 32); \
129968 + dcbf(p); \
129969 + } while (0)
129970 +/* Commonly used combo */
129971 +#define dcbit_ro(p) \
129972 + do { \
129973 + dcbi(p); \
129974 + dcbi((void*)p + 32); \
129975 + dcbt_ro(p); \
129976 + dcbt_ro((void*)p + 32); \
129977 + } while (0)
129978 +
129979 +static inline u64 mfatb(void)
129980 +{
129981 + u32 hi, lo, chk;
129982 + do {
129983 + hi = mfspr(SPRN_ATBU);
129984 + lo = mfspr(SPRN_ATBL);
129985 + chk = mfspr(SPRN_ATBU);
129986 + } while (unlikely(hi != chk));
129987 + return ((u64)hi << 32) | (u64)lo;
129988 +}
129989 +
129990 +#endif
129991 diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129992 new file mode 100644
129993 index 00000000..3a6d3722
129994 --- /dev/null
129995 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129996 @@ -0,0 +1,1983 @@
129997 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
129998 + * Authors: Andy Fleming <afleming@freescale.com>
129999 + * Timur Tabi <timur@freescale.com>
130000 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
130001 + *
130002 + * This file is licensed under the terms of the GNU General Public License
130003 + * version 2. This program is licensed "as is" without any warranty of any
130004 + * kind, whether express or implied.
130005 + */
130006 +
130007 +
130008 +#include <linux/miscdevice.h>
130009 +#include <linux/fs.h>
130010 +#include <linux/cdev.h>
130011 +#include <linux/mm.h>
130012 +#include <linux/of.h>
130013 +#include <linux/memblock.h>
130014 +#include <linux/slab.h>
130015 +#include <linux/mman.h>
130016 +#include <linux/of_reserved_mem.h>
130017 +
130018 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130019 +#include <mm/mmu_decl.h>
130020 +#endif
130021 +
130022 +#include "dpa_sys.h"
130023 +#include <linux/fsl_usdpaa.h>
130024 +#include "bman_low.h"
130025 +#include "qman_low.h"
130026 +
130027 +/* Physical address range of the memory reservation, exported for mm/mem.c */
130028 +static u64 phys_start;
130029 +static u64 phys_size;
130030 +static u64 arg_phys_size;
130031 +
130032 +/* PFN versions of the above */
130033 +static unsigned long pfn_start;
130034 +static unsigned long pfn_size;
130035 +
130036 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
130037 + * isn't atomic_t). */
130038 +static DEFINE_SPINLOCK(mem_lock);
130039 +
130040 +/* The range of TLB1 indices */
130041 +static unsigned int first_tlb;
130042 +static unsigned int num_tlb = 1;
130043 +static unsigned int current_tlb; /* loops around for fault handling */
130044 +
130045 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
130046 + * may be mapped. Unmapped fragments are always merged where possible. */
130047 +static LIST_HEAD(mem_list);
130048 +
130049 +struct mem_mapping;
130050 +
130051 +/* Memory fragments are in 'mem_list'. */
130052 +struct mem_fragment {
130053 + u64 base;
130054 + u64 len;
130055 + unsigned long pfn_base; /* PFN version of 'base' */
130056 + unsigned long pfn_len; /* PFN version of 'len' */
130057 + unsigned int refs; /* zero if unmapped */
130058 + u64 root_len; /* Size of the orignal fragment */
130059 + unsigned long root_pfn; /* PFN of the orignal fragment */
130060 + struct list_head list;
130061 + /* if mapped, flags+name captured at creation time */
130062 + u32 flags;
130063 + char name[USDPAA_DMA_NAME_MAX];
130064 + u64 map_len;
130065 + /* support multi-process locks per-memory-fragment. */
130066 + int has_locking;
130067 + wait_queue_head_t wq;
130068 + struct mem_mapping *owner;
130069 +};
130070 +
130071 +/* Mappings of memory fragments in 'struct ctx'. These are created from
130072 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
130073 + * mmap(). */
130074 +struct mem_mapping {
130075 + struct mem_fragment *root_frag;
130076 + u32 frag_count;
130077 + u64 total_size;
130078 + struct list_head list;
130079 + int refs;
130080 + void *virt_addr;
130081 +};
130082 +
130083 +struct portal_mapping {
130084 + struct usdpaa_ioctl_portal_map user;
130085 + union {
130086 + struct qm_portal_config *qportal;
130087 + struct bm_portal_config *bportal;
130088 + };
130089 + /* Declare space for the portals in case the process
130090 + exits unexpectedly and needs to be cleaned by the kernel */
130091 + union {
130092 + struct qm_portal qman_portal_low;
130093 + struct bm_portal bman_portal_low;
130094 + };
130095 + struct list_head list;
130096 + struct resource *phys;
130097 + struct iommu_domain *iommu_domain;
130098 +};
130099 +
130100 +/* Track the DPAA resources the process is using */
130101 +struct active_resource {
130102 + struct list_head list;
130103 + u32 id;
130104 + u32 num;
130105 + unsigned int refcount;
130106 +};
130107 +
130108 +/* Per-FD state (which should also be per-process but we don't enforce that) */
130109 +struct ctx {
130110 + /* Lock to protect the context */
130111 + spinlock_t lock;
130112 + /* Allocated resources get put here for accounting */
130113 + struct list_head resources[usdpaa_id_max];
130114 + /* list of DMA maps */
130115 + struct list_head maps;
130116 + /* list of portal maps */
130117 + struct list_head portals;
130118 +};
130119 +
130120 +/* Different resource classes */
130121 +static const struct alloc_backend {
130122 + enum usdpaa_id_type id_type;
130123 + int (*alloc)(u32 *, u32, u32, int);
130124 + void (*release)(u32 base, unsigned int count);
130125 + int (*reserve)(u32 base, unsigned int count);
130126 + const char *acronym;
130127 +} alloc_backends[] = {
130128 + {
130129 + .id_type = usdpaa_id_fqid,
130130 + .alloc = qman_alloc_fqid_range,
130131 + .release = qman_release_fqid_range,
130132 + .reserve = qman_reserve_fqid_range,
130133 + .acronym = "FQID"
130134 + },
130135 + {
130136 + .id_type = usdpaa_id_bpid,
130137 + .alloc = bman_alloc_bpid_range,
130138 + .release = bman_release_bpid_range,
130139 + .reserve = bman_reserve_bpid_range,
130140 + .acronym = "BPID"
130141 + },
130142 + {
130143 + .id_type = usdpaa_id_qpool,
130144 + .alloc = qman_alloc_pool_range,
130145 + .release = qman_release_pool_range,
130146 + .reserve = qman_reserve_pool_range,
130147 + .acronym = "QPOOL"
130148 + },
130149 + {
130150 + .id_type = usdpaa_id_cgrid,
130151 + .alloc = qman_alloc_cgrid_range,
130152 + .release = qman_release_cgrid_range,
130153 + .acronym = "CGRID"
130154 + },
130155 + {
130156 + .id_type = usdpaa_id_ceetm0_lfqid,
130157 + .alloc = qman_alloc_ceetm0_lfqid_range,
130158 + .release = qman_release_ceetm0_lfqid_range,
130159 + .acronym = "CEETM0_LFQID"
130160 + },
130161 + {
130162 + .id_type = usdpaa_id_ceetm0_channelid,
130163 + .alloc = qman_alloc_ceetm0_channel_range,
130164 + .release = qman_release_ceetm0_channel_range,
130165 + .acronym = "CEETM0_LFQID"
130166 + },
130167 + {
130168 + .id_type = usdpaa_id_ceetm1_lfqid,
130169 + .alloc = qman_alloc_ceetm1_lfqid_range,
130170 + .release = qman_release_ceetm1_lfqid_range,
130171 + .acronym = "CEETM1_LFQID"
130172 + },
130173 + {
130174 + .id_type = usdpaa_id_ceetm1_channelid,
130175 + .alloc = qman_alloc_ceetm1_channel_range,
130176 + .release = qman_release_ceetm1_channel_range,
130177 + .acronym = "CEETM1_LFQID"
130178 + },
130179 + {
130180 + /* This terminates the array */
130181 + .id_type = usdpaa_id_max
130182 + }
130183 +};
130184 +
130185 +/* Determines the largest acceptable page size for a given size
130186 + The sizes are determined by what the TLB1 acceptable page sizes are */
130187 +static u32 largest_page_size(u32 size)
130188 +{
130189 + int shift = 30; /* Start at 1G size */
130190 + if (size < 4096)
130191 + return 0;
130192 + do {
130193 + if (size >= (1<<shift))
130194 + return 1<<shift;
130195 + shift -= 2;
130196 + } while (shift >= 12); /* Up to 4k */
130197 + return 0;
130198 +}
130199 +
130200 +/* Determine if value is power of 4 */
130201 +static inline bool is_power_of_4(u64 x)
130202 +{
130203 + if (x == 0 || ((x & (x - 1)) != 0))
130204 + return false;
130205 + return !!(x & 0x5555555555555555ull);
130206 +}
130207 +
130208 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
130209 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
130210 + * until it has a suitable fragment size.) */
130211 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
130212 +{
130213 + struct mem_fragment *x[3];
130214 +
130215 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130216 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130217 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130218 + if (!x[0] || !x[1] || !x[2]) {
130219 + kfree(x[0]);
130220 + kfree(x[1]);
130221 + kfree(x[2]);
130222 + return NULL;
130223 + }
130224 + BUG_ON(frag->refs);
130225 + frag->len >>= 2;
130226 + frag->pfn_len >>= 2;
130227 + x[0]->base = frag->base + frag->len;
130228 + x[1]->base = x[0]->base + frag->len;
130229 + x[2]->base = x[1]->base + frag->len;
130230 + x[0]->len = x[1]->len = x[2]->len = frag->len;
130231 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
130232 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
130233 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
130234 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
130235 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
130236 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
130237 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
130238 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
130239 + list_add_tail(&x[0]->list, &frag->list);
130240 + list_add_tail(&x[1]->list, &x[0]->list);
130241 + list_add_tail(&x[2]->list, &x[1]->list);
130242 + return x[2];
130243 +}
130244 +
130245 +static __maybe_unused void dump_frags(void)
130246 +{
130247 + struct mem_fragment *frag;
130248 + int i = 0;
130249 + list_for_each_entry(frag, &mem_list, list) {
130250 + 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",
130251 + i, frag->base, frag->pfn_base,
130252 + frag->len, frag->root_len, frag->root_pfn,
130253 + frag->refs, frag->name);
130254 + ++i;
130255 + }
130256 +}
130257 +
130258 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
130259 +static void compress_frags(void)
130260 +{
130261 + /* Walk the fragment list and combine fragments */
130262 + struct mem_fragment *frag, *nxtfrag;
130263 + u64 len = 0;
130264 +
130265 + int i, numfrags;
130266 +
130267 +
130268 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130269 +
130270 + while (&frag->list != &mem_list) {
130271 + /* Must combine consecutive fragemenst with
130272 + same root_pfn such that they are power of 4 */
130273 + if (frag->refs != 0) {
130274 + frag = list_entry(frag->list.next,
130275 + struct mem_fragment, list);
130276 + continue; /* Not this window */
130277 + }
130278 + len = frag->len;
130279 + numfrags = 0;
130280 + nxtfrag = list_entry(frag->list.next,
130281 + struct mem_fragment, list);
130282 + while (true) {
130283 + if (&nxtfrag->list == &mem_list) {
130284 + numfrags = 0;
130285 + break; /* End of list */
130286 + }
130287 + if (nxtfrag->refs) {
130288 + numfrags = 0;
130289 + break; /* In use still */
130290 + }
130291 + if (nxtfrag->root_pfn != frag->root_pfn) {
130292 + numfrags = 0;
130293 + break; /* Crosses root fragment boundary */
130294 + }
130295 + len += nxtfrag->len;
130296 + numfrags++;
130297 + if (is_power_of_4(len)) {
130298 + /* These fragments can be combined */
130299 + break;
130300 + }
130301 + nxtfrag = list_entry(nxtfrag->list.next,
130302 + struct mem_fragment, list);
130303 + }
130304 + if (numfrags == 0) {
130305 + frag = list_entry(frag->list.next,
130306 + struct mem_fragment, list);
130307 + continue; /* try the next window */
130308 + }
130309 + for (i = 0; i < numfrags; i++) {
130310 + struct mem_fragment *todel =
130311 + list_entry(nxtfrag->list.prev,
130312 + struct mem_fragment, list);
130313 + nxtfrag->len += todel->len;
130314 + nxtfrag->pfn_len += todel->pfn_len;
130315 + list_del(&todel->list);
130316 + }
130317 + /* Re evaluate the list, things may merge now */
130318 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130319 + }
130320 +}
130321 +
130322 +/* Hook from arch/powerpc/mm/mem.c */
130323 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
130324 +{
130325 + struct mem_fragment *frag;
130326 + int idx = -1;
130327 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
130328 + return -1;
130329 + /* It's in-range, we need to find the fragment */
130330 + spin_lock(&mem_lock);
130331 + list_for_each_entry(frag, &mem_list, list) {
130332 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
130333 + frag->pfn_len))) {
130334 + *phys_addr = frag->base;
130335 + *size = frag->len;
130336 + idx = current_tlb++;
130337 + if (current_tlb >= (first_tlb + num_tlb))
130338 + current_tlb = first_tlb;
130339 + break;
130340 + }
130341 + }
130342 + spin_unlock(&mem_lock);
130343 + return idx;
130344 +}
130345 +
130346 +static int usdpaa_open(struct inode *inode, struct file *filp)
130347 +{
130348 + const struct alloc_backend *backend = &alloc_backends[0];
130349 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
130350 + if (!ctx)
130351 + return -ENOMEM;
130352 + filp->private_data = ctx;
130353 +
130354 + while (backend->id_type != usdpaa_id_max) {
130355 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
130356 + backend++;
130357 + }
130358 +
130359 + INIT_LIST_HEAD(&ctx->maps);
130360 + INIT_LIST_HEAD(&ctx->portals);
130361 + spin_lock_init(&ctx->lock);
130362 +
130363 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
130364 +
130365 + return 0;
130366 +}
130367 +
130368 +#define DQRR_MAXFILL 15
130369 +
130370 +/* Reset a QMan portal to its default state */
130371 +static int init_qm_portal(struct qm_portal_config *config,
130372 + struct qm_portal *portal)
130373 +{
130374 + const struct qm_dqrr_entry *dqrr = NULL;
130375 + int i;
130376 +
130377 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130378 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130379 +
130380 + /* Make sure interrupts are inhibited */
130381 + qm_out(IIR, 1);
130382 +
130383 + /* Initialize the DQRR. This will stop any dequeue
130384 + commands that are in progress */
130385 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
130386 + qm_dqrr_cdc, DQRR_MAXFILL)) {
130387 + pr_err("qm_dqrr_init() failed when trying to"
130388 + " recover portal, portal will be leaked\n");
130389 + return 1;
130390 + }
130391 +
130392 + /* Discard any entries on the DQRR */
130393 + /* If we consume the ring twice something is wrong */
130394 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
130395 + qm_dqrr_pvb_update(portal);
130396 + dqrr = qm_dqrr_current(portal);
130397 + if (!dqrr)
130398 + break;
130399 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
130400 + qm_dqrr_pvb_update(portal);
130401 + qm_dqrr_next(portal);
130402 + }
130403 + /* Initialize the EQCR */
130404 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
130405 + qm_eqcr_get_ci_stashing(portal), 1)) {
130406 + pr_err("Qman EQCR initialisation failed\n");
130407 + return 1;
130408 + }
130409 + /* initialize the MR */
130410 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
130411 + pr_err("Qman MR initialisation failed\n");
130412 + return 1;
130413 + }
130414 + qm_mr_pvb_update(portal);
130415 + while (qm_mr_current(portal)) {
130416 + qm_mr_next(portal);
130417 + qm_mr_cci_consume_to_current(portal);
130418 + qm_mr_pvb_update(portal);
130419 + }
130420 +
130421 + if (qm_mc_init(portal)) {
130422 + pr_err("Qman MC initialisation failed\n");
130423 + return 1;
130424 + }
130425 + return 0;
130426 +}
130427 +
130428 +static int init_bm_portal(struct bm_portal_config *config,
130429 + struct bm_portal *portal)
130430 +{
130431 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130432 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130433 +
130434 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
130435 + pr_err("Bman RCR initialisation failed\n");
130436 + return 1;
130437 + }
130438 + if (bm_mc_init(portal)) {
130439 + pr_err("Bman MC initialisation failed\n");
130440 + return 1;
130441 + }
130442 + return 0;
130443 +}
130444 +
130445 +/* Function that will scan all FQ's in the system. For each FQ that is not
130446 + OOS it will call the check_channel helper to determine if the FQ should
130447 + be torn down. If the check_channel helper returns true the FQ will be
130448 + transitioned to the OOS state */
130449 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
130450 + bool (*check_channel)(void*, u32))
130451 +{
130452 + u32 fq_id = 0;
130453 + while (1) {
130454 + struct qm_mc_command *mcc;
130455 + struct qm_mc_result *mcr;
130456 + u8 state;
130457 + u32 channel;
130458 +
130459 + /* Determine the channel for the FQID */
130460 + mcc = qm_mc_start(portal);
130461 + mcc->queryfq.fqid = fq_id;
130462 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
130463 + while (!(mcr = qm_mc_result(portal)))
130464 + cpu_relax();
130465 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130466 + == QM_MCR_VERB_QUERYFQ);
130467 + if (mcr->result != QM_MCR_RESULT_OK)
130468 + break; /* End of valid FQIDs */
130469 +
130470 + channel = mcr->queryfq.fqd.dest.channel;
130471 + /* Determine the state of the FQID */
130472 + mcc = qm_mc_start(portal);
130473 + mcc->queryfq_np.fqid = fq_id;
130474 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
130475 + while (!(mcr = qm_mc_result(portal)))
130476 + cpu_relax();
130477 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130478 + == QM_MCR_VERB_QUERYFQ_NP);
130479 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
130480 + if (state == QM_MCR_NP_STATE_OOS)
130481 + /* Already OOS, no need to do anymore checks */
130482 + goto next;
130483 +
130484 + if (check_channel(ctx, channel))
130485 + qm_shutdown_fq(&portal, 1, fq_id);
130486 + next:
130487 + ++fq_id;
130488 + }
130489 + return 0;
130490 +}
130491 +
130492 +static bool check_channel_device(void *_ctx, u32 channel)
130493 +{
130494 + struct ctx *ctx = _ctx;
130495 + struct portal_mapping *portal, *tmpportal;
130496 + struct active_resource *res;
130497 +
130498 + /* See if the FQ is destined for one of the portals we're cleaning up */
130499 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130500 + if (portal->user.type == usdpaa_portal_qman) {
130501 + if (portal->qportal->public_cfg.channel == channel) {
130502 + /* This FQs destination is a portal
130503 + we're cleaning, send a retire */
130504 + return true;
130505 + }
130506 + }
130507 + }
130508 +
130509 + /* Check the pool channels that will be released as well */
130510 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
130511 + if ((res->id >= channel) &&
130512 + ((res->id + res->num - 1) <= channel))
130513 + return true;
130514 + }
130515 + return false;
130516 +}
130517 +
130518 +static bool check_portal_channel(void *ctx, u32 channel)
130519 +{
130520 + u32 portal_channel = *(u32 *)ctx;
130521 + if (portal_channel == channel) {
130522 + /* This FQs destination is a portal
130523 + we're cleaning, send a retire */
130524 + return true;
130525 + }
130526 + return false;
130527 +}
130528 +
130529 +
130530 +
130531 +
130532 +static int usdpaa_release(struct inode *inode, struct file *filp)
130533 +{
130534 + struct ctx *ctx = filp->private_data;
130535 + struct mem_mapping *map, *tmpmap;
130536 + struct portal_mapping *portal, *tmpportal;
130537 + const struct alloc_backend *backend = &alloc_backends[0];
130538 + struct active_resource *res;
130539 + struct qm_portal *qm_cleanup_portal = NULL;
130540 + struct bm_portal *bm_cleanup_portal = NULL;
130541 + struct qm_portal_config *qm_alloced_portal = NULL;
130542 + struct bm_portal_config *bm_alloced_portal = NULL;
130543 +
130544 + struct qm_portal *portal_array[qman_portal_max];
130545 + int portal_count = 0;
130546 +
130547 + /* Ensure the release operation cannot be migrated to another
130548 + CPU as CPU specific variables may be needed during cleanup */
130549 +#ifdef CONFIG_PREEMPT_RT_FULL
130550 + migrate_disable();
130551 +#endif
130552 + /* The following logic is used to recover resources that were not
130553 + correctly released by the process that is closing the FD.
130554 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
130555 + in the kernel
130556 + */
130557 +
130558 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130559 + /* Try to recover any portals that weren't shut down */
130560 + if (portal->user.type == usdpaa_portal_qman) {
130561 + portal_array[portal_count] = &portal->qman_portal_low;
130562 + ++portal_count;
130563 + init_qm_portal(portal->qportal,
130564 + &portal->qman_portal_low);
130565 + if (!qm_cleanup_portal) {
130566 + qm_cleanup_portal = &portal->qman_portal_low;
130567 + } else {
130568 + /* Clean FQs on the dedicated channel */
130569 + u32 chan = portal->qportal->public_cfg.channel;
130570 + qm_check_and_destroy_fqs(
130571 + &portal->qman_portal_low, &chan,
130572 + check_portal_channel);
130573 + }
130574 + } else {
130575 + /* BMAN */
130576 + init_bm_portal(portal->bportal,
130577 + &portal->bman_portal_low);
130578 + if (!bm_cleanup_portal)
130579 + bm_cleanup_portal = &portal->bman_portal_low;
130580 + }
130581 + }
130582 + /* If no portal was found, allocate one for cleanup */
130583 + if (!qm_cleanup_portal) {
130584 + qm_alloced_portal = qm_get_unused_portal();
130585 + if (!qm_alloced_portal) {
130586 + pr_crit("No QMan portal avalaible for cleanup\n");
130587 +#ifdef CONFIG_PREEMPT_RT_FULL
130588 + migrate_enable();
130589 +#endif
130590 + return -1;
130591 + }
130592 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
130593 + GFP_KERNEL);
130594 + if (!qm_cleanup_portal) {
130595 +#ifdef CONFIG_PREEMPT_RT_FULL
130596 + migrate_enable();
130597 +#endif
130598 + return -ENOMEM;
130599 + }
130600 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
130601 + portal_array[portal_count] = qm_cleanup_portal;
130602 + ++portal_count;
130603 + }
130604 + if (!bm_cleanup_portal) {
130605 + bm_alloced_portal = bm_get_unused_portal();
130606 + if (!bm_alloced_portal) {
130607 + pr_crit("No BMan portal avalaible for cleanup\n");
130608 +#ifdef CONFIG_PREEMPT_RT_FULL
130609 + migrate_enable();
130610 +#endif
130611 + return -1;
130612 + }
130613 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
130614 + GFP_KERNEL);
130615 + if (!bm_cleanup_portal) {
130616 +#ifdef CONFIG_PREEMPT_RT_FULL
130617 + migrate_enable();
130618 +#endif
130619 + return -ENOMEM;
130620 + }
130621 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
130622 + }
130623 +
130624 + /* OOS the FQs associated with this process */
130625 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
130626 +
130627 + while (backend->id_type != usdpaa_id_max) {
130628 + int leaks = 0;
130629 + list_for_each_entry(res, &ctx->resources[backend->id_type],
130630 + list) {
130631 + if (backend->id_type == usdpaa_id_fqid) {
130632 + int i = 0;
130633 + for (; i < res->num; i++) {
130634 + /* Clean FQs with the cleanup portal */
130635 + qm_shutdown_fq(portal_array,
130636 + portal_count,
130637 + res->id + i);
130638 + }
130639 + }
130640 + leaks += res->num;
130641 + backend->release(res->id, res->num);
130642 + }
130643 + if (leaks)
130644 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
130645 + backend->acronym, (leaks > 1) ? "s" : "");
130646 + backend++;
130647 + }
130648 + /* Release any DMA regions */
130649 + spin_lock(&mem_lock);
130650 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
130651 + struct mem_fragment *current_frag = map->root_frag;
130652 + int i;
130653 + if (map->root_frag->has_locking &&
130654 + (map->root_frag->owner == map)) {
130655 + map->root_frag->owner = NULL;
130656 + wake_up(&map->root_frag->wq);
130657 + }
130658 + /* Check each fragment and merge if the ref count is 0 */
130659 + for (i = 0; i < map->frag_count; i++) {
130660 + --current_frag->refs;
130661 + current_frag = list_entry(current_frag->list.prev,
130662 + struct mem_fragment, list);
130663 + }
130664 +
130665 + compress_frags();
130666 + list_del(&map->list);
130667 + kfree(map);
130668 + }
130669 + spin_unlock(&mem_lock);
130670 +
130671 + /* Return portals */
130672 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130673 + if (portal->user.type == usdpaa_portal_qman) {
130674 + /* Give the portal back to the allocator */
130675 + init_qm_portal(portal->qportal,
130676 + &portal->qman_portal_low);
130677 + qm_put_unused_portal(portal->qportal);
130678 + } else {
130679 + init_bm_portal(portal->bportal,
130680 + &portal->bman_portal_low);
130681 + bm_put_unused_portal(portal->bportal);
130682 + }
130683 + list_del(&portal->list);
130684 + kfree(portal);
130685 + }
130686 + if (qm_alloced_portal) {
130687 + qm_put_unused_portal(qm_alloced_portal);
130688 + kfree(qm_cleanup_portal);
130689 + }
130690 + if (bm_alloced_portal) {
130691 + bm_put_unused_portal(bm_alloced_portal);
130692 + kfree(bm_cleanup_portal);
130693 + }
130694 +
130695 + kfree(ctx);
130696 +#ifdef CONFIG_PREEMPT_RT_FULL
130697 + migrate_enable();
130698 +#endif
130699 + return 0;
130700 +}
130701 +
130702 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130703 + int *match, unsigned long *pfn)
130704 +{
130705 + struct mem_mapping *map;
130706 +
130707 + list_for_each_entry(map, &ctx->maps, list) {
130708 + int i;
130709 + struct mem_fragment *frag = map->root_frag;
130710 +
130711 + for (i = 0; i < map->frag_count; i++) {
130712 + if (frag->pfn_base == vma->vm_pgoff) {
130713 + *match = 1;
130714 + *pfn = frag->pfn_base;
130715 + return 0;
130716 + }
130717 + frag = list_entry(frag->list.next, struct mem_fragment,
130718 + list);
130719 + }
130720 + }
130721 + *match = 0;
130722 + return 0;
130723 +}
130724 +
130725 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130726 + int *match, unsigned long *pfn)
130727 +{
130728 + *pfn = res->start >> PAGE_SHIFT;
130729 + if (*pfn == vma->vm_pgoff) {
130730 + *match = 1;
130731 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130732 + return -EINVAL;
130733 + } else
130734 + *match = 0;
130735 + return 0;
130736 +}
130737 +
130738 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130739 + int *match, unsigned long *pfn)
130740 +{
130741 + struct portal_mapping *portal;
130742 + int ret;
130743 +
130744 + list_for_each_entry(portal, &ctx->portals, list) {
130745 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130746 + match, pfn);
130747 + if (*match) {
130748 + vma->vm_page_prot =
130749 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130750 + pgprot_cached_ns(vma->vm_page_prot);
130751 +#else
130752 + pgprot_cached_noncoherent(vma->vm_page_prot);
130753 +#endif
130754 + return ret;
130755 + }
130756 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130757 + match, pfn);
130758 + if (*match) {
130759 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130760 + return ret;
130761 + }
130762 + }
130763 + *match = 0;
130764 + return 0;
130765 +}
130766 +
130767 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130768 +{
130769 + struct ctx *ctx = filp->private_data;
130770 + unsigned long pfn = 0;
130771 + int match, ret;
130772 +
130773 + spin_lock(&mem_lock);
130774 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130775 + if (!match)
130776 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130777 + spin_unlock(&mem_lock);
130778 + if (!match)
130779 + return -EINVAL;
130780 + if (!ret)
130781 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130782 + vma->vm_end - vma->vm_start,
130783 + vma->vm_page_prot);
130784 + return ret;
130785 +}
130786 +
130787 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130788 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130789 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130790 + ({ \
130791 + unsigned long foo_align = (sz) - 1; \
130792 + ((addr) + foo_align) & ~foo_align; \
130793 + })
130794 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130795 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130796 + unsigned long addr,
130797 + unsigned long len,
130798 + unsigned long pgoff,
130799 + unsigned long flags)
130800 +{
130801 + struct vm_area_struct *vma;
130802 +
130803 + if (len % PAGE_SIZE)
130804 + return -EINVAL;
130805 + if (!len)
130806 + return -EINVAL;
130807 +
130808 + /* Need to align the address to the largest pagesize of the mapping
130809 + * because the MMU requires the virtual address to have the same
130810 + * alignment as the physical address */
130811 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
130812 + vma = find_vma(current->mm, addr);
130813 + /* Keep searching until we reach the end of currently-used virtual
130814 + * address-space or we find a big enough gap. */
130815 + while (vma) {
130816 + if ((addr + len) < vma->vm_start)
130817 + return addr;
130818 +
130819 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
130820 + vma = vma->vm_next;
130821 + }
130822 + if ((TASK_SIZE - len) < addr)
130823 + return -ENOMEM;
130824 + return addr;
130825 +}
130826 +
130827 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
130828 +{
130829 + struct usdpaa_ioctl_id_alloc i;
130830 + const struct alloc_backend *backend;
130831 + struct active_resource *res;
130832 + int ret = copy_from_user(&i, arg, sizeof(i));
130833 + if (ret)
130834 + return ret;
130835 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130836 + return -EINVAL;
130837 + backend = &alloc_backends[i.id_type];
130838 + /* Allocate the required resource type */
130839 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
130840 + if (ret < 0)
130841 + return ret;
130842 + i.num = ret;
130843 + /* Copy the result to user-space */
130844 + ret = copy_to_user(arg, &i, sizeof(i));
130845 + if (ret) {
130846 + backend->release(i.base, i.num);
130847 + return ret;
130848 + }
130849 + /* Assign the allocated range to the FD accounting */
130850 + res = kmalloc(sizeof(*res), GFP_KERNEL);
130851 + if (!res) {
130852 + backend->release(i.base, i.num);
130853 + return -ENOMEM;
130854 + }
130855 + spin_lock(&ctx->lock);
130856 + res->id = i.base;
130857 + res->num = i.num;
130858 + res->refcount = 1;
130859 + list_add(&res->list, &ctx->resources[i.id_type]);
130860 + spin_unlock(&ctx->lock);
130861 + return 0;
130862 +}
130863 +
130864 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
130865 +{
130866 + struct usdpaa_ioctl_id_release i;
130867 + const struct alloc_backend *backend;
130868 + struct active_resource *tmp, *pos;
130869 +
130870 + int ret = copy_from_user(&i, arg, sizeof(i));
130871 + if (ret)
130872 + return ret;
130873 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130874 + return -EINVAL;
130875 + backend = &alloc_backends[i.id_type];
130876 + /* Pull the range out of the FD accounting - the range is valid iff this
130877 + * succeeds. */
130878 + spin_lock(&ctx->lock);
130879 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130880 + if (pos->id == i.base && pos->num == i.num) {
130881 + pos->refcount--;
130882 + if (pos->refcount) {
130883 + spin_unlock(&ctx->lock);
130884 + return 0; /* Still being used */
130885 + }
130886 + list_del(&pos->list);
130887 + kfree(pos);
130888 + spin_unlock(&ctx->lock);
130889 + goto found;
130890 + }
130891 + }
130892 + /* Failed to find the resource */
130893 + spin_unlock(&ctx->lock);
130894 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
130895 + i.id_type, i.base, i.num);
130896 + return -EINVAL;
130897 +found:
130898 + /* Release the resource to the backend */
130899 + backend->release(i.base, i.num);
130900 + return 0;
130901 +}
130902 +
130903 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
130904 +{
130905 + struct usdpaa_ioctl_id_reserve i;
130906 + const struct alloc_backend *backend;
130907 + struct active_resource *tmp, *pos;
130908 +
130909 + int ret = copy_from_user(&i, arg, sizeof(i));
130910 + if (ret)
130911 + return ret;
130912 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130913 + return -EINVAL;
130914 + backend = &alloc_backends[i.id_type];
130915 + if (!backend->reserve)
130916 + return -EINVAL;
130917 + /* Pull the range out of the FD accounting - the range is valid iff this
130918 + * succeeds. */
130919 + spin_lock(&ctx->lock);
130920 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130921 + if (pos->id == i.base && pos->num == i.num) {
130922 + pos->refcount++;
130923 + spin_unlock(&ctx->lock);
130924 + return 0;
130925 + }
130926 + }
130927 +
130928 + /* Failed to find the resource */
130929 + spin_unlock(&ctx->lock);
130930 +
130931 + /* Reserve the resource in the backend */
130932 + ret = backend->reserve(i.base, i.num);
130933 + if (ret)
130934 + return ret;
130935 + /* Assign the reserved range to the FD accounting */
130936 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
130937 + if (!pos) {
130938 + backend->release(i.base, i.num);
130939 + return -ENOMEM;
130940 + }
130941 + spin_lock(&ctx->lock);
130942 + pos->id = i.base;
130943 + pos->num = i.num;
130944 + pos->refcount = 1;
130945 + list_add(&pos->list, &ctx->resources[i.id_type]);
130946 + spin_unlock(&ctx->lock);
130947 + return 0;
130948 +}
130949 +
130950 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
130951 + struct usdpaa_ioctl_dma_map *i)
130952 +{
130953 + struct mem_fragment *frag, *start_frag, *next_frag;
130954 + struct mem_mapping *map, *tmp;
130955 + int ret = 0;
130956 + u32 largest_page, so_far = 0;
130957 + int frag_count = 0;
130958 + unsigned long next_addr = PAGE_SIZE, populate;
130959 +
130960 + /* error checking to ensure values copied from user space are valid */
130961 + if (i->len % PAGE_SIZE)
130962 + return -EINVAL;
130963 +
130964 + map = kmalloc(sizeof(*map), GFP_KERNEL);
130965 + if (!map)
130966 + return -ENOMEM;
130967 +
130968 + spin_lock(&mem_lock);
130969 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
130970 + list_for_each_entry(frag, &mem_list, list) {
130971 + if (frag->refs && (frag->flags &
130972 + USDPAA_DMA_FLAG_SHARE) &&
130973 + !strncmp(i->name, frag->name,
130974 + USDPAA_DMA_NAME_MAX)) {
130975 + /* Matching entry */
130976 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
130977 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
130978 + ret = -EBUSY;
130979 + goto out;
130980 + }
130981 +
130982 + /* Check to ensure size matches record */
130983 + if (i->len != frag->map_len && i->len) {
130984 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
130985 + frag->name);
130986 + return -EINVAL;
130987 + }
130988 +
130989 + /* Check if this has already been mapped
130990 + to this process */
130991 + list_for_each_entry(tmp, &ctx->maps, list)
130992 + if (tmp->root_frag == frag) {
130993 + /* Already mapped, just need to
130994 + inc ref count */
130995 + tmp->refs++;
130996 + kfree(map);
130997 + i->did_create = 0;
130998 + i->len = tmp->total_size;
130999 + i->phys_addr = frag->base;
131000 + i->ptr = tmp->virt_addr;
131001 + spin_unlock(&mem_lock);
131002 + return 0;
131003 + }
131004 + /* Matching entry - just need to map */
131005 + i->has_locking = frag->has_locking;
131006 + i->did_create = 0;
131007 + i->len = frag->map_len;
131008 + start_frag = frag;
131009 + goto do_map;
131010 + }
131011 + }
131012 + /* No matching entry */
131013 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
131014 + pr_err("ioctl_dma_map() No matching entry\n");
131015 + ret = -ENOMEM;
131016 + goto out;
131017 + }
131018 + }
131019 + /* New fragment required, size must be provided. */
131020 + if (!i->len) {
131021 + ret = -EINVAL;
131022 + goto out;
131023 + }
131024 +
131025 + /* Find one of more contiguous fragments that satisfy the total length
131026 + trying to minimize the number of fragments
131027 + compute the largest page size that the allocation could use */
131028 + largest_page = largest_page_size(i->len);
131029 + start_frag = NULL;
131030 + while (largest_page &&
131031 + largest_page <= largest_page_size(phys_size) &&
131032 + start_frag == NULL) {
131033 + /* Search the list for a frag of that size */
131034 + list_for_each_entry(frag, &mem_list, list) {
131035 + if (!frag->refs && (frag->len == largest_page)) {
131036 + /* See if the next x fragments are free
131037 + and can accomidate the size */
131038 + u32 found_size = largest_page;
131039 + next_frag = list_entry(frag->list.prev,
131040 + struct mem_fragment,
131041 + list);
131042 + /* If the fragement is too small check
131043 + if the neighbours cab support it */
131044 + while (found_size < i->len) {
131045 + if (&mem_list == &next_frag->list)
131046 + break; /* End of list */
131047 + if (next_frag->refs != 0 ||
131048 + next_frag->len == 0)
131049 + break; /* not enough space */
131050 + found_size += next_frag->len;
131051 + next_frag = list_entry(
131052 + next_frag->list.prev,
131053 + struct mem_fragment,
131054 + list);
131055 + }
131056 + if (found_size >= i->len) {
131057 + /* Success! there is enough contigous
131058 + free space */
131059 + start_frag = frag;
131060 + break;
131061 + }
131062 + }
131063 + } /* next frag loop */
131064 + /* Couldn't statisfy the request with this
131065 + largest page size, try a smaller one */
131066 + largest_page <<= 2;
131067 + }
131068 + if (start_frag == NULL) {
131069 + /* Couldn't find proper amount of space */
131070 + ret = -ENOMEM;
131071 + goto out;
131072 + }
131073 + i->did_create = 1;
131074 +do_map:
131075 + /* Verify there is sufficient space to do the mapping */
131076 + down_write(&current->mm->mmap_sem);
131077 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
131078 + up_write(&current->mm->mmap_sem);
131079 +
131080 + if (next_addr & ~PAGE_MASK) {
131081 + ret = -ENOMEM;
131082 + goto out;
131083 + }
131084 +
131085 + /* We may need to divide the final fragment to accomidate the mapping */
131086 + next_frag = start_frag;
131087 + while (so_far != i->len) {
131088 + BUG_ON(next_frag->len == 0);
131089 + while ((next_frag->len + so_far) > i->len) {
131090 + /* Split frag until they match */
131091 + split_frag(next_frag);
131092 + }
131093 + so_far += next_frag->len;
131094 + next_frag->refs++;
131095 + ++frag_count;
131096 + next_frag = list_entry(next_frag->list.prev,
131097 + struct mem_fragment, list);
131098 + }
131099 + if (i->did_create) {
131100 + size_t name_len = 0;
131101 + start_frag->flags = i->flags;
131102 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
131103 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
131104 + if (name_len >= USDPAA_DMA_NAME_MAX) {
131105 + ret = -EFAULT;
131106 + goto out;
131107 + }
131108 + start_frag->map_len = i->len;
131109 + start_frag->has_locking = i->has_locking;
131110 + init_waitqueue_head(&start_frag->wq);
131111 + start_frag->owner = NULL;
131112 + }
131113 +
131114 + /* Setup the map entry */
131115 + map->root_frag = start_frag;
131116 + map->total_size = i->len;
131117 + map->frag_count = frag_count;
131118 + map->refs = 1;
131119 + list_add(&map->list, &ctx->maps);
131120 + i->phys_addr = start_frag->base;
131121 +out:
131122 + spin_unlock(&mem_lock);
131123 +
131124 + if (!ret) {
131125 + unsigned long longret;
131126 + down_write(&current->mm->mmap_sem);
131127 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
131128 + PROT_READ |
131129 + (i->flags &
131130 + USDPAA_DMA_FLAG_RDONLY ? 0
131131 + : PROT_WRITE),
131132 + MAP_SHARED,
131133 + start_frag->pfn_base,
131134 + &populate);
131135 + up_write(&current->mm->mmap_sem);
131136 + if (longret & ~PAGE_MASK) {
131137 + ret = (int)longret;
131138 + } else {
131139 + i->ptr = (void *)longret;
131140 + map->virt_addr = i->ptr;
131141 + }
131142 + } else
131143 + kfree(map);
131144 + return ret;
131145 +}
131146 +
131147 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
131148 +{
131149 + struct mem_mapping *map;
131150 + struct vm_area_struct *vma;
131151 + int ret, i;
131152 + struct mem_fragment *current_frag;
131153 + size_t sz;
131154 + unsigned long base;
131155 + unsigned long vaddr;
131156 +
131157 + down_write(&current->mm->mmap_sem);
131158 + vma = find_vma(current->mm, (unsigned long)arg);
131159 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
131160 + up_write(&current->mm->mmap_sem);
131161 + return -EFAULT;
131162 + }
131163 + spin_lock(&mem_lock);
131164 + list_for_each_entry(map, &ctx->maps, list) {
131165 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
131166 + /* Drop the map lock if we hold it */
131167 + if (map->root_frag->has_locking &&
131168 + (map->root_frag->owner == map)) {
131169 + map->root_frag->owner = NULL;
131170 + wake_up(&map->root_frag->wq);
131171 + }
131172 + goto map_match;
131173 + }
131174 + }
131175 + /* Failed to find a matching mapping for this process */
131176 + ret = -EFAULT;
131177 + spin_unlock(&mem_lock);
131178 + goto out;
131179 +map_match:
131180 + map->refs--;
131181 + if (map->refs != 0) {
131182 + /* Another call the dma_map is referencing this */
131183 + ret = 0;
131184 + spin_unlock(&mem_lock);
131185 + goto out;
131186 + }
131187 +
131188 + current_frag = map->root_frag;
131189 + vaddr = (unsigned long) map->virt_addr;
131190 + for (i = 0; i < map->frag_count; i++) {
131191 + DPA_ASSERT(current_frag->refs > 0);
131192 + --current_frag->refs;
131193 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
131194 + /*
131195 + * Make sure we invalidate the TLB entry for
131196 + * this fragment, otherwise a remap of a different
131197 + * page to this vaddr would give acces to an
131198 + * incorrect piece of memory
131199 + */
131200 + cleartlbcam(vaddr, mfspr(SPRN_PID));
131201 +#endif
131202 + vaddr += current_frag->len;
131203 + current_frag = list_entry(current_frag->list.prev,
131204 + struct mem_fragment, list);
131205 + }
131206 + map->root_frag->name[0] = 0;
131207 + list_del(&map->list);
131208 + compress_frags();
131209 + spin_unlock(&mem_lock);
131210 +
131211 + base = vma->vm_start;
131212 + sz = vma->vm_end - vma->vm_start;
131213 + do_munmap(current->mm, base, sz);
131214 + ret = 0;
131215 + out:
131216 + up_write(&current->mm->mmap_sem);
131217 + return ret;
131218 +}
131219 +
131220 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
131221 +{
131222 + struct mem_fragment *frag;
131223 + struct usdpaa_ioctl_dma_used result;
131224 +
131225 + result.free_bytes = 0;
131226 + result.total_bytes = phys_size;
131227 +
131228 + list_for_each_entry(frag, &mem_list, list) {
131229 + if (frag->refs == 0)
131230 + result.free_bytes += frag->len;
131231 + }
131232 +
131233 + return copy_to_user(arg, &result, sizeof(result)); }
131234 +
131235 +static int test_lock(struct mem_mapping *map)
131236 +{
131237 + int ret = 0;
131238 + spin_lock(&mem_lock);
131239 + if (!map->root_frag->owner) {
131240 + map->root_frag->owner = map;
131241 + ret = 1;
131242 + }
131243 + spin_unlock(&mem_lock);
131244 + return ret;
131245 +}
131246 +
131247 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
131248 +{
131249 + struct mem_mapping *map;
131250 + struct vm_area_struct *vma;
131251 +
131252 + down_read(&current->mm->mmap_sem);
131253 + vma = find_vma(current->mm, (unsigned long)arg);
131254 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
131255 + up_read(&current->mm->mmap_sem);
131256 + return -EFAULT;
131257 + }
131258 + spin_lock(&mem_lock);
131259 + list_for_each_entry(map, &ctx->maps, list) {
131260 + if (map->root_frag->pfn_base == vma->vm_pgoff)
131261 + goto map_match;
131262 + }
131263 + map = NULL;
131264 +map_match:
131265 + spin_unlock(&mem_lock);
131266 + up_read(&current->mm->mmap_sem);
131267 +
131268 + if (!map)
131269 + return -EFAULT;
131270 + if (!map->root_frag->has_locking)
131271 + return -ENODEV;
131272 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
131273 +}
131274 +
131275 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
131276 +{
131277 + struct mem_mapping *map;
131278 + struct vm_area_struct *vma;
131279 + int ret;
131280 +
131281 + down_read(&current->mm->mmap_sem);
131282 + vma = find_vma(current->mm, (unsigned long)arg);
131283 + if (!vma || (vma->vm_start > (unsigned long)arg))
131284 + ret = -EFAULT;
131285 + else {
131286 + spin_lock(&mem_lock);
131287 + list_for_each_entry(map, &ctx->maps, list) {
131288 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
131289 + if (!map->root_frag->has_locking)
131290 + ret = -ENODEV;
131291 + else if (map->root_frag->owner == map) {
131292 + map->root_frag->owner = NULL;
131293 + wake_up(&map->root_frag->wq);
131294 + ret = 0;
131295 + } else
131296 + ret = -EBUSY;
131297 + goto map_match;
131298 + }
131299 + }
131300 + ret = -EINVAL;
131301 +map_match:
131302 + spin_unlock(&mem_lock);
131303 + }
131304 + up_read(&current->mm->mmap_sem);
131305 + return ret;
131306 +}
131307 +
131308 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
131309 +{
131310 + unsigned long longret = 0, populate;
131311 + resource_size_t len;
131312 +
131313 + down_write(&current->mm->mmap_sem);
131314 + len = resource_size(res);
131315 + if (len != (unsigned long)len)
131316 + return -EINVAL;
131317 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
131318 + PROT_READ | PROT_WRITE, MAP_SHARED,
131319 + res->start >> PAGE_SHIFT, &populate);
131320 + up_write(&current->mm->mmap_sem);
131321 +
131322 + if (longret & ~PAGE_MASK)
131323 + return (int)longret;
131324 +
131325 + *ptr = (void *) longret;
131326 + return 0;
131327 +}
131328 +
131329 +static void portal_munmap(struct resource *res, void *ptr)
131330 +{
131331 + down_write(&current->mm->mmap_sem);
131332 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
131333 + up_write(&current->mm->mmap_sem);
131334 +}
131335 +
131336 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
131337 + struct usdpaa_ioctl_portal_map *arg)
131338 +{
131339 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131340 + int ret;
131341 +
131342 + if (!mapping)
131343 + return -ENOMEM;
131344 +
131345 + mapping->user = *arg;
131346 + mapping->iommu_domain = NULL;
131347 +
131348 + if (mapping->user.type == usdpaa_portal_qman) {
131349 + mapping->qportal =
131350 + qm_get_unused_portal_idx(mapping->user.index);
131351 + if (!mapping->qportal) {
131352 + ret = -ENODEV;
131353 + goto err_get_portal;
131354 + }
131355 + mapping->phys = &mapping->qportal->addr_phys[0];
131356 + mapping->user.channel = mapping->qportal->public_cfg.channel;
131357 + mapping->user.pools = mapping->qportal->public_cfg.pools;
131358 + mapping->user.index = mapping->qportal->public_cfg.index;
131359 + } else if (mapping->user.type == usdpaa_portal_bman) {
131360 + mapping->bportal =
131361 + bm_get_unused_portal_idx(mapping->user.index);
131362 + if (!mapping->bportal) {
131363 + ret = -ENODEV;
131364 + goto err_get_portal;
131365 + }
131366 + mapping->phys = &mapping->bportal->addr_phys[0];
131367 + mapping->user.index = mapping->bportal->public_cfg.index;
131368 + } else {
131369 + ret = -EINVAL;
131370 + goto err_copy_from_user;
131371 + }
131372 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131373 + * handlers look it up. */
131374 + spin_lock(&mem_lock);
131375 + list_add(&mapping->list, &ctx->portals);
131376 + spin_unlock(&mem_lock);
131377 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
131378 + &mapping->user.addr.cena);
131379 + if (ret)
131380 + goto err_mmap_cena;
131381 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
131382 + &mapping->user.addr.cinh);
131383 + if (ret)
131384 + goto err_mmap_cinh;
131385 + *arg = mapping->user;
131386 + return ret;
131387 +
131388 +err_mmap_cinh:
131389 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131390 +err_mmap_cena:
131391 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
131392 + qm_put_unused_portal(mapping->qportal);
131393 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
131394 + bm_put_unused_portal(mapping->bportal);
131395 + spin_lock(&mem_lock);
131396 + list_del(&mapping->list);
131397 + spin_unlock(&mem_lock);
131398 +err_get_portal:
131399 +err_copy_from_user:
131400 + kfree(mapping);
131401 + return ret;
131402 +}
131403 +
131404 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
131405 +{
131406 + struct portal_mapping *mapping;
131407 + struct vm_area_struct *vma;
131408 + unsigned long pfn;
131409 + u32 channel;
131410 +
131411 + /* Get the PFN corresponding to one of the virt addresses */
131412 + down_read(&current->mm->mmap_sem);
131413 + vma = find_vma(current->mm, (unsigned long)i->cinh);
131414 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
131415 + up_read(&current->mm->mmap_sem);
131416 + return -EFAULT;
131417 + }
131418 + pfn = vma->vm_pgoff;
131419 + up_read(&current->mm->mmap_sem);
131420 +
131421 + /* Find the corresponding portal */
131422 + spin_lock(&mem_lock);
131423 + list_for_each_entry(mapping, &ctx->portals, list) {
131424 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
131425 + goto found;
131426 + }
131427 + mapping = NULL;
131428 +found:
131429 + if (mapping)
131430 + list_del(&mapping->list);
131431 + spin_unlock(&mem_lock);
131432 + if (!mapping)
131433 + return -ENODEV;
131434 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
131435 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131436 + if (mapping->user.type == usdpaa_portal_qman) {
131437 + init_qm_portal(mapping->qportal,
131438 + &mapping->qman_portal_low);
131439 +
131440 + /* Tear down any FQs this portal is referencing */
131441 + channel = mapping->qportal->public_cfg.channel;
131442 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131443 + &channel,
131444 + check_portal_channel);
131445 + qm_put_unused_portal(mapping->qportal);
131446 + } else if (mapping->user.type == usdpaa_portal_bman) {
131447 + init_bm_portal(mapping->bportal,
131448 + &mapping->bman_portal_low);
131449 + bm_put_unused_portal(mapping->bportal);
131450 + }
131451 + kfree(mapping);
131452 + return 0;
131453 +}
131454 +
131455 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
131456 + uint32_t cpu, uint32_t cache, uint32_t window)
131457 +{
131458 +#ifdef CONFIG_FSL_PAMU
131459 + int ret;
131460 + int window_count = 1;
131461 + struct iommu_domain_geometry geom_attr;
131462 + struct pamu_stash_attribute stash_attr;
131463 +
131464 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
131465 + if (!pcfg->iommu_domain) {
131466 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
131467 + __func__);
131468 + goto _no_iommu;
131469 + }
131470 + geom_attr.aperture_start = 0;
131471 + geom_attr.aperture_end =
131472 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
131473 + geom_attr.force_aperture = true;
131474 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
131475 + &geom_attr);
131476 + if (ret < 0) {
131477 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131478 + __func__, ret);
131479 + goto _iommu_domain_free;
131480 + }
131481 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
131482 + &window_count);
131483 + if (ret < 0) {
131484 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131485 + __func__, ret);
131486 + goto _iommu_domain_free;
131487 + }
131488 + stash_attr.cpu = cpu;
131489 + stash_attr.cache = cache;
131490 + /* set stash information for the window */
131491 + stash_attr.window = 0;
131492 +
131493 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131494 + DOMAIN_ATTR_FSL_PAMU_STASH,
131495 + &stash_attr);
131496 + if (ret < 0) {
131497 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131498 + __func__, ret);
131499 + goto _iommu_domain_free;
131500 + }
131501 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
131502 + IOMMU_READ | IOMMU_WRITE);
131503 + if (ret < 0) {
131504 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
131505 + __func__, ret);
131506 + goto _iommu_domain_free;
131507 + }
131508 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
131509 + if (ret < 0) {
131510 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
131511 + __func__, ret);
131512 + goto _iommu_domain_free;
131513 + }
131514 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131515 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
131516 + &window_count);
131517 + if (ret < 0) {
131518 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131519 + __func__, ret);
131520 + goto _iommu_detach_device;
131521 + }
131522 +_no_iommu:
131523 +#endif
131524 +
131525 +#ifdef CONFIG_FSL_QMAN_CONFIG
131526 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
131527 +#endif
131528 + pr_warn("Failed to set QMan portal's stash request queue\n");
131529 +
131530 + return;
131531 +
131532 +#ifdef CONFIG_FSL_PAMU
131533 +_iommu_detach_device:
131534 + iommu_detach_device(pcfg->iommu_domain, NULL);
131535 +_iommu_domain_free:
131536 + iommu_domain_free(pcfg->iommu_domain);
131537 +#endif
131538 +}
131539 +
131540 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
131541 + struct usdpaa_ioctl_raw_portal *arg)
131542 +{
131543 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131544 + int ret;
131545 +
131546 + if (!mapping)
131547 + return -ENOMEM;
131548 +
131549 + mapping->user.type = arg->type;
131550 + mapping->iommu_domain = NULL;
131551 + if (arg->type == usdpaa_portal_qman) {
131552 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
131553 + if (!mapping->qportal) {
131554 + ret = -ENODEV;
131555 + goto err;
131556 + }
131557 + mapping->phys = &mapping->qportal->addr_phys[0];
131558 + arg->index = mapping->qportal->public_cfg.index;
131559 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
131560 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
131561 + if (arg->enable_stash) {
131562 + /* Setup the PAMU with the supplied parameters */
131563 + portal_config_pamu(mapping->qportal, arg->sdest,
131564 + arg->cpu, arg->cache, arg->window);
131565 + }
131566 + } else if (mapping->user.type == usdpaa_portal_bman) {
131567 + mapping->bportal =
131568 + bm_get_unused_portal_idx(arg->index);
131569 + if (!mapping->bportal) {
131570 + ret = -ENODEV;
131571 + goto err;
131572 + }
131573 + mapping->phys = &mapping->bportal->addr_phys[0];
131574 + arg->index = mapping->bportal->public_cfg.index;
131575 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
131576 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
131577 + } else {
131578 + ret = -EINVAL;
131579 + goto err;
131580 + }
131581 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131582 + * handlers look it up. */
131583 + spin_lock(&mem_lock);
131584 + list_add(&mapping->list, &ctx->portals);
131585 + spin_unlock(&mem_lock);
131586 + return 0;
131587 +err:
131588 + kfree(mapping);
131589 + return ret;
131590 +}
131591 +
131592 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
131593 + struct usdpaa_ioctl_raw_portal *arg)
131594 +{
131595 + struct portal_mapping *mapping;
131596 + u32 channel;
131597 +
131598 + /* Find the corresponding portal */
131599 + spin_lock(&mem_lock);
131600 + list_for_each_entry(mapping, &ctx->portals, list) {
131601 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
131602 + goto found;
131603 + }
131604 + mapping = NULL;
131605 +found:
131606 + if (mapping)
131607 + list_del(&mapping->list);
131608 + spin_unlock(&mem_lock);
131609 + if (!mapping)
131610 + return -ENODEV;
131611 + if (mapping->user.type == usdpaa_portal_qman) {
131612 + init_qm_portal(mapping->qportal,
131613 + &mapping->qman_portal_low);
131614 +
131615 + /* Tear down any FQs this portal is referencing */
131616 + channel = mapping->qportal->public_cfg.channel;
131617 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131618 + &channel,
131619 + check_portal_channel);
131620 + qm_put_unused_portal(mapping->qportal);
131621 + } else if (mapping->user.type == usdpaa_portal_bman) {
131622 + init_bm_portal(mapping->bportal,
131623 + &mapping->bman_portal_low);
131624 + bm_put_unused_portal(mapping->bportal);
131625 + }
131626 + kfree(mapping);
131627 + return 0;
131628 +}
131629 +
131630 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
131631 +{
131632 + struct ctx *ctx = fp->private_data;
131633 + void __user *a = (void __user *)arg;
131634 + switch (cmd) {
131635 + case USDPAA_IOCTL_ID_ALLOC:
131636 + return ioctl_id_alloc(ctx, a);
131637 + case USDPAA_IOCTL_ID_RELEASE:
131638 + return ioctl_id_release(ctx, a);
131639 + case USDPAA_IOCTL_ID_RESERVE:
131640 + return ioctl_id_reserve(ctx, a);
131641 + case USDPAA_IOCTL_DMA_MAP:
131642 + {
131643 + struct usdpaa_ioctl_dma_map input;
131644 + int ret;
131645 + if (copy_from_user(&input, a, sizeof(input)))
131646 + return -EFAULT;
131647 + ret = ioctl_dma_map(fp, ctx, &input);
131648 + if (copy_to_user(a, &input, sizeof(input)))
131649 + return -EFAULT;
131650 + return ret;
131651 + }
131652 + case USDPAA_IOCTL_DMA_UNMAP:
131653 + return ioctl_dma_unmap(ctx, a);
131654 + case USDPAA_IOCTL_DMA_LOCK:
131655 + return ioctl_dma_lock(ctx, a);
131656 + case USDPAA_IOCTL_DMA_UNLOCK:
131657 + return ioctl_dma_unlock(ctx, a);
131658 + case USDPAA_IOCTL_PORTAL_MAP:
131659 + {
131660 + struct usdpaa_ioctl_portal_map input;
131661 + int ret;
131662 + if (copy_from_user(&input, a, sizeof(input)))
131663 + return -EFAULT;
131664 + ret = ioctl_portal_map(fp, ctx, &input);
131665 + if (copy_to_user(a, &input, sizeof(input)))
131666 + return -EFAULT;
131667 + return ret;
131668 + }
131669 + case USDPAA_IOCTL_PORTAL_UNMAP:
131670 + {
131671 + struct usdpaa_portal_map input;
131672 + if (copy_from_user(&input, a, sizeof(input)))
131673 + return -EFAULT;
131674 + return ioctl_portal_unmap(ctx, &input);
131675 + }
131676 + case USDPAA_IOCTL_DMA_USED:
131677 + return ioctl_dma_stats(ctx, a);
131678 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
131679 + {
131680 + struct usdpaa_ioctl_raw_portal input;
131681 + int ret;
131682 + if (copy_from_user(&input, a, sizeof(input)))
131683 + return -EFAULT;
131684 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
131685 + if (copy_to_user(a, &input, sizeof(input)))
131686 + return -EFAULT;
131687 + return ret;
131688 + }
131689 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
131690 + {
131691 + struct usdpaa_ioctl_raw_portal input;
131692 + if (copy_from_user(&input, a, sizeof(input)))
131693 + return -EFAULT;
131694 + return ioctl_free_raw_portal(fp, ctx, &input);
131695 + }
131696 + }
131697 + return -EINVAL;
131698 +}
131699 +
131700 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131701 + unsigned long arg)
131702 +{
131703 +#ifdef CONFIG_COMPAT
131704 + struct ctx *ctx = fp->private_data;
131705 + void __user *a = (void __user *)arg;
131706 +#endif
131707 + switch (cmd) {
131708 +#ifdef CONFIG_COMPAT
131709 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131710 + {
131711 + int ret;
131712 + struct usdpaa_ioctl_dma_map_compat input;
131713 + struct usdpaa_ioctl_dma_map converted;
131714 +
131715 + if (copy_from_user(&input, a, sizeof(input)))
131716 + return -EFAULT;
131717 +
131718 + converted.ptr = compat_ptr(input.ptr);
131719 + converted.phys_addr = input.phys_addr;
131720 + converted.len = input.len;
131721 + converted.flags = input.flags;
131722 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131723 + converted.has_locking = input.has_locking;
131724 + converted.did_create = input.did_create;
131725 +
131726 + ret = ioctl_dma_map(fp, ctx, &converted);
131727 + input.ptr = ptr_to_compat(converted.ptr);
131728 + input.phys_addr = converted.phys_addr;
131729 + input.len = converted.len;
131730 + input.flags = converted.flags;
131731 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131732 + input.has_locking = converted.has_locking;
131733 + input.did_create = converted.did_create;
131734 + if (copy_to_user(a, &input, sizeof(input)))
131735 + return -EFAULT;
131736 + return ret;
131737 + }
131738 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131739 + {
131740 + int ret;
131741 + struct compat_usdpaa_ioctl_portal_map input;
131742 + struct usdpaa_ioctl_portal_map converted;
131743 + if (copy_from_user(&input, a, sizeof(input)))
131744 + return -EFAULT;
131745 + converted.type = input.type;
131746 + converted.index = input.index;
131747 + ret = ioctl_portal_map(fp, ctx, &converted);
131748 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131749 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131750 + input.channel = converted.channel;
131751 + input.pools = converted.pools;
131752 + input.index = converted.index;
131753 + if (copy_to_user(a, &input, sizeof(input)))
131754 + return -EFAULT;
131755 + return ret;
131756 + }
131757 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131758 + {
131759 + struct usdpaa_portal_map_compat input;
131760 + struct usdpaa_portal_map converted;
131761 +
131762 + if (copy_from_user(&input, a, sizeof(input)))
131763 + return -EFAULT;
131764 + converted.cinh = compat_ptr(input.cinh);
131765 + converted.cena = compat_ptr(input.cena);
131766 + return ioctl_portal_unmap(ctx, &converted);
131767 + }
131768 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131769 + {
131770 + int ret;
131771 + struct usdpaa_ioctl_raw_portal converted;
131772 + struct compat_ioctl_raw_portal input;
131773 + if (copy_from_user(&input, a, sizeof(input)))
131774 + return -EFAULT;
131775 + converted.type = input.type;
131776 + converted.index = input.index;
131777 + converted.enable_stash = input.enable_stash;
131778 + converted.cpu = input.cpu;
131779 + converted.cache = input.cache;
131780 + converted.window = input.window;
131781 + converted.sdest = input.sdest;
131782 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131783 +
131784 + input.cinh = converted.cinh;
131785 + input.cena = converted.cena;
131786 + input.index = converted.index;
131787 +
131788 + if (copy_to_user(a, &input, sizeof(input)))
131789 + return -EFAULT;
131790 + return ret;
131791 + }
131792 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131793 + {
131794 + struct usdpaa_ioctl_raw_portal converted;
131795 + struct compat_ioctl_raw_portal input;
131796 + if (copy_from_user(&input, a, sizeof(input)))
131797 + return -EFAULT;
131798 + converted.type = input.type;
131799 + converted.index = input.index;
131800 + converted.cinh = input.cinh;
131801 + converted.cena = input.cena;
131802 + return ioctl_free_raw_portal(fp, ctx, &converted);
131803 + }
131804 +#endif
131805 + default:
131806 + return usdpaa_ioctl(fp, cmd, arg);
131807 + }
131808 + return -EINVAL;
131809 +}
131810 +
131811 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131812 + enum usdpaa_portal_type ptype, unsigned int *irq,
131813 + void **iir_reg)
131814 +{
131815 + /* Walk the list of portals for filp and return the config
131816 + for the portal that matches the hint */
131817 + struct ctx *context;
131818 + struct portal_mapping *portal;
131819 +
131820 + /* First sanitize the filp */
131821 + if (filp->f_op->open != usdpaa_open)
131822 + return -ENODEV;
131823 + context = filp->private_data;
131824 + spin_lock(&context->lock);
131825 + list_for_each_entry(portal, &context->portals, list) {
131826 + if (portal->user.type == ptype &&
131827 + portal->user.addr.cinh == cinh) {
131828 + if (ptype == usdpaa_portal_qman) {
131829 + *irq = portal->qportal->public_cfg.irq;
131830 + *iir_reg = portal->qportal->addr_virt[1] +
131831 + QM_REG_IIR;
131832 + } else {
131833 + *irq = portal->bportal->public_cfg.irq;
131834 + *iir_reg = portal->bportal->addr_virt[1] +
131835 + BM_REG_IIR;
131836 + }
131837 + spin_unlock(&context->lock);
131838 + return 0;
131839 + }
131840 + }
131841 + spin_unlock(&context->lock);
131842 + return -EINVAL;
131843 +}
131844 +
131845 +static const struct file_operations usdpaa_fops = {
131846 + .open = usdpaa_open,
131847 + .release = usdpaa_release,
131848 + .mmap = usdpaa_mmap,
131849 + .get_unmapped_area = usdpaa_get_unmapped_area,
131850 + .unlocked_ioctl = usdpaa_ioctl,
131851 + .compat_ioctl = usdpaa_ioctl_compat
131852 +};
131853 +
131854 +static struct miscdevice usdpaa_miscdev = {
131855 + .name = "fsl-usdpaa",
131856 + .fops = &usdpaa_fops,
131857 + .minor = MISC_DYNAMIC_MINOR,
131858 +};
131859 +
131860 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
131861 + * indicate how much memory (if any) to allocate during early boot. If the
131862 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
131863 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
131864 + * than there are TLB1 entries, fault-handling will occur. */
131865 +
131866 +static __init int usdpaa_mem(char *arg)
131867 +{
131868 + pr_warn("uspdaa_mem argument is depracated\n");
131869 + arg_phys_size = memparse(arg, &arg);
131870 + num_tlb = 1;
131871 + if (*arg == ',') {
131872 + unsigned long ul;
131873 + int err = kstrtoul(arg + 1, 0, &ul);
131874 + if (err < 0) {
131875 + num_tlb = 1;
131876 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
131877 + } else
131878 + num_tlb = (unsigned int)ul;
131879 + }
131880 + return 0;
131881 +}
131882 +early_param("usdpaa_mem", usdpaa_mem);
131883 +
131884 +static int usdpaa_mem_init(struct reserved_mem *rmem)
131885 +{
131886 + phys_start = rmem->base;
131887 + phys_size = rmem->size;
131888 +
131889 + WARN_ON(!(phys_start && phys_size));
131890 +
131891 + return 0;
131892 +}
131893 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
131894 +
131895 +__init int fsl_usdpaa_init_early(void)
131896 +{
131897 + if (!phys_size || !phys_start) {
131898 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
131899 + return 0;
131900 + }
131901 + if (phys_size % PAGE_SIZE) {
131902 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
131903 + phys_size = 0;
131904 + return 0;
131905 + }
131906 + if (arg_phys_size && phys_size != arg_phys_size) {
131907 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
131908 + arg_phys_size, phys_size);
131909 + phys_size = 0;
131910 + return 0;
131911 + }
131912 + pfn_start = phys_start >> PAGE_SHIFT;
131913 + pfn_size = phys_size >> PAGE_SHIFT;
131914 +#ifdef CONFIG_PPC
131915 + first_tlb = current_tlb = tlbcam_index;
131916 + tlbcam_index += num_tlb;
131917 +#endif
131918 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
131919 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
131920 + return 0;
131921 +}
131922 +subsys_initcall(fsl_usdpaa_init_early);
131923 +
131924 +
131925 +static int __init usdpaa_init(void)
131926 +{
131927 + struct mem_fragment *frag;
131928 + int ret;
131929 + u64 tmp_size = phys_size;
131930 + u64 tmp_start = phys_start;
131931 + u64 tmp_pfn_size = pfn_size;
131932 + u64 tmp_pfn_start = pfn_start;
131933 +
131934 + pr_info("Freescale USDPAA process driver\n");
131935 + if (!phys_start) {
131936 + pr_warn("fsl-usdpaa: no region found\n");
131937 + return 0;
131938 + }
131939 +
131940 + while (tmp_size != 0) {
131941 + u32 frag_size = largest_page_size(tmp_size);
131942 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
131943 + if (!frag) {
131944 + pr_err("Failed to setup USDPAA memory accounting\n");
131945 + return -ENOMEM;
131946 + }
131947 + frag->base = tmp_start;
131948 + frag->len = frag->root_len = frag_size;
131949 + frag->root_pfn = tmp_pfn_start;
131950 + frag->pfn_base = tmp_pfn_start;
131951 + frag->pfn_len = frag_size / PAGE_SIZE;
131952 + frag->refs = 0;
131953 + init_waitqueue_head(&frag->wq);
131954 + frag->owner = NULL;
131955 + list_add(&frag->list, &mem_list);
131956 +
131957 + /* Adjust for this frag */
131958 + tmp_start += frag_size;
131959 + tmp_size -= frag_size;
131960 + tmp_pfn_start += frag_size / PAGE_SIZE;
131961 + tmp_pfn_size -= frag_size / PAGE_SIZE;
131962 + }
131963 + ret = misc_register(&usdpaa_miscdev);
131964 + if (ret)
131965 + pr_err("fsl-usdpaa: failed to register misc device\n");
131966 + return ret;
131967 +}
131968 +
131969 +static void __exit usdpaa_exit(void)
131970 +{
131971 + misc_deregister(&usdpaa_miscdev);
131972 +}
131973 +
131974 +module_init(usdpaa_init);
131975 +module_exit(usdpaa_exit);
131976 +
131977 +MODULE_LICENSE("GPL");
131978 +MODULE_AUTHOR("Freescale Semiconductor");
131979 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
131980 diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131981 new file mode 100644
131982 index 00000000..914c7471
131983 --- /dev/null
131984 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131985 @@ -0,0 +1,289 @@
131986 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
131987 + * All rights reserved.
131988 + *
131989 + * Redistribution and use in source and binary forms, with or without
131990 + * modification, are permitted provided that the following conditions are met:
131991 + * * Redistributions of source code must retain the above copyright
131992 + * notice, this list of conditions and the following disclaimer.
131993 + * * Redistributions in binary form must reproduce the above copyright
131994 + * notice, this list of conditions and the following disclaimer in the
131995 + * documentation and/or other materials provided with the distribution.
131996 + * * Neither the name of Freescale Semiconductor nor the
131997 + * names of its contributors may be used to endorse or promote products
131998 + * derived from this software without specific prior written permission.
131999 + *
132000 + *
132001 + * ALTERNATIVELY, this software may be distributed under the terms of the
132002 + * GNU General Public License ("GPL") as published by the Free Software
132003 + * Foundation, either version 2 of that License or (at your option) any
132004 + * later version.
132005 + *
132006 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132007 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132008 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132009 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132010 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132011 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132012 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132013 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132014 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132015 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132016 + */
132017 +
132018 +/* define a device that allows USPDAA processes to open a file
132019 + descriptor and specify which IRQ it wants to montior using an ioctl()
132020 + When an IRQ is received, the device becomes readable so that a process
132021 + can use read() or select() type calls to monitor for IRQs */
132022 +
132023 +#include <linux/miscdevice.h>
132024 +#include <linux/fs.h>
132025 +#include <linux/cdev.h>
132026 +#include <linux/slab.h>
132027 +#include <linux/interrupt.h>
132028 +#include <linux/poll.h>
132029 +#include <linux/uaccess.h>
132030 +#include <linux/fsl_usdpaa.h>
132031 +#include <linux/module.h>
132032 +#include <linux/fdtable.h>
132033 +#include <linux/file.h>
132034 +
132035 +#include "qman_low.h"
132036 +#include "bman_low.h"
132037 +
132038 +struct usdpaa_irq_ctx {
132039 + int irq_set; /* Set to true once the irq is set via ioctl */
132040 + unsigned int irq_num;
132041 + u32 last_irq_count; /* Last value returned from read */
132042 + u32 irq_count; /* Number of irqs since last read */
132043 + wait_queue_head_t wait_queue; /* Waiting processes */
132044 + spinlock_t lock;
132045 + void *inhibit_addr; /* inhibit register address */
132046 + struct file *usdpaa_filp;
132047 + char irq_name[128];
132048 +};
132049 +
132050 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
132051 +{
132052 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
132053 + if (!ctx)
132054 + return -ENOMEM;
132055 + ctx->irq_set = 0;
132056 + ctx->irq_count = 0;
132057 + ctx->last_irq_count = 0;
132058 + init_waitqueue_head(&ctx->wait_queue);
132059 + spin_lock_init(&ctx->lock);
132060 + filp->private_data = ctx;
132061 + return 0;
132062 +}
132063 +
132064 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
132065 +{
132066 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132067 + if (ctx->irq_set) {
132068 + /* Inhibit the IRQ */
132069 + out_be32(ctx->inhibit_addr, 0x1);
132070 + irq_set_affinity_hint(ctx->irq_num, NULL);
132071 + free_irq(ctx->irq_num, ctx);
132072 + ctx->irq_set = 0;
132073 + fput(ctx->usdpaa_filp);
132074 + }
132075 + kfree(filp->private_data);
132076 + return 0;
132077 +}
132078 +
132079 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
132080 +{
132081 + unsigned long flags;
132082 + struct usdpaa_irq_ctx *ctx = _ctx;
132083 + spin_lock_irqsave(&ctx->lock, flags);
132084 + ++ctx->irq_count;
132085 + spin_unlock_irqrestore(&ctx->lock, flags);
132086 + wake_up_all(&ctx->wait_queue);
132087 + /* Set the inhibit register. This will be reenabled
132088 + once the USDPAA code handles the IRQ */
132089 + out_be32(ctx->inhibit_addr, 0x1);
132090 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
132091 + return IRQ_HANDLED;
132092 +}
132093 +
132094 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
132095 +{
132096 + struct usdpaa_irq_ctx *ctx = fp->private_data;
132097 + int ret;
132098 +
132099 + if (ctx->irq_set) {
132100 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
132101 + return -EBUSY;
132102 + }
132103 +
132104 + ctx->usdpaa_filp = fget(irq_map->fd);
132105 + if (!ctx->usdpaa_filp) {
132106 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
132107 + return -EINVAL;
132108 + }
132109 +
132110 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
132111 + irq_map->type, &ctx->irq_num,
132112 + &ctx->inhibit_addr);
132113 + if (ret) {
132114 + pr_debug("USDPAA IRQ couldn't identify portal\n");
132115 + fput(ctx->usdpaa_filp);
132116 + return ret;
132117 + }
132118 +
132119 + ctx->irq_set = 1;
132120 +
132121 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
132122 + "usdpaa_irq %d", ctx->irq_num);
132123 +
132124 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
132125 + ctx->irq_name, ctx);
132126 + if (ret) {
132127 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
132128 + ctx->irq_num, ret);
132129 + ctx->irq_set = 0;
132130 + fput(ctx->usdpaa_filp);
132131 + return ret;
132132 + }
132133 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
132134 + if (ret)
132135 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
132136 +
132137 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
132138 + if (ret)
132139 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
132140 +
132141 + return 0;
132142 +}
132143 +
132144 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
132145 + unsigned long arg)
132146 +{
132147 + int ret;
132148 + struct usdpaa_ioctl_irq_map irq_map;
132149 +
132150 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
132151 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
132152 + return -EINVAL;
132153 + }
132154 +
132155 + ret = copy_from_user(&irq_map, (void __user *)arg,
132156 + sizeof(irq_map));
132157 + if (ret)
132158 + return ret;
132159 + return map_irq(fp, &irq_map);
132160 +}
132161 +
132162 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
132163 + size_t count, loff_t *offp)
132164 +{
132165 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132166 + int ret;
132167 +
132168 + if (!ctx->irq_set) {
132169 + pr_debug("Reading USDPAA IRQ before it was set\n");
132170 + return -EINVAL;
132171 + }
132172 +
132173 + if (count < sizeof(ctx->irq_count)) {
132174 + pr_debug("USDPAA IRQ Read too small\n");
132175 + return -EINVAL;
132176 + }
132177 + if (ctx->irq_count == ctx->last_irq_count) {
132178 + if (filp->f_flags & O_NONBLOCK)
132179 + return -EAGAIN;
132180 +
132181 + ret = wait_event_interruptible(ctx->wait_queue,
132182 + ctx->irq_count != ctx->last_irq_count);
132183 + if (ret == -ERESTARTSYS)
132184 + return ret;
132185 + }
132186 +
132187 + ctx->last_irq_count = ctx->irq_count;
132188 +
132189 + if (copy_to_user(buff, &ctx->last_irq_count,
132190 + sizeof(ctx->last_irq_count)))
132191 + return -EFAULT;
132192 + return sizeof(ctx->irq_count);
132193 +}
132194 +
132195 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
132196 +{
132197 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132198 + unsigned int ret = 0;
132199 + unsigned long flags;
132200 +
132201 + if (!ctx->irq_set)
132202 + return POLLHUP;
132203 +
132204 + poll_wait(filp, &ctx->wait_queue, wait);
132205 +
132206 + spin_lock_irqsave(&ctx->lock, flags);
132207 + if (ctx->irq_count != ctx->last_irq_count)
132208 + ret |= POLLIN | POLLRDNORM;
132209 + spin_unlock_irqrestore(&ctx->lock, flags);
132210 + return ret;
132211 +}
132212 +
132213 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
132214 + unsigned long arg)
132215 +{
132216 +#ifdef CONFIG_COMPAT
132217 + void __user *a = (void __user *)arg;
132218 +#endif
132219 + switch (cmd) {
132220 +#ifdef CONFIG_COMPAT
132221 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
132222 + {
132223 + struct compat_ioctl_irq_map input;
132224 + struct usdpaa_ioctl_irq_map converted;
132225 + if (copy_from_user(&input, a, sizeof(input)))
132226 + return -EFAULT;
132227 + converted.type = input.type;
132228 + converted.fd = input.fd;
132229 + converted.portal_cinh = compat_ptr(input.portal_cinh);
132230 + return map_irq(fp, &converted);
132231 + }
132232 +#endif
132233 + default:
132234 + return usdpaa_irq_ioctl(fp, cmd, arg);
132235 + }
132236 +}
132237 +
132238 +static const struct file_operations usdpaa_irq_fops = {
132239 + .open = usdpaa_irq_open,
132240 + .release = usdpaa_irq_release,
132241 + .unlocked_ioctl = usdpaa_irq_ioctl,
132242 + .compat_ioctl = usdpaa_irq_ioctl_compat,
132243 + .read = usdpaa_irq_read,
132244 + .poll = usdpaa_irq_poll
132245 +};
132246 +
132247 +static struct miscdevice usdpaa_miscdev = {
132248 + .name = "fsl-usdpaa-irq",
132249 + .fops = &usdpaa_irq_fops,
132250 + .minor = MISC_DYNAMIC_MINOR,
132251 +};
132252 +
132253 +static int __init usdpaa_irq_init(void)
132254 +{
132255 + int ret;
132256 +
132257 + pr_info("Freescale USDPAA process IRQ driver\n");
132258 + ret = misc_register(&usdpaa_miscdev);
132259 + if (ret)
132260 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
132261 + return ret;
132262 +}
132263 +
132264 +static void __exit usdpaa_irq_exit(void)
132265 +{
132266 + misc_deregister(&usdpaa_miscdev);
132267 +}
132268 +
132269 +module_init(usdpaa_irq_init);
132270 +module_exit(usdpaa_irq_exit);
132271 +
132272 +MODULE_LICENSE("GPL");
132273 +MODULE_AUTHOR("Freescale Semiconductor");
132274 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
132275 diff --git a/drivers/staging/fsl_qbman/qbman_driver.c b/drivers/staging/fsl_qbman/qbman_driver.c
132276 new file mode 100644
132277 index 00000000..ab487d5f
132278 --- /dev/null
132279 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
132280 @@ -0,0 +1,88 @@
132281 +/* Copyright 2013 Freescale Semiconductor, Inc.
132282 + *
132283 + * Redistribution and use in source and binary forms, with or without
132284 + * modification, are permitted provided that the following conditions are met:
132285 + * * Redistributions of source code must retain the above copyright
132286 + * notice, this list of conditions and the following disclaimer.
132287 + * * Redistributions in binary form must reproduce the above copyright
132288 + * notice, this list of conditions and the following disclaimer in the
132289 + * documentation and/or other materials provided with the distribution.
132290 + * * Neither the name of Freescale Semiconductor nor the
132291 + * names of its contributors may be used to endorse or promote products
132292 + * derived from this software without specific prior written permission.
132293 + *
132294 + *
132295 + * ALTERNATIVELY, this software may be distributed under the terms of the
132296 + * GNU General Public License ("GPL") as published by the Free Software
132297 + * Foundation, either version 2 of that License or (at your option) any
132298 + * later version.
132299 + *
132300 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132301 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132302 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132303 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132304 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132305 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132306 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132307 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132308 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132309 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132310 + */
132311 +
132312 +#include <linux/time.h>
132313 +#include "qman_private.h"
132314 +#include "bman_private.h"
132315 +__init void qman_init_early(void);
132316 +__init void bman_init_early(void);
132317 +
132318 +static __init int qbman_init(void)
132319 +{
132320 + struct device_node *dn;
132321 + u32 is_portal_available;
132322 +
132323 + bman_init();
132324 + qman_init();
132325 +
132326 + is_portal_available = 0;
132327 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
132328 + if (!of_device_is_available(dn))
132329 + continue;
132330 + else
132331 + is_portal_available = 1;
132332 + }
132333 +
132334 + if (!qman_have_ccsr() && is_portal_available) {
132335 + struct qman_fq fq = {
132336 + .fqid = 1
132337 + };
132338 + struct qm_mcr_queryfq_np np;
132339 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
132340 + struct timespec nowts, diffts, startts = current_kernel_time();
132341 + /* Loop while querying given fqid succeeds or time out */
132342 + while (1) {
132343 + err = qman_query_fq_np(&fq, &np);
132344 + if (!err) {
132345 + /* success, control-plane has configured QMan */
132346 + break;
132347 + } else if (err != -ERANGE) {
132348 + pr_err("QMan: I/O error, continuing anyway\n");
132349 + break;
132350 + }
132351 + nowts = current_kernel_time();
132352 + diffts = timespec_sub(nowts, startts);
132353 + if (diffts.tv_sec > 0) {
132354 + if (!retry--) {
132355 + pr_err("QMan: time out, control-plane"
132356 + " dead?\n");
132357 + break;
132358 + }
132359 + pr_warn("QMan: polling for the control-plane"
132360 + " (%d)\n", retry);
132361 + }
132362 + }
132363 + }
132364 + bman_resource_init();
132365 + qman_resource_init();
132366 + return 0;
132367 +}
132368 +subsys_initcall(qbman_init);
132369 diff --git a/drivers/staging/fsl_qbman/qman_config.c b/drivers/staging/fsl_qbman/qman_config.c
132370 new file mode 100644
132371 index 00000000..9bb1e11a
132372 --- /dev/null
132373 +++ b/drivers/staging/fsl_qbman/qman_config.c
132374 @@ -0,0 +1,1224 @@
132375 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
132376 + *
132377 + * Redistribution and use in source and binary forms, with or without
132378 + * modification, are permitted provided that the following conditions are met:
132379 + * * Redistributions of source code must retain the above copyright
132380 + * notice, this list of conditions and the following disclaimer.
132381 + * * Redistributions in binary form must reproduce the above copyright
132382 + * notice, this list of conditions and the following disclaimer in the
132383 + * documentation and/or other materials provided with the distribution.
132384 + * * Neither the name of Freescale Semiconductor nor the
132385 + * names of its contributors may be used to endorse or promote products
132386 + * derived from this software without specific prior written permission.
132387 + *
132388 + *
132389 + * ALTERNATIVELY, this software may be distributed under the terms of the
132390 + * GNU General Public License ("GPL") as published by the Free Software
132391 + * Foundation, either version 2 of that License or (at your option) any
132392 + * later version.
132393 + *
132394 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132395 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132396 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132397 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132398 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132399 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132400 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132401 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132402 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132403 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132404 + */
132405 +
132406 +#include <asm/cacheflush.h>
132407 +#include "qman_private.h"
132408 +#include <linux/highmem.h>
132409 +#include <linux/of_reserved_mem.h>
132410 +
132411 +/* Last updated for v00.800 of the BG */
132412 +
132413 +/* Register offsets */
132414 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
132415 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
132416 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
132417 +#define REG_DD_CFG 0x0200
132418 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
132419 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
132420 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
132421 +#define REG_PFDR_FPC 0x0400
132422 +#define REG_PFDR_FP_HEAD 0x0404
132423 +#define REG_PFDR_FP_TAIL 0x0408
132424 +#define REG_PFDR_FP_LWIT 0x0410
132425 +#define REG_PFDR_CFG 0x0414
132426 +#define REG_SFDR_CFG 0x0500
132427 +#define REG_SFDR_IN_USE 0x0504
132428 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
132429 +#define REG_WQ_DEF_ENC_WQID 0x0630
132430 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
132431 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
132432 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
132433 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
132434 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
132435 +#define REG_CM_CFG 0x0800
132436 +#define REG_ECSR 0x0a00
132437 +#define REG_ECIR 0x0a04
132438 +#define REG_EADR 0x0a08
132439 +#define REG_ECIR2 0x0a0c
132440 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
132441 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
132442 +#define REG_MCR 0x0b00
132443 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
132444 +#define REG_MISC_CFG 0x0be0
132445 +#define REG_HID_CFG 0x0bf0
132446 +#define REG_IDLE_STAT 0x0bf4
132447 +#define REG_IP_REV_1 0x0bf8
132448 +#define REG_IP_REV_2 0x0bfc
132449 +#define REG_FQD_BARE 0x0c00
132450 +#define REG_PFDR_BARE 0x0c20
132451 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
132452 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
132453 +#define REG_QCSP_BARE 0x0c80
132454 +#define REG_QCSP_BAR 0x0c84
132455 +#define REG_CI_SCHED_CFG 0x0d00
132456 +#define REG_SRCIDR 0x0d04
132457 +#define REG_LIODNR 0x0d08
132458 +#define REG_CI_RLM_AVG 0x0d14
132459 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
132460 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
132461 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
132462 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
132463 +#define REG_CEETM_CFG_IDX 0x900
132464 +#define REG_CEETM_CFG_PRES 0x904
132465 +#define REG_CEETM_XSFDR_IN_USE 0x908
132466 +
132467 +/* Assists for QMAN_MCR */
132468 +#define MCR_INIT_PFDR 0x01000000
132469 +#define MCR_get_rslt(v) (u8)((v) >> 24)
132470 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
132471 +#define MCR_rslt_ok(r) (rslt == 0xf0)
132472 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
132473 +#define MCR_rslt_inval(r) (rslt == 0xff)
132474 +
132475 +struct qman;
132476 +
132477 +/* Follows WQ_CS_CFG0-5 */
132478 +enum qm_wq_class {
132479 + qm_wq_portal = 0,
132480 + qm_wq_pool = 1,
132481 + qm_wq_fman0 = 2,
132482 + qm_wq_fman1 = 3,
132483 + qm_wq_caam = 4,
132484 + qm_wq_pme = 5,
132485 + qm_wq_first = qm_wq_portal,
132486 + qm_wq_last = qm_wq_pme
132487 +};
132488 +
132489 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
132490 +enum qm_memory {
132491 + qm_memory_fqd,
132492 + qm_memory_pfdr
132493 +};
132494 +
132495 +/* Used by all error interrupt registers except 'inhibit' */
132496 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
132497 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
132498 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
132499 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
132500 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
132501 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
132502 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
132503 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
132504 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
132505 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
132506 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
132507 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
132508 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
132509 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
132510 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
132511 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
132512 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
132513 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
132514 +
132515 +/* QMAN_ECIR valid error bit */
132516 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
132517 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
132518 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
132519 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
132520 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
132521 + QM_EIRQ_IFSI)
132522 +
132523 +union qman_ecir {
132524 + u32 ecir_raw;
132525 + struct {
132526 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132527 + u32 __reserved:2;
132528 + u32 portal_type:1;
132529 + u32 portal_num:5;
132530 + u32 fqid:24;
132531 +#else
132532 + u32 fqid:24;
132533 + u32 portal_num:5;
132534 + u32 portal_type:1;
132535 + u32 __reserved:2;
132536 +#endif
132537 + } __packed info;
132538 +};
132539 +
132540 +union qman_ecir2 {
132541 + u32 ecir2_raw;
132542 + struct {
132543 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132544 + u32 portal_type:1;
132545 + u32 __reserved:21;
132546 + u32 portal_num:10;
132547 +#else
132548 + u32 portal_num:10;
132549 + u32 __reserved:21;
132550 + u32 portal_type:1;
132551 +#endif
132552 + } __packed info;
132553 +};
132554 +
132555 +union qman_eadr {
132556 + u32 eadr_raw;
132557 + struct {
132558 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132559 + u32 __reserved1:4;
132560 + u32 memid:4;
132561 + u32 __reserved2:12;
132562 + u32 eadr:12;
132563 +#else
132564 + u32 eadr:12;
132565 + u32 __reserved2:12;
132566 + u32 memid:4;
132567 + u32 __reserved1:4;
132568 +#endif
132569 + } __packed info;
132570 + struct {
132571 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132572 + u32 __reserved1:3;
132573 + u32 memid:5;
132574 + u32 __reserved:8;
132575 + u32 eadr:16;
132576 +#else
132577 + u32 eadr:16;
132578 + u32 __reserved:8;
132579 + u32 memid:5;
132580 + u32 __reserved1:3;
132581 +#endif
132582 + } __packed info_rev3;
132583 +};
132584 +
132585 +struct qman_hwerr_txt {
132586 + u32 mask;
132587 + const char *txt;
132588 +};
132589 +
132590 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
132591 +
132592 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
132593 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
132594 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
132595 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
132596 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
132597 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
132598 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
132599 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
132600 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
132601 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
132602 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
132603 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
132604 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
132605 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
132606 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
132607 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
132608 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
132609 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
132610 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
132611 +};
132612 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
132613 +
132614 +struct qman_error_info_mdata {
132615 + u16 addr_mask;
132616 + u16 bits;
132617 + const char *txt;
132618 +};
132619 +
132620 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
132621 +static const struct qman_error_info_mdata error_mdata[] = {
132622 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
132623 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
132624 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
132625 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
132626 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
132627 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
132628 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
132629 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
132630 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
132631 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
132632 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
132633 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
132634 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
132635 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
132636 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
132637 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
132638 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
132639 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
132640 +};
132641 +#define QMAN_ERR_MDATA_COUNT \
132642 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
132643 +
132644 +/* Add this in Kconfig */
132645 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
132646 +
132647 +/**
132648 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
132649 + * @v: for accessors that write values, this is the 32-bit value
132650 + *
132651 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
132652 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
132653 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
132654 + * "write the enable register" rather than "enable the write register"!
132655 + */
132656 +#define qm_err_isr_status_read(qm) \
132657 + __qm_err_isr_read(qm, qm_isr_status)
132658 +#define qm_err_isr_status_clear(qm, m) \
132659 + __qm_err_isr_write(qm, qm_isr_status, m)
132660 +#define qm_err_isr_enable_read(qm) \
132661 + __qm_err_isr_read(qm, qm_isr_enable)
132662 +#define qm_err_isr_enable_write(qm, v) \
132663 + __qm_err_isr_write(qm, qm_isr_enable, v)
132664 +#define qm_err_isr_disable_read(qm) \
132665 + __qm_err_isr_read(qm, qm_isr_disable)
132666 +#define qm_err_isr_disable_write(qm, v) \
132667 + __qm_err_isr_write(qm, qm_isr_disable, v)
132668 +#define qm_err_isr_inhibit(qm) \
132669 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
132670 +#define qm_err_isr_uninhibit(qm) \
132671 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
132672 +
132673 +/*
132674 + * TODO: unimplemented registers
132675 + *
132676 + * Keeping a list here of Qman registers I have not yet covered;
132677 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
132678 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
132679 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
132680 + */
132681 +
132682 +/* Encapsulate "struct qman *" as a cast of the register space address. */
132683 +
132684 +static struct qman *qm_create(void *regs)
132685 +{
132686 + return (struct qman *)regs;
132687 +}
132688 +
132689 +static inline u32 __qm_in(struct qman *qm, u32 offset)
132690 +{
132691 + return in_be32((void *)qm + offset);
132692 +}
132693 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
132694 +{
132695 + out_be32((void *)qm + offset, val);
132696 +}
132697 +#define qm_in(reg) __qm_in(qm, REG_##reg)
132698 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
132699 +
132700 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
132701 +{
132702 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132703 +}
132704 +
132705 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132706 +{
132707 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132708 +}
132709 +
132710 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132711 + int ed, u8 sernd)
132712 +{
132713 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132714 + (portal == qm_dc_portal_fman1));
132715 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132716 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132717 + else
132718 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132719 +}
132720 +
132721 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132722 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132723 + u8 csw6, u8 csw7)
132724 +{
132725 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132726 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132727 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132728 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132729 +}
132730 +
132731 +static void qm_set_hid(struct qman *qm)
132732 +{
132733 + qm_out(HID_CFG, 0);
132734 +}
132735 +
132736 +static void qm_set_corenet_initiator(struct qman *qm)
132737 +{
132738 + qm_out(CI_SCHED_CFG,
132739 + 0x80000000 | /* write srcciv enable */
132740 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132741 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132742 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132743 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132744 +}
132745 +
132746 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132747 + u8 *cfg)
132748 +{
132749 + u32 v = qm_in(IP_REV_1);
132750 + u32 v2 = qm_in(IP_REV_2);
132751 + *id = (v >> 16);
132752 + *major = (v >> 8) & 0xff;
132753 + *minor = v & 0xff;
132754 + *cfg = v2 & 0xff;
132755 +}
132756 +
132757 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132758 + int enable, int prio, int stash, u32 size)
132759 +{
132760 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132761 + u32 exp = ilog2(size);
132762 + /* choke if size isn't within range */
132763 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132764 + is_power_of_2(size));
132765 + /* choke if 'ba' has lower-alignment than 'size' */
132766 + DPA_ASSERT(!(ba & (size - 1)));
132767 + __qm_out(qm, offset, upper_32_bits(ba));
132768 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132769 + __qm_out(qm, offset + REG_offset_AR,
132770 + (enable ? 0x80000000 : 0) |
132771 + (prio ? 0x40000000 : 0) |
132772 + (stash ? 0x20000000 : 0) |
132773 + (exp - 1));
132774 +}
132775 +
132776 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132777 +{
132778 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132779 + qm_out(PFDR_CFG, k);
132780 +}
132781 +
132782 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132783 +{
132784 + qm_out(SFDR_CFG, th & 0x3ff);
132785 +}
132786 +
132787 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132788 +{
132789 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132790 +
132791 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132792 + /* Make sure the command interface is 'idle' */
132793 + if (!MCR_rslt_idle(rslt))
132794 + panic("QMAN_MCR isn't idle");
132795 +
132796 + /* Write the MCR command params then the verb */
132797 + qm_out(MCP(0), pfdr_start);
132798 + /* TODO: remove this - it's a workaround for a model bug that is
132799 + * corrected in more recent versions. We use the workaround until
132800 + * everyone has upgraded. */
132801 + qm_out(MCP(1), (pfdr_start + num - 16));
132802 + lwsync();
132803 + qm_out(MCR, MCR_INIT_PFDR);
132804 + /* Poll for the result */
132805 + do {
132806 + rslt = MCR_get_rslt(qm_in(MCR));
132807 + } while (!MCR_rslt_idle(rslt));
132808 + if (MCR_rslt_ok(rslt))
132809 + return 0;
132810 + if (MCR_rslt_eaccess(rslt))
132811 + return -EACCES;
132812 + if (MCR_rslt_inval(rslt))
132813 + return -EINVAL;
132814 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
132815 + return -ENOSYS;
132816 +}
132817 +
132818 +/*****************/
132819 +/* Config driver */
132820 +/*****************/
132821 +
132822 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
132823 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
132824 +
132825 +/* We support only one of these */
132826 +static struct qman *qm;
132827 +static struct device_node *qm_node;
132828 +
132829 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
132830 + * during qman_init_ccsr(). */
132831 +static dma_addr_t fqd_a, pfdr_a;
132832 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
132833 +
132834 +static int qman_fqd(struct reserved_mem *rmem)
132835 +{
132836 + fqd_a = rmem->base;
132837 + fqd_sz = rmem->size;
132838 +
132839 + WARN_ON(!(fqd_a && fqd_sz));
132840 +
132841 + return 0;
132842 +}
132843 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
132844 +
132845 +static int qman_pfdr(struct reserved_mem *rmem)
132846 +{
132847 + pfdr_a = rmem->base;
132848 + pfdr_sz = rmem->size;
132849 +
132850 + WARN_ON(!(pfdr_a && pfdr_sz));
132851 +
132852 + return 0;
132853 +}
132854 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
132855 +
132856 +size_t get_qman_fqd_size()
132857 +{
132858 + return fqd_sz;
132859 +}
132860 +
132861 +/* Parse the <name> property to extract the memory location and size and
132862 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
132863 + * size. Also flush this memory range from data cache so that QMAN originated
132864 + * transactions for this memory region could be marked non-coherent.
132865 + */
132866 +static __init int parse_mem_property(struct device_node *node, const char *name,
132867 + dma_addr_t *addr, size_t *sz, int zero)
132868 +{
132869 + int ret;
132870 +
132871 + /* If using a "zero-pma", don't try to zero it, even if you asked */
132872 + if (zero && of_find_property(node, "zero-pma", &ret)) {
132873 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
132874 + zero = 0;
132875 + }
132876 +
132877 + if (zero) {
132878 + /* map as cacheable, non-guarded */
132879 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132880 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
132881 +#else
132882 + void __iomem *tmpp = ioremap(*addr, *sz);
132883 +#endif
132884 +
132885 + if (!tmpp)
132886 + return -ENOMEM;
132887 + memset_io(tmpp, 0, *sz);
132888 + flush_dcache_range((unsigned long)tmpp,
132889 + (unsigned long)tmpp + *sz);
132890 + iounmap(tmpp);
132891 + }
132892 +
132893 + return 0;
132894 +}
132895 +
132896 +/* TODO:
132897 + * - there is obviously no handling of errors,
132898 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
132899 + * both memory resources to zero.
132900 + */
132901 +static int __init fsl_qman_init(struct device_node *node)
132902 +{
132903 + struct resource res;
132904 + resource_size_t len;
132905 + u32 __iomem *regs;
132906 + const char *s;
132907 + int ret, standby = 0;
132908 + u16 id;
132909 + u8 major, minor, cfg;
132910 + ret = of_address_to_resource(node, 0, &res);
132911 + if (ret) {
132912 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
132913 + return ret;
132914 + }
132915 + s = of_get_property(node, "fsl,hv-claimable", &ret);
132916 + if (s && !strcmp(s, "standby"))
132917 + standby = 1;
132918 + if (!standby) {
132919 + ret = parse_mem_property(node, "fsl,qman-fqd",
132920 + &fqd_a, &fqd_sz, 1);
132921 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
132922 + BUG_ON(ret);
132923 + ret = parse_mem_property(node, "fsl,qman-pfdr",
132924 + &pfdr_a, &pfdr_sz, 0);
132925 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
132926 + BUG_ON(ret);
132927 + }
132928 + /* Global configuration */
132929 + len = resource_size(&res);
132930 + if (len != (unsigned long)len)
132931 + return -EINVAL;
132932 + regs = ioremap(res.start, (unsigned long)len);
132933 + qm = qm_create(regs);
132934 + qm_node = node;
132935 + qm_get_version(qm, &id, &major, &minor, &cfg);
132936 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
132937 + if (!qman_ip_rev) {
132938 + if ((major == 1) && (minor == 0)) {
132939 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
132940 + iounmap(regs);
132941 + return -ENODEV;
132942 + } else if ((major == 1) && (minor == 1))
132943 + qman_ip_rev = QMAN_REV11;
132944 + else if ((major == 1) && (minor == 2))
132945 + qman_ip_rev = QMAN_REV12;
132946 + else if ((major == 2) && (minor == 0))
132947 + qman_ip_rev = QMAN_REV20;
132948 + else if ((major == 3) && (minor == 0))
132949 + qman_ip_rev = QMAN_REV30;
132950 + else if ((major == 3) && (minor == 1))
132951 + qman_ip_rev = QMAN_REV31;
132952 + else if ((major == 3) && (minor == 2))
132953 + qman_ip_rev = QMAN_REV32;
132954 + else {
132955 + pr_warn("unknown Qman version, default to rev1.1\n");
132956 + qman_ip_rev = QMAN_REV11;
132957 + }
132958 + qman_ip_cfg = cfg;
132959 + }
132960 +
132961 + if (standby) {
132962 + pr_info(" -> in standby mode\n");
132963 + return 0;
132964 + }
132965 + return 0;
132966 +}
132967 +
132968 +int qman_have_ccsr(void)
132969 +{
132970 + return qm ? 1 : 0;
132971 +}
132972 +
132973 +__init int qman_init_early(void)
132974 +{
132975 + struct device_node *dn;
132976 + int ret;
132977 +
132978 + for_each_compatible_node(dn, NULL, "fsl,qman") {
132979 + if (qm)
132980 + pr_err("%s: only one 'fsl,qman' allowed\n",
132981 + dn->full_name);
132982 + else {
132983 + if (!of_device_is_available(dn))
132984 + continue;
132985 +
132986 + ret = fsl_qman_init(dn);
132987 + BUG_ON(ret);
132988 + }
132989 + }
132990 + return 0;
132991 +}
132992 +postcore_initcall_sync(qman_init_early);
132993 +
132994 +static void log_edata_bits(u32 bit_count)
132995 +{
132996 + u32 i, j, mask = 0xffffffff;
132997 +
132998 + pr_warn("Qman ErrInt, EDATA:\n");
132999 + i = bit_count/32;
133000 + if (bit_count%32) {
133001 + i++;
133002 + mask = ~(mask << bit_count%32);
133003 + }
133004 + j = 16-i;
133005 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
133006 + j++;
133007 + for (; j < 16; j++)
133008 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
133009 +}
133010 +
133011 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
133012 +{
133013 + union qman_ecir ecir_val;
133014 + union qman_eadr eadr_val;
133015 +
133016 + ecir_val.ecir_raw = qm_in(ECIR);
133017 + /* Is portal info valid */
133018 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133019 + union qman_ecir2 ecir2_val;
133020 + ecir2_val.ecir2_raw = qm_in(ECIR2);
133021 + if (ecsr_val & PORTAL_ECSR_ERR) {
133022 + pr_warn("Qman ErrInt: %s id %d\n",
133023 + (ecir2_val.info.portal_type) ?
133024 + "DCP" : "SWP", ecir2_val.info.portal_num);
133025 + }
133026 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
133027 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
133028 + ecir_val.info.fqid);
133029 + }
133030 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
133031 + eadr_val.eadr_raw = qm_in(EADR);
133032 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
133033 + error_mdata[eadr_val.info_rev3.memid].txt,
133034 + error_mdata[eadr_val.info_rev3.memid].addr_mask
133035 + & eadr_val.info_rev3.eadr);
133036 + log_edata_bits(
133037 + error_mdata[eadr_val.info_rev3.memid].bits);
133038 + }
133039 + } else {
133040 + if (ecsr_val & PORTAL_ECSR_ERR) {
133041 + pr_warn("Qman ErrInt: %s id %d\n",
133042 + (ecir_val.info.portal_type) ?
133043 + "DCP" : "SWP", ecir_val.info.portal_num);
133044 + }
133045 + if (ecsr_val & FQID_ECSR_ERR) {
133046 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
133047 + ecir_val.info.fqid);
133048 + }
133049 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
133050 + eadr_val.eadr_raw = qm_in(EADR);
133051 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
133052 + error_mdata[eadr_val.info.memid].txt,
133053 + error_mdata[eadr_val.info.memid].addr_mask
133054 + & eadr_val.info.eadr);
133055 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
133056 + }
133057 + }
133058 +}
133059 +
133060 +/* Qman interrupt handler */
133061 +static irqreturn_t qman_isr(int irq, void *ptr)
133062 +{
133063 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
133064 +
133065 + ier_val = qm_err_isr_enable_read(qm);
133066 + isr_val = qm_err_isr_status_read(qm);
133067 + ecsr_val = qm_in(ECSR);
133068 + isr_mask = isr_val & ier_val;
133069 +
133070 + if (!isr_mask)
133071 + return IRQ_NONE;
133072 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
133073 + if (qman_hwerr_txts[i].mask & isr_mask) {
133074 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
133075 + if (qman_hwerr_txts[i].mask & ecsr_val) {
133076 + log_additional_error_info(isr_mask, ecsr_val);
133077 + /* Re-arm error capture registers */
133078 + qm_out(ECSR, ecsr_val);
133079 + }
133080 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
133081 + pr_devel("Qman un-enabling error 0x%x\n",
133082 + qman_hwerr_txts[i].mask);
133083 + ier_val &= ~qman_hwerr_txts[i].mask;
133084 + qm_err_isr_enable_write(qm, ier_val);
133085 + }
133086 + }
133087 + }
133088 + qm_err_isr_status_clear(qm, isr_val);
133089 + return IRQ_HANDLED;
133090 +}
133091 +
133092 +static int __bind_irq(void)
133093 +{
133094 + int ret, err_irq;
133095 +
133096 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
133097 + if (err_irq == 0) {
133098 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
133099 + "interrupts");
133100 + return -ENODEV;
133101 + }
133102 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
133103 + if (ret) {
133104 + pr_err("request_irq() failed %d for '%s'\n", ret,
133105 + qm_node->full_name);
133106 + return -ENODEV;
133107 + }
133108 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
133109 + * to resource allocation during driver init). */
133110 + qm_err_isr_status_clear(qm, 0xffffffff);
133111 + /* Enable Error Interrupts */
133112 + qm_err_isr_enable_write(qm, 0xffffffff);
133113 + return 0;
133114 +}
133115 +
133116 +int qman_init_ccsr(struct device_node *node)
133117 +{
133118 + int ret;
133119 + if (!qman_have_ccsr())
133120 + return 0;
133121 + if (node != qm_node)
133122 + return -EINVAL;
133123 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
133124 + /* TEMP for LS1043 : should be done in uboot */
133125 + qm_out(QCSP_BARE, 0x5);
133126 + qm_out(QCSP_BAR, 0x0);
133127 +#endif
133128 + /* FQD memory */
133129 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
133130 + /* PFDR memory */
133131 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
133132 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
133133 + /* thresholds */
133134 + qm_set_pfdr_threshold(qm, 512, 64);
133135 + qm_set_sfdr_threshold(qm, 128);
133136 + /* clear stale PEBI bit from interrupt status register */
133137 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
133138 + /* corenet initiator settings */
133139 + qm_set_corenet_initiator(qm);
133140 + /* HID settings */
133141 + qm_set_hid(qm);
133142 + /* Set scheduling weights to defaults */
133143 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
133144 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
133145 + /* We are not prepared to accept ERNs for hardware enqueues */
133146 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
133147 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
133148 + /* Initialise Error Interrupt Handler */
133149 + ret = __bind_irq();
133150 + if (ret)
133151 + return ret;
133152 + return 0;
133153 +}
133154 +
133155 +#define LIO_CFG_LIODN_MASK 0x0fff0000
133156 +void qman_liodn_fixup(u16 channel)
133157 +{
133158 + static int done;
133159 + static u32 liodn_offset;
133160 + u32 before, after;
133161 + int idx = channel - QM_CHANNEL_SWPORTAL0;
133162 +
133163 + if (!qman_have_ccsr())
133164 + return;
133165 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
133166 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
133167 + else
133168 + before = qm_in(QCSP_LIO_CFG(idx));
133169 + if (!done) {
133170 + liodn_offset = before & LIO_CFG_LIODN_MASK;
133171 + done = 1;
133172 + return;
133173 + }
133174 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
133175 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
133176 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
133177 + else
133178 + qm_out(QCSP_LIO_CFG(idx), after);
133179 +}
133180 +
133181 +#define IO_CFG_SDEST_MASK 0x00ff0000
133182 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
133183 +{
133184 + int idx = channel - QM_CHANNEL_SWPORTAL0;
133185 + u32 before, after;
133186 +
133187 + if (!qman_have_ccsr())
133188 + return -ENODEV;
133189 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
133190 + /* LS1043A - only one L2 cache */
133191 + cpu_idx = 0;
133192 + }
133193 +
133194 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133195 + before = qm_in(REV3_QCSP_IO_CFG(idx));
133196 + /* Each pair of vcpu share the same SRQ(SDEST) */
133197 + cpu_idx /= 2;
133198 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
133199 + qm_out(REV3_QCSP_IO_CFG(idx), after);
133200 + } else {
133201 + before = qm_in(QCSP_IO_CFG(idx));
133202 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
133203 + qm_out(QCSP_IO_CFG(idx), after);
133204 + }
133205 + return 0;
133206 +}
133207 +
133208 +#define MISC_CFG_WPM_MASK 0x00000002
133209 +int qm_set_wpm(int wpm)
133210 +{
133211 + u32 before;
133212 + u32 after;
133213 +
133214 + if (!qman_have_ccsr())
133215 + return -ENODEV;
133216 +
133217 + before = qm_in(MISC_CFG);
133218 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
133219 + qm_out(MISC_CFG, after);
133220 + return 0;
133221 +}
133222 +
133223 +int qm_get_wpm(int *wpm)
133224 +{
133225 + u32 before;
133226 +
133227 + if (!qman_have_ccsr())
133228 + return -ENODEV;
133229 +
133230 + before = qm_in(MISC_CFG);
133231 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
133232 + return 0;
133233 +}
133234 +
133235 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
133236 + * PRES = (2^22 / credit update reference period) * QMan clock period
133237 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
133238 + */
133239 +
133240 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
133241 +{
133242 + u64 temp;
133243 + u16 pres;
133244 +
133245 + if (!qman_have_ccsr())
133246 + return -ENODEV;
133247 +
133248 + temp = 0x400000 * 100;
133249 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
133250 + temp *= 10000000;
133251 + do_div(temp, qman_clk);
133252 + pres = (u16) temp;
133253 + qm_out(CEETM_CFG_IDX, portal);
133254 + qm_out(CEETM_CFG_PRES, pres);
133255 + return 0;
133256 +}
133257 +
133258 +int qman_ceetm_get_prescaler(u16 *pres)
133259 +{
133260 + if (!qman_have_ccsr())
133261 + return -ENODEV;
133262 + *pres = (u16)qm_in(CEETM_CFG_PRES);
133263 + return 0;
133264 +}
133265 +
133266 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
133267 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
133268 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133269 +{
133270 + u32 dcp_cfg;
133271 +
133272 + if (!qman_have_ccsr())
133273 + return -ENODEV;
133274 +
133275 + dcp_cfg = qm_in(DCP_CFG(portal));
133276 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
133277 + qm_out(DCP_CFG(portal), dcp_cfg);
133278 + return 0;
133279 +}
133280 +
133281 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133282 +{
133283 + u32 dcp_cfg;
133284 +
133285 + if (!qman_have_ccsr())
133286 + return -ENODEV;
133287 + dcp_cfg = qm_in(DCP_CFG(portal));
133288 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
133289 + qm_out(DCP_CFG(portal), dcp_cfg);
133290 + return 0;
133291 +}
133292 +
133293 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
133294 +{
133295 + if (!qman_have_ccsr())
133296 + return -ENODEV;
133297 + *num = qm_in(CEETM_XSFDR_IN_USE);
133298 + return 0;
133299 +}
133300 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
133301 +
133302 +#ifdef CONFIG_SYSFS
133303 +
133304 +#define DRV_NAME "fsl-qman"
133305 +#define DCP_MAX_ID 3
133306 +#define DCP_MIN_ID 0
133307 +
133308 +static ssize_t show_pfdr_fpc(struct device *dev,
133309 + struct device_attribute *dev_attr, char *buf)
133310 +{
133311 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
133312 +};
133313 +
133314 +static ssize_t show_dlm_avg(struct device *dev,
133315 + struct device_attribute *dev_attr, char *buf)
133316 +{
133317 + u32 data;
133318 + int i;
133319 +
133320 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133321 + return -EINVAL;
133322 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133323 + return -EINVAL;
133324 + data = qm_in(DCP_DLM_AVG(i));
133325 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133326 + (data & 0x000000ff)*390625);
133327 +};
133328 +
133329 +static ssize_t set_dlm_avg(struct device *dev,
133330 + struct device_attribute *dev_attr, const char *buf, size_t count)
133331 +{
133332 + unsigned long val;
133333 + int i;
133334 +
133335 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133336 + return -EINVAL;
133337 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133338 + return -EINVAL;
133339 + if (kstrtoul(buf, 0, &val)) {
133340 + dev_dbg(dev, "invalid input %s\n", buf);
133341 + return -EINVAL;
133342 + }
133343 + qm_out(DCP_DLM_AVG(i), val);
133344 + return count;
133345 +};
133346 +
133347 +static ssize_t show_pfdr_cfg(struct device *dev,
133348 + struct device_attribute *dev_attr, char *buf)
133349 +{
133350 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
133351 +};
133352 +
133353 +static ssize_t set_pfdr_cfg(struct device *dev,
133354 + struct device_attribute *dev_attr, const char *buf, size_t count)
133355 +{
133356 + unsigned long val;
133357 +
133358 + if (kstrtoul(buf, 0, &val)) {
133359 + dev_dbg(dev, "invalid input %s\n", buf);
133360 + return -EINVAL;
133361 + }
133362 + qm_out(PFDR_CFG, val);
133363 + return count;
133364 +};
133365 +
133366 +static ssize_t show_sfdr_in_use(struct device *dev,
133367 + struct device_attribute *dev_attr, char *buf)
133368 +{
133369 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
133370 +};
133371 +
133372 +static ssize_t show_idle_stat(struct device *dev,
133373 + struct device_attribute *dev_attr, char *buf)
133374 +{
133375 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
133376 +};
133377 +
133378 +static ssize_t show_ci_rlm_avg(struct device *dev,
133379 + struct device_attribute *dev_attr, char *buf)
133380 +{
133381 + u32 data = qm_in(CI_RLM_AVG);
133382 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133383 + (data & 0x000000ff)*390625);
133384 +};
133385 +
133386 +static ssize_t set_ci_rlm_avg(struct device *dev,
133387 + struct device_attribute *dev_attr, const char *buf, size_t count)
133388 +{
133389 + unsigned long val;
133390 +
133391 + if (kstrtoul(buf, 0, &val)) {
133392 + dev_dbg(dev, "invalid input %s\n", buf);
133393 + return -EINVAL;
133394 + }
133395 + qm_out(CI_RLM_AVG, val);
133396 + return count;
133397 +};
133398 +
133399 +static ssize_t show_err_isr(struct device *dev,
133400 + struct device_attribute *dev_attr, char *buf)
133401 +{
133402 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
133403 +};
133404 +
133405 +#define SBEC_MAX_ID 14
133406 +#define SBEC_MIN_ID 0
133407 +
133408 +static ssize_t show_sbec(struct device *dev,
133409 + struct device_attribute *dev_attr, char *buf)
133410 +{
133411 + int i;
133412 +
133413 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
133414 + return -EINVAL;
133415 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
133416 + return -EINVAL;
133417 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
133418 +};
133419 +
133420 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
133421 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
133422 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
133423 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
133424 + show_ci_rlm_avg, set_ci_rlm_avg);
133425 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
133426 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
133427 +
133428 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133429 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133430 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133431 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133432 +
133433 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
133434 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
133435 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
133436 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
133437 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
133438 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
133439 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
133440 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
133441 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
133442 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
133443 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
133444 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
133445 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
133446 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
133447 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
133448 +
133449 +static struct attribute *qman_dev_attributes[] = {
133450 + &dev_attr_pfdr_fpc.attr,
133451 + &dev_attr_pfdr_cfg.attr,
133452 + &dev_attr_idle_stat.attr,
133453 + &dev_attr_ci_rlm_avg.attr,
133454 + &dev_attr_err_isr.attr,
133455 + &dev_attr_dcp0_dlm_avg.attr,
133456 + &dev_attr_dcp1_dlm_avg.attr,
133457 + &dev_attr_dcp2_dlm_avg.attr,
133458 + &dev_attr_dcp3_dlm_avg.attr,
133459 + /* sfdr_in_use will be added if necessary */
133460 + NULL
133461 +};
133462 +
133463 +static struct attribute *qman_dev_ecr_attributes[] = {
133464 + &dev_attr_sbec_0.attr,
133465 + &dev_attr_sbec_1.attr,
133466 + &dev_attr_sbec_2.attr,
133467 + &dev_attr_sbec_3.attr,
133468 + &dev_attr_sbec_4.attr,
133469 + &dev_attr_sbec_5.attr,
133470 + &dev_attr_sbec_6.attr,
133471 + &dev_attr_sbec_7.attr,
133472 + &dev_attr_sbec_8.attr,
133473 + &dev_attr_sbec_9.attr,
133474 + &dev_attr_sbec_10.attr,
133475 + &dev_attr_sbec_11.attr,
133476 + &dev_attr_sbec_12.attr,
133477 + &dev_attr_sbec_13.attr,
133478 + &dev_attr_sbec_14.attr,
133479 + NULL
133480 +};
133481 +
133482 +/* root level */
133483 +static const struct attribute_group qman_dev_attr_grp = {
133484 + .name = NULL,
133485 + .attrs = qman_dev_attributes
133486 +};
133487 +static const struct attribute_group qman_dev_ecr_grp = {
133488 + .name = "error_capture",
133489 + .attrs = qman_dev_ecr_attributes
133490 +};
133491 +
133492 +static int of_fsl_qman_remove(struct platform_device *ofdev)
133493 +{
133494 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133495 + return 0;
133496 +};
133497 +
133498 +static int of_fsl_qman_probe(struct platform_device *ofdev)
133499 +{
133500 + int ret;
133501 +
133502 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133503 + if (ret)
133504 + goto done;
133505 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
133506 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
133507 + if (ret)
133508 + goto del_group_0;
133509 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
133510 + if (ret)
133511 + goto del_group_0;
133512 +
133513 + goto done;
133514 +
133515 +del_group_0:
133516 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133517 +done:
133518 + if (ret)
133519 + dev_err(&ofdev->dev,
133520 + "Cannot create dev attributes ret=%d\n", ret);
133521 + return ret;
133522 +};
133523 +
133524 +static struct of_device_id of_fsl_qman_ids[] = {
133525 + {
133526 + .compatible = "fsl,qman",
133527 + },
133528 + {}
133529 +};
133530 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
133531 +
133532 +#ifdef CONFIG_SUSPEND
133533 +
133534 +static u32 saved_isdr;
133535 +static int qman_pm_suspend_noirq(struct device *dev)
133536 +{
133537 + uint32_t idle_state;
133538 +
133539 + suspend_unused_qportal();
133540 + /* save isdr, disable all, clear isr */
133541 + saved_isdr = qm_err_isr_disable_read(qm);
133542 + qm_err_isr_disable_write(qm, 0xffffffff);
133543 + qm_err_isr_status_clear(qm, 0xffffffff);
133544 + idle_state = qm_in(IDLE_STAT);
133545 + if (!(idle_state & 0x1)) {
133546 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
133547 + qm_err_isr_disable_write(qm, saved_isdr);
133548 + resume_unused_qportal();
133549 + return -EBUSY;
133550 + }
133551 +#ifdef CONFIG_PM_DEBUG
133552 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
133553 +#endif
133554 + return 0;
133555 +}
133556 +
133557 +static int qman_pm_resume_noirq(struct device *dev)
133558 +{
133559 + /* restore isdr */
133560 + qm_err_isr_disable_write(qm, saved_isdr);
133561 + resume_unused_qportal();
133562 + return 0;
133563 +}
133564 +#else
133565 +#define qman_pm_suspend_noirq NULL
133566 +#define qman_pm_resume_noirq NULL
133567 +#endif
133568 +
133569 +static const struct dev_pm_ops qman_pm_ops = {
133570 + .suspend_noirq = qman_pm_suspend_noirq,
133571 + .resume_noirq = qman_pm_resume_noirq,
133572 +};
133573 +
133574 +static struct platform_driver of_fsl_qman_driver = {
133575 + .driver = {
133576 + .owner = THIS_MODULE,
133577 + .name = DRV_NAME,
133578 + .of_match_table = of_fsl_qman_ids,
133579 + .pm = &qman_pm_ops,
133580 + },
133581 + .probe = of_fsl_qman_probe,
133582 + .remove = of_fsl_qman_remove,
133583 +};
133584 +
133585 +static int qman_ctrl_init(void)
133586 +{
133587 + return platform_driver_register(&of_fsl_qman_driver);
133588 +}
133589 +
133590 +static void qman_ctrl_exit(void)
133591 +{
133592 + platform_driver_unregister(&of_fsl_qman_driver);
133593 +}
133594 +
133595 +module_init(qman_ctrl_init);
133596 +module_exit(qman_ctrl_exit);
133597 +
133598 +#endif /* CONFIG_SYSFS */
133599 diff --git a/drivers/staging/fsl_qbman/qman_debugfs.c b/drivers/staging/fsl_qbman/qman_debugfs.c
133600 new file mode 100644
133601 index 00000000..fb8ecba1
133602 --- /dev/null
133603 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
133604 @@ -0,0 +1,1594 @@
133605 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
133606 + *
133607 + * Redistribution and use in source and binary forms, with or without
133608 + * modification, are permitted provided that the following conditions are met:
133609 + * * Redistributions of source code must retain the above copyright
133610 + * notice, this list of conditions and the following disclaimer.
133611 + * * Redistributions in binary form must reproduce the above copyright
133612 + * notice, this list of conditions and the following disclaimer in the
133613 + * documentation and/or other materials provided with the distribution.
133614 + * * Neither the name of Freescale Semiconductor nor the
133615 + * names of its contributors may be used to endorse or promote products
133616 + * derived from this software without specific prior written permission.
133617 + *
133618 + *
133619 + * ALTERNATIVELY, this software may be distributed under the terms of the
133620 + * GNU General Public License ("GPL") as published by the Free Software
133621 + * Foundation, either version 2 of that License or (at your option) any
133622 + * later version.
133623 + *
133624 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133625 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133626 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133627 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133628 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133629 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133630 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133631 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133632 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133634 + */
133635 +#include "qman_private.h"
133636 +
133637 +#define MAX_FQID (0x00ffffff)
133638 +#define QM_FQD_BLOCK_SIZE 64
133639 +#define QM_FQD_AR (0xC10)
133640 +
133641 +static u32 fqid_max;
133642 +static u64 qman_ccsr_start;
133643 +static u64 qman_ccsr_size;
133644 +
133645 +static const char * const state_txt[] = {
133646 + "Out of Service",
133647 + "Retired",
133648 + "Tentatively Scheduled",
133649 + "Truly Scheduled",
133650 + "Parked",
133651 + "Active, Active Held or Held Suspended",
133652 + "Unknown State 6",
133653 + "Unknown State 7",
133654 + NULL,
133655 +};
133656 +
133657 +static const u8 fqd_states[] = {
133658 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
133659 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
133660 + QM_MCR_NP_STATE_ACTIVE};
133661 +
133662 +struct mask_to_text {
133663 + u16 mask;
133664 + const char *txt;
133665 +};
133666 +
133667 +struct mask_filter_s {
133668 + u16 mask;
133669 + u8 filter;
133670 +};
133671 +
133672 +static const struct mask_filter_s mask_filter[] = {
133673 + {QM_FQCTRL_PREFERINCACHE, 0},
133674 + {QM_FQCTRL_PREFERINCACHE, 1},
133675 + {QM_FQCTRL_HOLDACTIVE, 0},
133676 + {QM_FQCTRL_HOLDACTIVE, 1},
133677 + {QM_FQCTRL_AVOIDBLOCK, 0},
133678 + {QM_FQCTRL_AVOIDBLOCK, 1},
133679 + {QM_FQCTRL_FORCESFDR, 0},
133680 + {QM_FQCTRL_FORCESFDR, 1},
133681 + {QM_FQCTRL_CPCSTASH, 0},
133682 + {QM_FQCTRL_CPCSTASH, 1},
133683 + {QM_FQCTRL_CTXASTASHING, 0},
133684 + {QM_FQCTRL_CTXASTASHING, 1},
133685 + {QM_FQCTRL_ORP, 0},
133686 + {QM_FQCTRL_ORP, 1},
133687 + {QM_FQCTRL_TDE, 0},
133688 + {QM_FQCTRL_TDE, 1},
133689 + {QM_FQCTRL_CGE, 0},
133690 + {QM_FQCTRL_CGE, 1}
133691 +};
133692 +
133693 +static const struct mask_to_text fq_ctrl_text_list[] = {
133694 + {
133695 + .mask = QM_FQCTRL_PREFERINCACHE,
133696 + .txt = "Prefer in cache",
133697 + },
133698 + {
133699 + .mask = QM_FQCTRL_HOLDACTIVE,
133700 + .txt = "Hold active in portal",
133701 + },
133702 + {
133703 + .mask = QM_FQCTRL_AVOIDBLOCK,
133704 + .txt = "Avoid Blocking",
133705 + },
133706 + {
133707 + .mask = QM_FQCTRL_FORCESFDR,
133708 + .txt = "High-priority SFDRs",
133709 + },
133710 + {
133711 + .mask = QM_FQCTRL_CPCSTASH,
133712 + .txt = "CPC Stash Enable",
133713 + },
133714 + {
133715 + .mask = QM_FQCTRL_CTXASTASHING,
133716 + .txt = "Context-A stashing",
133717 + },
133718 + {
133719 + .mask = QM_FQCTRL_ORP,
133720 + .txt = "ORP Enable",
133721 + },
133722 + {
133723 + .mask = QM_FQCTRL_TDE,
133724 + .txt = "Tail-Drop Enable",
133725 + },
133726 + {
133727 + .mask = QM_FQCTRL_CGE,
133728 + .txt = "Congestion Group Enable",
133729 + },
133730 + {
133731 + .mask = 0,
133732 + .txt = NULL,
133733 + }
133734 +};
133735 +
133736 +static const char *get_fqd_ctrl_text(u16 mask)
133737 +{
133738 + int i = 0;
133739 +
133740 + while (fq_ctrl_text_list[i].txt != NULL) {
133741 + if (fq_ctrl_text_list[i].mask == mask)
133742 + return fq_ctrl_text_list[i].txt;
133743 + i++;
133744 + }
133745 + return NULL;
133746 +}
133747 +
133748 +static const struct mask_to_text stashing_text_list[] = {
133749 + {
133750 + .mask = QM_STASHING_EXCL_CTX,
133751 + .txt = "FQ Ctx Stash"
133752 + },
133753 + {
133754 + .mask = QM_STASHING_EXCL_DATA,
133755 + .txt = "Frame Data Stash",
133756 + },
133757 + {
133758 + .mask = QM_STASHING_EXCL_ANNOTATION,
133759 + .txt = "Frame Annotation Stash",
133760 + },
133761 + {
133762 + .mask = 0,
133763 + .txt = NULL,
133764 + },
133765 +};
133766 +
133767 +static int user_input_convert(const char __user *user_buf, size_t count,
133768 + unsigned long *val)
133769 +{
133770 + char buf[12];
133771 +
133772 + if (count > sizeof(buf) - 1)
133773 + return -EINVAL;
133774 + if (copy_from_user(buf, user_buf, count))
133775 + return -EFAULT;
133776 + buf[count] = '\0';
133777 + if (kstrtoul(buf, 0, val))
133778 + return -EINVAL;
133779 + return 0;
133780 +}
133781 +
133782 +struct line_buffer_fq {
133783 + u32 buf[8];
133784 + u32 buf_cnt;
133785 + int line_cnt;
133786 +};
133787 +
133788 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133789 + struct seq_file *file)
133790 +{
133791 + line_buf->buf[line_buf->buf_cnt] = fqid;
133792 + line_buf->buf_cnt++;
133793 + if (line_buf->buf_cnt == 8) {
133794 + /* Buffer is full, flush it */
133795 + if (line_buf->line_cnt != 0)
133796 + seq_puts(file, ",\n");
133797 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
133798 + "0x%06x,0x%06x,0x%06x",
133799 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
133800 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
133801 + line_buf->buf[6], line_buf->buf[7]);
133802 + line_buf->buf_cnt = 0;
133803 + line_buf->line_cnt++;
133804 + }
133805 +}
133806 +
133807 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
133808 + struct seq_file *file)
133809 +{
133810 + if (line_buf->buf_cnt) {
133811 + int y = 0;
133812 + if (line_buf->line_cnt != 0)
133813 + seq_puts(file, ",\n");
133814 + while (y != line_buf->buf_cnt) {
133815 + if (y+1 == line_buf->buf_cnt)
133816 + seq_printf(file, "0x%06x", line_buf->buf[y]);
133817 + else
133818 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
133819 + y++;
133820 + }
133821 + line_buf->line_cnt++;
133822 + }
133823 + if (line_buf->line_cnt)
133824 + seq_putc(file, '\n');
133825 +}
133826 +
133827 +static struct dentry *dfs_root; /* debugfs root directory */
133828 +
133829 +/*******************************************************************************
133830 + * Query Frame Queue Non Programmable Fields
133831 + ******************************************************************************/
133832 +struct query_fq_np_fields_data_s {
133833 + u32 fqid;
133834 +};
133835 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
133836 + .fqid = 1,
133837 +};
133838 +
133839 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
133840 +{
133841 + int ret;
133842 + struct qm_mcr_queryfq_np np;
133843 + struct qman_fq fq;
133844 +
133845 + fq.fqid = query_fq_np_fields_data.fqid;
133846 + ret = qman_query_fq_np(&fq, &np);
133847 + if (ret)
133848 + return ret;
133849 + /* Print state */
133850 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
133851 + fq.fqid);
133852 + seq_printf(file, " force eligible pending: %s\n",
133853 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
133854 + seq_printf(file, " retirement pending: %s\n",
133855 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
133856 + seq_printf(file, " state: %s\n",
133857 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
133858 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
133859 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
133860 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
133861 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
133862 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
133863 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
133864 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
133865 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
133866 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
133867 + seq_printf(file, " is: ics_surp contains a %s\n",
133868 + (np.is) ? "deficit" : "surplus");
133869 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
133870 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
133871 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
133872 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
133873 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
133874 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
133875 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
133876 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
133877 + return 0;
133878 +}
133879 +
133880 +static int query_fq_np_fields_open(struct inode *inode,
133881 + struct file *file)
133882 +{
133883 + return single_open(file, query_fq_np_fields_show, NULL);
133884 +}
133885 +
133886 +static ssize_t query_fq_np_fields_write(struct file *f,
133887 + const char __user *buf, size_t count, loff_t *off)
133888 +{
133889 + int ret;
133890 + unsigned long val;
133891 +
133892 + ret = user_input_convert(buf, count, &val);
133893 + if (ret)
133894 + return ret;
133895 + if (val > MAX_FQID)
133896 + return -EINVAL;
133897 + query_fq_np_fields_data.fqid = (u32)val;
133898 + return count;
133899 +}
133900 +
133901 +static const struct file_operations query_fq_np_fields_fops = {
133902 + .owner = THIS_MODULE,
133903 + .open = query_fq_np_fields_open,
133904 + .read = seq_read,
133905 + .write = query_fq_np_fields_write,
133906 + .release = single_release,
133907 +};
133908 +
133909 +/*******************************************************************************
133910 + * Frame Queue Programmable Fields
133911 + ******************************************************************************/
133912 +struct query_fq_fields_data_s {
133913 + u32 fqid;
133914 +};
133915 +
133916 +static struct query_fq_fields_data_s query_fq_fields_data = {
133917 + .fqid = 1,
133918 +};
133919 +
133920 +static int query_fq_fields_show(struct seq_file *file, void *offset)
133921 +{
133922 + int ret;
133923 + struct qm_fqd fqd;
133924 + struct qman_fq fq;
133925 + int i = 0;
133926 +
133927 + memset(&fqd, 0, sizeof(struct qm_fqd));
133928 + fq.fqid = query_fq_fields_data.fqid;
133929 + ret = qman_query_fq(&fq, &fqd);
133930 + if (ret)
133931 + return ret;
133932 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
133933 + fq.fqid);
133934 + seq_printf(file, " orprws: %u\n", fqd.orprws);
133935 + seq_printf(file, " oa: %u\n", fqd.oa);
133936 + seq_printf(file, " olws: %u\n", fqd.olws);
133937 +
133938 + seq_printf(file, " cgid: %u\n", fqd.cgid);
133939 +
133940 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
133941 + seq_puts(file, " fq_ctrl: None\n");
133942 + else {
133943 + i = 0;
133944 + seq_puts(file, " fq_ctrl:\n");
133945 + while (fq_ctrl_text_list[i].txt != NULL) {
133946 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
133947 + fq_ctrl_text_list[i].mask)
133948 + seq_printf(file, " %s\n",
133949 + fq_ctrl_text_list[i].txt);
133950 + i++;
133951 + }
133952 + }
133953 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
133954 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
133955 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
133956 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
133957 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
133958 +
133959 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
133960 +
133961 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
133962 + /* Any stashing configured */
133963 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
133964 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
133965 + else {
133966 + seq_puts(file, " ctx_a_stash_exclusive:\n");
133967 + i = 0;
133968 + while (stashing_text_list[i].txt != NULL) {
133969 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
133970 + seq_printf(file, " %s\n",
133971 + stashing_text_list[i].txt);
133972 + i++;
133973 + }
133974 + }
133975 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
133976 + fqd.context_a.stashing.annotation_cl);
133977 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
133978 + fqd.context_a.stashing.data_cl);
133979 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
133980 + fqd.context_a.stashing.context_cl);
133981 + return 0;
133982 +}
133983 +
133984 +static int query_fq_fields_open(struct inode *inode,
133985 + struct file *file)
133986 +{
133987 + return single_open(file, query_fq_fields_show, NULL);
133988 +}
133989 +
133990 +static ssize_t query_fq_fields_write(struct file *f,
133991 + const char __user *buf, size_t count, loff_t *off)
133992 +{
133993 + int ret;
133994 + unsigned long val;
133995 +
133996 + ret = user_input_convert(buf, count, &val);
133997 + if (ret)
133998 + return ret;
133999 + if (val > MAX_FQID)
134000 + return -EINVAL;
134001 + query_fq_fields_data.fqid = (u32)val;
134002 + return count;
134003 +}
134004 +
134005 +static const struct file_operations query_fq_fields_fops = {
134006 + .owner = THIS_MODULE,
134007 + .open = query_fq_fields_open,
134008 + .read = seq_read,
134009 + .write = query_fq_fields_write,
134010 + .release = single_release,
134011 +};
134012 +
134013 +/*******************************************************************************
134014 + * Query WQ lengths
134015 + ******************************************************************************/
134016 +struct query_wq_lengths_data_s {
134017 + union {
134018 + u16 channel_wq; /* ignores wq (3 lsbits) */
134019 + struct {
134020 + u16 id:13; /* qm_channel */
134021 + u16 __reserved:3;
134022 + } __packed channel;
134023 + };
134024 +};
134025 +static struct query_wq_lengths_data_s query_wq_lengths_data;
134026 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
134027 +{
134028 + int ret;
134029 + struct qm_mcr_querywq wq;
134030 + int i;
134031 +
134032 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
134033 + wq.channel.id = query_wq_lengths_data.channel.id;
134034 + ret = qman_query_wq(0, &wq);
134035 + if (ret)
134036 + return ret;
134037 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
134038 + for (i = 0; i < 8; i++)
134039 + /* mask out upper 4 bits since they are not part of length */
134040 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
134041 + return 0;
134042 +}
134043 +
134044 +static int query_wq_lengths_open(struct inode *inode,
134045 + struct file *file)
134046 +{
134047 + return single_open(file, query_wq_lengths_show, NULL);
134048 +}
134049 +
134050 +static ssize_t query_wq_lengths_write(struct file *f,
134051 + const char __user *buf, size_t count, loff_t *off)
134052 +{
134053 + int ret;
134054 + unsigned long val;
134055 +
134056 + ret = user_input_convert(buf, count, &val);
134057 + if (ret)
134058 + return ret;
134059 + if (val > 0xfff8)
134060 + return -EINVAL;
134061 + query_wq_lengths_data.channel.id = (u16)val;
134062 + return count;
134063 +}
134064 +
134065 +static const struct file_operations query_wq_lengths_fops = {
134066 + .owner = THIS_MODULE,
134067 + .open = query_wq_lengths_open,
134068 + .read = seq_read,
134069 + .write = query_wq_lengths_write,
134070 + .release = single_release,
134071 +};
134072 +
134073 +/*******************************************************************************
134074 + * Query CGR
134075 + ******************************************************************************/
134076 +struct query_cgr_s {
134077 + u8 cgid;
134078 +};
134079 +static struct query_cgr_s query_cgr_data;
134080 +
134081 +static int query_cgr_show(struct seq_file *file, void *offset)
134082 +{
134083 + int ret;
134084 + struct qm_mcr_querycgr cgrd;
134085 + struct qman_cgr cgr;
134086 + int i, j;
134087 + u32 mask;
134088 +
134089 + memset(&cgr, 0, sizeof(cgr));
134090 + memset(&cgrd, 0, sizeof(cgrd));
134091 + cgr.cgrid = query_cgr_data.cgid;
134092 + ret = qman_query_cgr(&cgr, &cgrd);
134093 + if (ret)
134094 + return ret;
134095 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
134096 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134097 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
134098 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
134099 + cgrd.cgr.wr_parm_g.Pn);
134100 +
134101 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134102 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
134103 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
134104 + cgrd.cgr.wr_parm_y.Pn);
134105 +
134106 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134107 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
134108 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
134109 + cgrd.cgr.wr_parm_r.Pn);
134110 +
134111 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134112 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
134113 +
134114 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
134115 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134116 + seq_puts(file, " cscn_targ_dcp:\n");
134117 + mask = 0x80000000;
134118 + for (i = 0; i < 32; i++) {
134119 + if (cgrd.cgr.cscn_targ & mask)
134120 + seq_printf(file, " send CSCN to dcp %u\n",
134121 + (31 - i));
134122 + mask >>= 1;
134123 + }
134124 +
134125 + seq_puts(file, " cscn_targ_swp:\n");
134126 + for (i = 0; i < 4; i++) {
134127 + mask = 0x80000000;
134128 + for (j = 0; j < 32; j++) {
134129 + if (cgrd.cscn_targ_swp[i] & mask)
134130 + seq_printf(file, " send CSCN to swp"
134131 + " %u\n", (127 - (i * 32) - j));
134132 + mask >>= 1;
134133 + }
134134 + }
134135 + } else {
134136 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
134137 + }
134138 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
134139 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
134140 +
134141 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
134142 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
134143 +
134144 + seq_printf(file, " mode: %s\n",
134145 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
134146 + "frame count" : "byte count");
134147 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
134148 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
134149 +
134150 + return 0;
134151 +}
134152 +
134153 +static int query_cgr_open(struct inode *inode, struct file *file)
134154 +{
134155 + return single_open(file, query_cgr_show, NULL);
134156 +}
134157 +
134158 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
134159 + size_t count, loff_t *off)
134160 +{
134161 + int ret;
134162 + unsigned long val;
134163 +
134164 + ret = user_input_convert(buf, count, &val);
134165 + if (ret)
134166 + return ret;
134167 + if (val > 0xff)
134168 + return -EINVAL;
134169 + query_cgr_data.cgid = (u8)val;
134170 + return count;
134171 +}
134172 +
134173 +static const struct file_operations query_cgr_fops = {
134174 + .owner = THIS_MODULE,
134175 + .open = query_cgr_open,
134176 + .read = seq_read,
134177 + .write = query_cgr_write,
134178 + .release = single_release,
134179 +};
134180 +
134181 +/*******************************************************************************
134182 + * Test Write CGR
134183 + ******************************************************************************/
134184 +struct test_write_cgr_s {
134185 + u64 i_bcnt;
134186 + u8 cgid;
134187 +};
134188 +static struct test_write_cgr_s test_write_cgr_data;
134189 +
134190 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
134191 +{
134192 + int ret;
134193 + struct qm_mcr_cgrtestwrite result;
134194 + struct qman_cgr cgr;
134195 + u64 i_bcnt;
134196 +
134197 + memset(&cgr, 0, sizeof(struct qman_cgr));
134198 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
134199 + cgr.cgrid = test_write_cgr_data.cgid;
134200 + i_bcnt = test_write_cgr_data.i_bcnt;
134201 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
134202 + if (ret)
134203 + return ret;
134204 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
134205 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134206 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
134207 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
134208 + result.cgr.wr_parm_g.Pn);
134209 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134210 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
134211 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
134212 + result.cgr.wr_parm_y.Pn);
134213 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134214 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
134215 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
134216 + result.cgr.wr_parm_r.Pn);
134217 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134218 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
134219 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
134220 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
134221 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
134222 + seq_printf(file, " cs: %u\n", result.cgr.cs);
134223 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
134224 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
134225 +
134226 + /* Add Mode for Si 2 */
134227 + seq_printf(file, " mode: %s\n",
134228 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
134229 + "frame count" : "byte count");
134230 +
134231 + seq_printf(file, " i_bcnt: %llu\n",
134232 + qm_mcr_cgrtestwrite_i_get64(&result));
134233 + seq_printf(file, " a_bcnt: %llu\n",
134234 + qm_mcr_cgrtestwrite_a_get64(&result));
134235 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
134236 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
134237 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
134238 + return 0;
134239 +}
134240 +
134241 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
134242 +{
134243 + return single_open(file, testwrite_cgr_show, NULL);
134244 +}
134245 +
134246 +static const struct file_operations testwrite_cgr_fops = {
134247 + .owner = THIS_MODULE,
134248 + .open = testwrite_cgr_open,
134249 + .read = seq_read,
134250 + .release = single_release,
134251 +};
134252 +
134253 +
134254 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
134255 +{
134256 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
134257 + return 0;
134258 +}
134259 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
134260 +{
134261 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
134262 +}
134263 +
134264 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
134265 + size_t count, loff_t *off)
134266 +{
134267 + int ret;
134268 + unsigned long val;
134269 +
134270 + ret = user_input_convert(buf, count, &val);
134271 + if (ret)
134272 + return ret;
134273 + test_write_cgr_data.i_bcnt = val;
134274 + return count;
134275 +}
134276 +
134277 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
134278 + .owner = THIS_MODULE,
134279 + .open = testwrite_cgr_ibcnt_open,
134280 + .read = seq_read,
134281 + .write = testwrite_cgr_ibcnt_write,
134282 + .release = single_release,
134283 +};
134284 +
134285 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
134286 +{
134287 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
134288 + return 0;
134289 +}
134290 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
134291 +{
134292 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
134293 +}
134294 +
134295 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
134296 + size_t count, loff_t *off)
134297 +{
134298 + int ret;
134299 + unsigned long val;
134300 +
134301 + ret = user_input_convert(buf, count, &val);
134302 + if (ret)
134303 + return ret;
134304 + if (val > 0xff)
134305 + return -EINVAL;
134306 + test_write_cgr_data.cgid = (u8)val;
134307 + return count;
134308 +}
134309 +
134310 +static const struct file_operations teswrite_cgr_cgrid_fops = {
134311 + .owner = THIS_MODULE,
134312 + .open = testwrite_cgr_cgrid_open,
134313 + .read = seq_read,
134314 + .write = testwrite_cgr_cgrid_write,
134315 + .release = single_release,
134316 +};
134317 +
134318 +/*******************************************************************************
134319 + * Query Congestion State
134320 + ******************************************************************************/
134321 +static int query_congestion_show(struct seq_file *file, void *offset)
134322 +{
134323 + int ret;
134324 + struct qm_mcr_querycongestion cs;
134325 + int i, j, in_cong = 0;
134326 + u32 mask;
134327 +
134328 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
134329 + ret = qman_query_congestion(&cs);
134330 + if (ret)
134331 + return ret;
134332 + seq_puts(file, "Query Congestion Result\n");
134333 + for (i = 0; i < 8; i++) {
134334 + mask = 0x80000000;
134335 + for (j = 0; j < 32; j++) {
134336 + if (cs.state.__state[i] & mask) {
134337 + in_cong = 1;
134338 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
134339 + "in congestion");
134340 + }
134341 + mask >>= 1;
134342 + }
134343 + }
134344 + if (!in_cong)
134345 + seq_puts(file, " All congestion groups not congested.\n");
134346 + return 0;
134347 +}
134348 +
134349 +static int query_congestion_open(struct inode *inode, struct file *file)
134350 +{
134351 + return single_open(file, query_congestion_show, NULL);
134352 +}
134353 +
134354 +static const struct file_operations query_congestion_fops = {
134355 + .owner = THIS_MODULE,
134356 + .open = query_congestion_open,
134357 + .read = seq_read,
134358 + .release = single_release,
134359 +};
134360 +
134361 +/*******************************************************************************
134362 + * Query CCGR
134363 + ******************************************************************************/
134364 +struct query_ccgr_s {
134365 + u32 ccgid;
134366 +};
134367 +static struct query_ccgr_s query_ccgr_data;
134368 +
134369 +static int query_ccgr_show(struct seq_file *file, void *offset)
134370 +{
134371 + int ret;
134372 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
134373 + struct qm_mcc_ceetm_ccgr_query query_opts;
134374 + int i, j;
134375 + u32 mask;
134376 +
134377 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
134378 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
134379 +
134380 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134381 + return -EINVAL;
134382 +
134383 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
134384 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
134385 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
134386 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
134387 + if (ret)
134388 + return ret;
134389 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
134390 + query_opts.dcpid);
134391 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134392 + ccgr_query.cm_query.wr_parm_g.MA,
134393 + ccgr_query.cm_query.wr_parm_g.Mn,
134394 + ccgr_query.cm_query.wr_parm_g.SA,
134395 + ccgr_query.cm_query.wr_parm_g.Sn,
134396 + ccgr_query.cm_query.wr_parm_g.Pn);
134397 +
134398 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134399 + ccgr_query.cm_query.wr_parm_y.MA,
134400 + ccgr_query.cm_query.wr_parm_y.Mn,
134401 + ccgr_query.cm_query.wr_parm_y.SA,
134402 + ccgr_query.cm_query.wr_parm_y.Sn,
134403 + ccgr_query.cm_query.wr_parm_y.Pn);
134404 +
134405 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134406 + ccgr_query.cm_query.wr_parm_r.MA,
134407 + ccgr_query.cm_query.wr_parm_r.Mn,
134408 + ccgr_query.cm_query.wr_parm_r.SA,
134409 + ccgr_query.cm_query.wr_parm_r.Sn,
134410 + ccgr_query.cm_query.wr_parm_r.Pn);
134411 +
134412 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134413 + ccgr_query.cm_query.ctl_wr_en_g,
134414 + ccgr_query.cm_query.ctl_wr_en_y,
134415 + ccgr_query.cm_query.ctl_wr_en_r);
134416 +
134417 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
134418 + seq_puts(file, " cscn_targ_dcp:\n");
134419 + mask = 0x80000000;
134420 + for (i = 0; i < 32; i++) {
134421 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
134422 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
134423 + mask >>= 1;
134424 + }
134425 +
134426 + seq_puts(file, " cscn_targ_swp:\n");
134427 + for (i = 0; i < 4; i++) {
134428 + mask = 0x80000000;
134429 + for (j = 0; j < 32; j++) {
134430 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
134431 + seq_printf(file, " send CSCN to swp"
134432 + "%u\n", (127 - (i * 32) - j));
134433 + mask >>= 1;
134434 + }
134435 + }
134436 +
134437 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
134438 +
134439 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
134440 + ccgr_query.cm_query.cs_thres.TA,
134441 + ccgr_query.cm_query.cs_thres.Tn);
134442 +
134443 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
134444 + ccgr_query.cm_query.cs_thres_x.TA,
134445 + ccgr_query.cm_query.cs_thres_x.Tn);
134446 +
134447 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
134448 + ccgr_query.cm_query.td_thres.TA,
134449 + ccgr_query.cm_query.td_thres.Tn);
134450 +
134451 + seq_printf(file, " mode: %s\n",
134452 + (ccgr_query.cm_query.ctl_mode &
134453 + QMAN_CGR_MODE_FRAME) ?
134454 + "frame count" : "byte count");
134455 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
134456 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
134457 +
134458 + return 0;
134459 +}
134460 +
134461 +static int query_ccgr_open(struct inode *inode, struct file *file)
134462 +{
134463 + return single_open(file, query_ccgr_show, NULL);
134464 +}
134465 +
134466 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
134467 + size_t count, loff_t *off)
134468 +{
134469 + int ret;
134470 + unsigned long val;
134471 +
134472 + ret = user_input_convert(buf, count, &val);
134473 + if (ret)
134474 + return ret;
134475 + query_ccgr_data.ccgid = val;
134476 + return count;
134477 +}
134478 +
134479 +static const struct file_operations query_ccgr_fops = {
134480 + .owner = THIS_MODULE,
134481 + .open = query_ccgr_open,
134482 + .read = seq_read,
134483 + .write = query_ccgr_write,
134484 + .release = single_release,
134485 +};
134486 +/*******************************************************************************
134487 + * QMan register
134488 + ******************************************************************************/
134489 +struct qman_register_s {
134490 + u32 val;
134491 +};
134492 +static struct qman_register_s qman_register_data;
134493 +
134494 +static void init_ccsrmempeek(void)
134495 +{
134496 + struct device_node *dn;
134497 + const u32 *regaddr_p;
134498 +
134499 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
134500 + if (!dn) {
134501 + pr_info("No fsl,qman node\n");
134502 + return;
134503 + }
134504 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
134505 + if (!regaddr_p) {
134506 + of_node_put(dn);
134507 + return;
134508 + }
134509 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
134510 + of_node_put(dn);
134511 +}
134512 +/* This function provides access to QMan ccsr memory map */
134513 +static int qman_ccsrmempeek(u32 *val, u32 offset)
134514 +{
134515 + void __iomem *addr;
134516 + u64 phys_addr;
134517 +
134518 + if (!qman_ccsr_start)
134519 + return -EINVAL;
134520 +
134521 + if (offset > (qman_ccsr_size - sizeof(u32)))
134522 + return -EINVAL;
134523 +
134524 + phys_addr = qman_ccsr_start + offset;
134525 + addr = ioremap(phys_addr, sizeof(u32));
134526 + if (!addr) {
134527 + pr_err("ccsrmempeek, ioremap failed\n");
134528 + return -EINVAL;
134529 + }
134530 + *val = in_be32(addr);
134531 + iounmap(addr);
134532 + return 0;
134533 +}
134534 +
134535 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
134536 +{
134537 + u32 b;
134538 +
134539 + qman_ccsrmempeek(&b, qman_register_data.val);
134540 + seq_printf(file, "QMan register offset = 0x%x\n",
134541 + qman_register_data.val);
134542 + seq_printf(file, "value = 0x%08x\n", b);
134543 +
134544 + return 0;
134545 +}
134546 +
134547 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
134548 +{
134549 + return single_open(file, qman_ccsrmempeek_show, NULL);
134550 +}
134551 +
134552 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
134553 + size_t count, loff_t *off)
134554 +{
134555 + int ret;
134556 + unsigned long val;
134557 +
134558 + ret = user_input_convert(buf, count, &val);
134559 + if (ret)
134560 + return ret;
134561 + /* multiple of 4 */
134562 + if (val > (qman_ccsr_size - sizeof(u32))) {
134563 + pr_info("Input 0x%lx > 0x%llx\n",
134564 + val, (qman_ccsr_size - sizeof(u32)));
134565 + return -EINVAL;
134566 + }
134567 + if (val & 0x3) {
134568 + pr_info("Input 0x%lx not multiple of 4\n", val);
134569 + return -EINVAL;
134570 + }
134571 + qman_register_data.val = val;
134572 + return count;
134573 +}
134574 +
134575 +static const struct file_operations qman_ccsrmempeek_fops = {
134576 + .owner = THIS_MODULE,
134577 + .open = qman_ccsrmempeek_open,
134578 + .read = seq_read,
134579 + .write = qman_ccsrmempeek_write,
134580 +};
134581 +
134582 +/*******************************************************************************
134583 + * QMan state
134584 + ******************************************************************************/
134585 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
134586 +{
134587 + struct qm_mcr_queryfq_np np;
134588 + struct qman_fq fq;
134589 + struct line_buffer_fq line_buf;
134590 + int ret, i;
134591 + u8 *state = file->private;
134592 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134593 +
134594 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134595 + memset(&line_buf, 0, sizeof(line_buf));
134596 +
134597 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
134598 +
134599 + for (i = 1; i < fqid_max; i++) {
134600 + fq.fqid = i;
134601 + ret = qman_query_fq_np(&fq, &np);
134602 + if (ret)
134603 + return ret;
134604 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
134605 + add_to_line_buffer(&line_buf, fq.fqid, file);
134606 + /* Keep a summary count of all states */
134607 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134608 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134609 + }
134610 + flush_line_buffer(&line_buf, file);
134611 +
134612 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134613 + seq_printf(file, "%s count = %u\n", state_txt[i],
134614 + qm_fq_state_cnt[i]);
134615 + }
134616 + return 0;
134617 +}
134618 +
134619 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
134620 +{
134621 + return single_open(file, qman_fqd_state_show, inode->i_private);
134622 +}
134623 +
134624 +static const struct file_operations qman_fqd_state_fops = {
134625 + .owner = THIS_MODULE,
134626 + .open = qman_fqd_state_open,
134627 + .read = seq_read,
134628 +};
134629 +
134630 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
134631 +{
134632 + struct qm_fqd fqd;
134633 + struct qman_fq fq;
134634 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
134635 + int ret, i;
134636 + struct mask_filter_s *data = file->private;
134637 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
134638 + struct line_buffer_fq line_buf;
134639 +
134640 + memset(&line_buf, 0, sizeof(line_buf));
134641 + seq_printf(file, "List of fq ids with: %s :%s\n",
134642 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
134643 + for (i = 1; i < fqid_max; i++) {
134644 + fq.fqid = i;
134645 + memset(&fqd, 0, sizeof(struct qm_fqd));
134646 + ret = qman_query_fq(&fq, &fqd);
134647 + if (ret)
134648 + return ret;
134649 + if (data->filter) {
134650 + if (fqd.fq_ctrl & data->mask)
134651 + add_to_line_buffer(&line_buf, fq.fqid, file);
134652 + } else {
134653 + if (!(fqd.fq_ctrl & data->mask))
134654 + add_to_line_buffer(&line_buf, fq.fqid, file);
134655 + }
134656 + if (fqd.fq_ctrl & data->mask)
134657 + fq_en_cnt++;
134658 + else
134659 + fq_di_cnt++;
134660 + }
134661 + flush_line_buffer(&line_buf, file);
134662 +
134663 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
134664 + ctrl_txt, fq_en_cnt);
134665 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
134666 + ctrl_txt, fq_di_cnt);
134667 + return 0;
134668 +}
134669 +
134670 +/*******************************************************************************
134671 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
134672 + ******************************************************************************/
134673 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
134674 +{
134675 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
134676 +}
134677 +
134678 +static const struct file_operations qman_fqd_ctrl_fops = {
134679 + .owner = THIS_MODULE,
134680 + .open = qman_fqd_ctrl_open,
134681 + .read = seq_read,
134682 +};
134683 +
134684 +/*******************************************************************************
134685 + * QMan ctrl summary
134686 + ******************************************************************************/
134687 +/*******************************************************************************
134688 + * QMan summary state
134689 + ******************************************************************************/
134690 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
134691 +{
134692 + struct qm_mcr_queryfq_np np;
134693 + struct qman_fq fq;
134694 + int ret, i;
134695 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134696 +
134697 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134698 +
134699 + for (i = 1; i < fqid_max; i++) {
134700 + fq.fqid = i;
134701 + ret = qman_query_fq_np(&fq, &np);
134702 + if (ret)
134703 + return ret;
134704 + /* Keep a summary count of all states */
134705 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134706 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134707 + }
134708 +
134709 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134710 + seq_printf(file, "%s count = %u\n", state_txt[i],
134711 + qm_fq_state_cnt[i]);
134712 + }
134713 + return 0;
134714 +}
134715 +
134716 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134717 +{
134718 + struct qm_fqd fqd;
134719 + struct qman_fq fq;
134720 + int ret, i , j;
134721 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134722 +
134723 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134724 +
134725 + for (i = 1; i < fqid_max; i++) {
134726 + memset(&fqd, 0, sizeof(struct qm_fqd));
134727 + fq.fqid = i;
134728 + ret = qman_query_fq(&fq, &fqd);
134729 + if (ret)
134730 + return ret;
134731 + /* Keep a summary count of all states */
134732 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134733 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134734 + mask_filter[j].mask)
134735 + qm_prog_cnt[j/2]++;
134736 + }
134737 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134738 + seq_printf(file, "%s count = %u\n",
134739 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134740 + qm_prog_cnt[i]);
134741 + }
134742 + return 0;
134743 +}
134744 +
134745 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134746 +{
134747 + int ret;
134748 +
134749 + /* Display summary of non programmable fields */
134750 + ret = qman_fqd_non_prog_summary_show(file, offset);
134751 + if (ret)
134752 + return ret;
134753 + seq_puts(file, "-----------------------------------------\n");
134754 + /* Display programmable fields */
134755 + ret = qman_fqd_prog_summary_show(file, offset);
134756 + if (ret)
134757 + return ret;
134758 + return 0;
134759 +}
134760 +
134761 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134762 +{
134763 + return single_open(file, qman_fqd_summary_show, NULL);
134764 +}
134765 +
134766 +static const struct file_operations qman_fqd_summary_fops = {
134767 + .owner = THIS_MODULE,
134768 + .open = qman_fqd_summary_open,
134769 + .read = seq_read,
134770 +};
134771 +
134772 +/*******************************************************************************
134773 + * QMan destination work queue
134774 + ******************************************************************************/
134775 +struct qman_dest_wq_s {
134776 + u16 wq_id;
134777 +};
134778 +static struct qman_dest_wq_s qman_dest_wq_data = {
134779 + .wq_id = 0,
134780 +};
134781 +
134782 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134783 +{
134784 + struct qm_fqd fqd;
134785 + struct qman_fq fq;
134786 + int ret, i;
134787 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134788 + struct line_buffer_fq line_buf;
134789 +
134790 + memset(&line_buf, 0, sizeof(line_buf));
134791 + /* use vmalloc : need to allocate large memory region and don't
134792 + * require the memory to be physically contiguous. */
134793 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134794 + if (!wq)
134795 + return -ENOMEM;
134796 +
134797 + seq_printf(file, "List of fq ids with destination work queue id"
134798 + " = 0x%x\n", wq_id);
134799 +
134800 + for (i = 1; i < fqid_max; i++) {
134801 + fq.fqid = i;
134802 + memset(&fqd, 0, sizeof(struct qm_fqd));
134803 + ret = qman_query_fq(&fq, &fqd);
134804 + if (ret) {
134805 + vfree(wq);
134806 + return ret;
134807 + }
134808 + if (wq_id == fqd.dest_wq)
134809 + add_to_line_buffer(&line_buf, fq.fqid, file);
134810 + wq[fqd.dest_wq]++;
134811 + }
134812 + flush_line_buffer(&line_buf, file);
134813 +
134814 + seq_puts(file, "Summary of all FQD destination work queue values\n");
134815 + for (i = 0; i < 0xFFFF; i++) {
134816 + if (wq[i])
134817 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
134818 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
134819 + }
134820 + vfree(wq);
134821 + return 0;
134822 +}
134823 +
134824 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
134825 + size_t count, loff_t *off)
134826 +{
134827 + int ret;
134828 + unsigned long val;
134829 +
134830 + ret = user_input_convert(buf, count, &val);
134831 + if (ret)
134832 + return ret;
134833 + if (val > 0xFFFF)
134834 + return -EINVAL;
134835 + qman_dest_wq_data.wq_id = val;
134836 + return count;
134837 +}
134838 +
134839 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
134840 +{
134841 + return single_open(file, qman_fqd_dest_wq_show, NULL);
134842 +}
134843 +
134844 +static const struct file_operations qman_fqd_dest_wq_fops = {
134845 + .owner = THIS_MODULE,
134846 + .open = qman_fqd_dest_wq_open,
134847 + .read = seq_read,
134848 + .write = qman_fqd_dest_wq_write,
134849 +};
134850 +
134851 +/*******************************************************************************
134852 + * QMan Intra-Class Scheduling Credit
134853 + ******************************************************************************/
134854 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
134855 +{
134856 + struct qm_fqd fqd;
134857 + struct qman_fq fq;
134858 + int ret, i;
134859 + u32 fq_cnt = 0;
134860 + struct line_buffer_fq line_buf;
134861 +
134862 + memset(&line_buf, 0, sizeof(line_buf));
134863 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
134864 + "\n");
134865 +
134866 + for (i = 1; i < fqid_max; i++) {
134867 + fq.fqid = i;
134868 + memset(&fqd, 0, sizeof(struct qm_fqd));
134869 + ret = qman_query_fq(&fq, &fqd);
134870 + if (ret)
134871 + return ret;
134872 + if (fqd.ics_cred > 0) {
134873 + add_to_line_buffer(&line_buf, fq.fqid, file);
134874 + fq_cnt++;
134875 + }
134876 + }
134877 + flush_line_buffer(&line_buf, file);
134878 +
134879 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
134880 + return 0;
134881 +}
134882 +
134883 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
134884 +{
134885 + return single_open(file, qman_fqd_cred_show, NULL);
134886 +}
134887 +
134888 +static const struct file_operations qman_fqd_cred_fops = {
134889 + .owner = THIS_MODULE,
134890 + .open = qman_fqd_cred_open,
134891 + .read = seq_read,
134892 +};
134893 +
134894 +/*******************************************************************************
134895 + * Class Queue Fields
134896 + ******************************************************************************/
134897 +struct query_cq_fields_data_s {
134898 + u32 cqid;
134899 +};
134900 +
134901 +static struct query_cq_fields_data_s query_cq_fields_data = {
134902 + .cqid = 1,
134903 +};
134904 +
134905 +static int query_cq_fields_show(struct seq_file *file, void *offset)
134906 +{
134907 + int ret;
134908 + struct qm_mcr_ceetm_cq_query query_result;
134909 + unsigned int cqid;
134910 + unsigned int portal;
134911 +
134912 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134913 + return -EINVAL;
134914 +
134915 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
134916 + portal = query_cq_fields_data.cqid >> 24;
134917 + if (portal > qm_dc_portal_fman1)
134918 + return -EINVAL;
134919 +
134920 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
134921 + if (ret)
134922 + return ret;
134923 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
134924 + cqid, portal);
134925 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
134926 + seq_printf(file, " state: %u\n", query_result.state);
134927 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
134928 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
134929 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
134930 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
134931 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
134932 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
134933 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
134934 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
134935 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
134936 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
134937 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
134938 +
134939 + return 0;
134940 +}
134941 +
134942 +static int query_cq_fields_open(struct inode *inode,
134943 + struct file *file)
134944 +{
134945 + return single_open(file, query_cq_fields_show, NULL);
134946 +}
134947 +
134948 +static ssize_t query_cq_fields_write(struct file *f,
134949 + const char __user *buf, size_t count, loff_t *off)
134950 +{
134951 + int ret;
134952 + unsigned long val;
134953 +
134954 + ret = user_input_convert(buf, count, &val);
134955 + if (ret)
134956 + return ret;
134957 + query_cq_fields_data.cqid = (u32)val;
134958 + return count;
134959 +}
134960 +
134961 +static const struct file_operations query_cq_fields_fops = {
134962 + .owner = THIS_MODULE,
134963 + .open = query_cq_fields_open,
134964 + .read = seq_read,
134965 + .write = query_cq_fields_write,
134966 + .release = single_release,
134967 +};
134968 +
134969 +/*******************************************************************************
134970 + * READ CEETM_XSFDR_IN_USE
134971 + ******************************************************************************/
134972 +struct query_ceetm_xsfdr_data_s {
134973 + enum qm_dc_portal dcp_portal;
134974 +};
134975 +
134976 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
134977 +
134978 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
134979 +{
134980 + int ret;
134981 + unsigned int xsfdr_in_use;
134982 + enum qm_dc_portal portal;
134983 +
134984 +
134985 + if (qman_ip_rev < QMAN_REV31)
134986 + return -EINVAL;
134987 +
134988 + portal = query_ceetm_xsfdr_data.dcp_portal;
134989 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
134990 + if (ret) {
134991 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
134992 + portal);
134993 + return ret;
134994 + }
134995 +
134996 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
134997 + (xsfdr_in_use & 0x1FFF));
134998 + return 0;
134999 +}
135000 +
135001 +static int query_ceetm_xsfdr_open(struct inode *inode,
135002 + struct file *file)
135003 +{
135004 + return single_open(file, query_ceetm_xsfdr_show, NULL);
135005 +}
135006 +
135007 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
135008 + const char __user *buf, size_t count, loff_t *off)
135009 +{
135010 + int ret;
135011 + unsigned long val;
135012 +
135013 + ret = user_input_convert(buf, count, &val);
135014 + if (ret)
135015 + return ret;
135016 + if (val > qm_dc_portal_fman1)
135017 + return -EINVAL;
135018 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
135019 + return count;
135020 +}
135021 +
135022 +static const struct file_operations query_ceetm_xsfdr_fops = {
135023 + .owner = THIS_MODULE,
135024 + .open = query_ceetm_xsfdr_open,
135025 + .read = seq_read,
135026 + .write = query_ceetm_xsfdr_write,
135027 + .release = single_release,
135028 +};
135029 +
135030 +/* helper macros used in qman_debugfs_module_init */
135031 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
135032 + do { \
135033 + d = debugfs_create_file(name, \
135034 + mode, parent, \
135035 + data, \
135036 + fops); \
135037 + if (d == NULL) { \
135038 + ret = -ENOMEM; \
135039 + goto _return; \
135040 + } \
135041 + } while (0)
135042 +
135043 +/* dfs_root as parent */
135044 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
135045 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
135046 +
135047 +/* fqd_root as parent */
135048 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
135049 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
135050 +
135051 +/* fqd state */
135052 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
135053 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
135054 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
135055 +
135056 +static int __init qman_debugfs_module_init(void)
135057 +{
135058 + int ret = 0;
135059 + struct dentry *d, *fqd_root;
135060 + u32 reg;
135061 +
135062 + fqid_max = 0;
135063 + init_ccsrmempeek();
135064 + if (qman_ccsr_start) {
135065 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
135066 + /* extract the size of the FQD window */
135067 + reg = reg & 0x3f;
135068 + /* calculate valid frame queue descriptor range */
135069 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
135070 + }
135071 + }
135072 + dfs_root = debugfs_create_dir("qman", NULL);
135073 + fqd_root = debugfs_create_dir("fqd", dfs_root);
135074 + if (dfs_root == NULL || fqd_root == NULL) {
135075 + ret = -ENOMEM;
135076 + pr_err("Cannot create qman/fqd debugfs dir\n");
135077 + goto _return;
135078 + }
135079 + if (fqid_max) {
135080 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
135081 + NULL, &qman_ccsrmempeek_fops);
135082 + }
135083 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
135084 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
135085 +
135086 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
135087 + &query_fq_fields_data, &query_fq_fields_fops);
135088 +
135089 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
135090 + &query_wq_lengths_data, &query_wq_lengths_fops);
135091 +
135092 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
135093 + &query_cgr_data, &query_cgr_fops);
135094 +
135095 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
135096 + NULL, &query_congestion_fops);
135097 +
135098 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
135099 + NULL, &testwrite_cgr_fops);
135100 +
135101 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
135102 + NULL, &teswrite_cgr_cgrid_fops);
135103 +
135104 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
135105 + NULL, &teswrite_cgr_ibcnt_fops);
135106 +
135107 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
135108 + &query_ccgr_data, &query_ccgr_fops);
135109 + /* Create files with fqd_root as parent */
135110 +
135111 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
135112 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
135113 +
135114 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
135115 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
135116 + &qman_fqd_state_fops);
135117 +
135118 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
135119 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
135120 + &qman_fqd_state_fops);
135121 +
135122 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
135123 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
135124 + &qman_fqd_state_fops);
135125 +
135126 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
135127 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
135128 + &qman_fqd_state_fops);
135129 +
135130 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
135131 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
135132 + &qman_fqd_state_fops);
135133 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
135134 + &query_cq_fields_data, &query_cq_fields_fops);
135135 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
135136 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
135137 +
135138 +
135139 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
135140 +
135141 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
135142 +
135143 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
135144 +
135145 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
135146 +
135147 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
135148 +
135149 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
135150 +
135151 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
135152 +
135153 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
135154 +
135155 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
135156 +
135157 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
135158 +
135159 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
135160 +
135161 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
135162 +
135163 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
135164 +
135165 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
135166 +
135167 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
135168 +
135169 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
135170 +
135171 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
135172 +
135173 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
135174 +
135175 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
135176 + NULL, &qman_fqd_summary_fops);
135177 +
135178 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
135179 + NULL, &qman_fqd_dest_wq_fops);
135180 +
135181 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
135182 + NULL, &qman_fqd_cred_fops);
135183 +
135184 + return 0;
135185 +
135186 +_return:
135187 + debugfs_remove_recursive(dfs_root);
135188 + return ret;
135189 +}
135190 +
135191 +static void __exit qman_debugfs_module_exit(void)
135192 +{
135193 + debugfs_remove_recursive(dfs_root);
135194 +}
135195 +
135196 +module_init(qman_debugfs_module_init);
135197 +module_exit(qman_debugfs_module_exit);
135198 +MODULE_LICENSE("Dual BSD/GPL");
135199 diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c
135200 new file mode 100644
135201 index 00000000..857ecd62
135202 --- /dev/null
135203 +++ b/drivers/staging/fsl_qbman/qman_driver.c
135204 @@ -0,0 +1,977 @@
135205 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135206 + *
135207 + * Redistribution and use in source and binary forms, with or without
135208 + * modification, are permitted provided that the following conditions are met:
135209 + * * Redistributions of source code must retain the above copyright
135210 + * notice, this list of conditions and the following disclaimer.
135211 + * * Redistributions in binary form must reproduce the above copyright
135212 + * notice, this list of conditions and the following disclaimer in the
135213 + * documentation and/or other materials provided with the distribution.
135214 + * * Neither the name of Freescale Semiconductor nor the
135215 + * names of its contributors may be used to endorse or promote products
135216 + * derived from this software without specific prior written permission.
135217 + *
135218 + *
135219 + * ALTERNATIVELY, this software may be distributed under the terms of the
135220 + * GNU General Public License ("GPL") as published by the Free Software
135221 + * Foundation, either version 2 of that License or (at your option) any
135222 + * later version.
135223 + *
135224 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135225 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135226 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135227 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135228 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135229 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135230 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135231 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135232 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135233 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135234 + */
135235 +
135236 +#include "qman_private.h"
135237 +
135238 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
135239 +#ifdef CONFIG_HOTPLUG_CPU
135240 +#include <linux/cpu.h>
135241 +#endif
135242 +
135243 +/* Global variable containing revision id (even on non-control plane systems
135244 + * where CCSR isn't available) */
135245 +u16 qman_ip_rev;
135246 +EXPORT_SYMBOL(qman_ip_rev);
135247 +u8 qman_ip_cfg;
135248 +EXPORT_SYMBOL(qman_ip_cfg);
135249 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
135250 +EXPORT_SYMBOL(qm_channel_pool1);
135251 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
135252 +EXPORT_SYMBOL(qm_channel_caam);
135253 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
135254 +EXPORT_SYMBOL(qm_channel_pme);
135255 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
135256 +EXPORT_SYMBOL(qm_channel_dce);
135257 +u16 qman_portal_max;
135258 +EXPORT_SYMBOL(qman_portal_max);
135259 +
135260 +u32 qman_clk;
135261 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
135262 +/* the qman ceetm instances on the given SoC */
135263 +u8 num_ceetms;
135264 +
135265 +/* For these variables, and the portal-initialisation logic, the
135266 + * comments in bman_driver.c apply here so won't be repeated. */
135267 +static struct qman_portal *shared_portals[NR_CPUS];
135268 +static int num_shared_portals;
135269 +static int shared_portals_idx;
135270 +static LIST_HEAD(unused_pcfgs);
135271 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
135272 +
135273 +/* A SDQCR mask comprising all the available/visible pool channels */
135274 +static u32 pools_sdqcr;
135275 +
135276 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
135277 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
135278 +#define STR_FQID_RANGE "fsl,fqid-range"
135279 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
135280 +#define STR_CGRID_RANGE "fsl,cgrid-range"
135281 +
135282 +/* A "fsl,fqid-range" node; release the given range to the allocator */
135283 +static __init int fsl_fqid_range_init(struct device_node *node)
135284 +{
135285 + int ret;
135286 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
135287 + if (!range) {
135288 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
135289 + return -EINVAL;
135290 + }
135291 + if (ret != 8) {
135292 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
135293 + return -EINVAL;
135294 + }
135295 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135296 + pr_info("Qman: FQID allocator includes range %d:%d\n",
135297 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135298 + return 0;
135299 +}
135300 +
135301 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
135302 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
135303 +{
135304 + int ret;
135305 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135306 + if (!chanid) {
135307 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135308 + return -EINVAL;
135309 + }
135310 + if (ret != 8) {
135311 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135312 + return -EINVAL;
135313 + }
135314 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
135315 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
135316 + return 0;
135317 +}
135318 +
135319 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
135320 +static __init int fsl_pool_channel_range_init(struct device_node *node)
135321 +{
135322 + int ret;
135323 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135324 + if (!chanid) {
135325 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135326 + return -EINVAL;
135327 + }
135328 + if (ret != 8) {
135329 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135330 + return -EINVAL;
135331 + }
135332 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135333 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
135334 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135335 + return 0;
135336 +}
135337 +
135338 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
135339 +static __init int fsl_cgrid_range_init(struct device_node *node)
135340 +{
135341 + struct qman_cgr cgr;
135342 + int ret, errors = 0;
135343 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
135344 + if (!range) {
135345 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
135346 + return -EINVAL;
135347 + }
135348 + if (ret != 8) {
135349 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
135350 + return -EINVAL;
135351 + }
135352 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135353 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
135354 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135355 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
135356 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
135357 + if (ret)
135358 + errors++;
135359 + }
135360 + if (errors)
135361 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
135362 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
135363 + return 0;
135364 +}
135365 +
135366 +static __init int fsl_ceetm_init(struct device_node *node)
135367 +{
135368 + enum qm_dc_portal dcp_portal;
135369 + struct qm_ceetm_sp *sp;
135370 + struct qm_ceetm_lni *lni;
135371 + int ret, i;
135372 + const u32 *range;
135373 +
135374 + /* Find LFQID range */
135375 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
135376 + if (!range) {
135377 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
135378 + node->full_name);
135379 + return -EINVAL;
135380 + }
135381 + if (ret != 8) {
135382 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
135383 + " %s\n", node->full_name);
135384 + return -EINVAL;
135385 + }
135386 +
135387 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
135388 + if (dcp_portal > qm_dc_portal_fman1) {
135389 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
135390 + return -EINVAL;
135391 + }
135392 +
135393 + if (dcp_portal == qm_dc_portal_fman0)
135394 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135395 + if (dcp_portal == qm_dc_portal_fman1)
135396 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135397 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
135398 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135399 +
135400 + qman_ceetms[dcp_portal].idx = dcp_portal;
135401 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
135402 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
135403 +
135404 + /* Find Sub-portal range */
135405 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
135406 + if (!range) {
135407 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
135408 + return -EINVAL;
135409 + }
135410 + if (ret != 8) {
135411 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
135412 + node->full_name);
135413 + return -EINVAL;
135414 + }
135415 +
135416 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135417 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
135418 + if (!sp) {
135419 + pr_err("Can't alloc memory for sub-portal %d\n",
135420 + range[0] + i);
135421 + return -ENOMEM;
135422 + }
135423 + sp->idx = be32_to_cpu(range[0]) + i;
135424 + sp->dcp_idx = dcp_portal;
135425 + sp->is_claimed = 0;
135426 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
135427 + sp++;
135428 + }
135429 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
135430 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135431 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
135432 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
135433 +
135434 + /* Find LNI range */
135435 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
135436 + if (!range) {
135437 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
135438 + return -EINVAL;
135439 + }
135440 + if (ret != 8) {
135441 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
135442 + node->full_name);
135443 + return -EINVAL;
135444 + }
135445 +
135446 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135447 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
135448 + if (!lni) {
135449 + pr_err("Can't alloc memory for LNI %d\n",
135450 + range[0] + i);
135451 + return -ENOMEM;
135452 + }
135453 + lni->idx = be32_to_cpu(range[0]) + i;
135454 + lni->dcp_idx = dcp_portal;
135455 + lni->is_claimed = 0;
135456 + INIT_LIST_HEAD(&lni->channels);
135457 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
135458 + lni++;
135459 + }
135460 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
135461 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135462 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
135463 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
135464 +
135465 + /* Find CEETM channel range */
135466 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
135467 + if (!range) {
135468 + pr_err("No fsl,ceetm-channel-range in node %s\n",
135469 + node->full_name);
135470 + return -EINVAL;
135471 + }
135472 + if (ret != 8) {
135473 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
135474 + "%s\n", node->full_name);
135475 + return -EINVAL;
135476 + }
135477 +
135478 + if (dcp_portal == qm_dc_portal_fman0)
135479 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135480 + if (dcp_portal == qm_dc_portal_fman1)
135481 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135482 + pr_debug("Qman: The channel allocator of CEETM %d includes"
135483 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135484 +
135485 + /* Set CEETM PRES register */
135486 + ret = qman_ceetm_set_prescaler(dcp_portal);
135487 + if (ret)
135488 + return ret;
135489 + return 0;
135490 +}
135491 +
135492 +static void qman_get_ip_revision(struct device_node *dn)
135493 +{
135494 + u16 ip_rev = 0;
135495 + u8 ip_cfg = QMAN_REV_CFG_0;
135496 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135497 + if (!of_device_is_available(dn))
135498 + continue;
135499 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
135500 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
135501 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
135502 + BUG_ON(1);
135503 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
135504 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
135505 + ip_rev = QMAN_REV11;
135506 + qman_portal_max = 10;
135507 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
135508 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
135509 + ip_rev = QMAN_REV12;
135510 + qman_portal_max = 10;
135511 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
135512 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
135513 + ip_rev = QMAN_REV20;
135514 + qman_portal_max = 3;
135515 + } else if (of_device_is_compatible(dn,
135516 + "fsl,qman-portal-3.0.0")) {
135517 + ip_rev = QMAN_REV30;
135518 + qman_portal_max = 50;
135519 + } else if (of_device_is_compatible(dn,
135520 + "fsl,qman-portal-3.0.1")) {
135521 + ip_rev = QMAN_REV30;
135522 + qman_portal_max = 25;
135523 + ip_cfg = QMAN_REV_CFG_1;
135524 + } else if (of_device_is_compatible(dn,
135525 + "fsl,qman-portal-3.1.0")) {
135526 + ip_rev = QMAN_REV31;
135527 + qman_portal_max = 50;
135528 + } else if (of_device_is_compatible(dn,
135529 + "fsl,qman-portal-3.1.1")) {
135530 + ip_rev = QMAN_REV31;
135531 + qman_portal_max = 25;
135532 + ip_cfg = QMAN_REV_CFG_1;
135533 + } else if (of_device_is_compatible(dn,
135534 + "fsl,qman-portal-3.1.2")) {
135535 + ip_rev = QMAN_REV31;
135536 + qman_portal_max = 18;
135537 + ip_cfg = QMAN_REV_CFG_2;
135538 + } else if (of_device_is_compatible(dn,
135539 + "fsl,qman-portal-3.1.3")) {
135540 + ip_rev = QMAN_REV31;
135541 + qman_portal_max = 10;
135542 + ip_cfg = QMAN_REV_CFG_3;
135543 + } else if (of_device_is_compatible(dn,
135544 + "fsl,qman-portal-3.2.0")) {
135545 + ip_rev = QMAN_REV32;
135546 + qman_portal_max = 10;
135547 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
135548 + } else if (of_device_is_compatible(dn,
135549 + "fsl,qman-portal-3.2.1")) {
135550 + ip_rev = QMAN_REV32;
135551 + qman_portal_max = 10;
135552 + ip_cfg = QMAN_REV_CFG_3;
135553 + } else {
135554 + pr_warn("unknown QMan version in portal node,"
135555 + "default to rev1.1\n");
135556 + ip_rev = QMAN_REV11;
135557 + qman_portal_max = 10;
135558 + }
135559 +
135560 + if (!qman_ip_rev) {
135561 + if (ip_rev) {
135562 + qman_ip_rev = ip_rev;
135563 + qman_ip_cfg = ip_cfg;
135564 + } else {
135565 + pr_warn("unknown Qman version,"
135566 + " default to rev1.1\n");
135567 + qman_ip_rev = QMAN_REV11;
135568 + qman_ip_cfg = QMAN_REV_CFG_0;
135569 + }
135570 + } else if (ip_rev && (qman_ip_rev != ip_rev))
135571 + pr_warn("Revision=0x%04x, but portal '%s' has"
135572 + " 0x%04x\n",
135573 + qman_ip_rev, dn->full_name, ip_rev);
135574 + if (qman_ip_rev == ip_rev)
135575 + break;
135576 + }
135577 +}
135578 +
135579 +/* Parse a portal node, perform generic mapping duties and return the config. It
135580 + * is not known at this stage for what purpose (or even if) the portal will be
135581 + * used. */
135582 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
135583 +{
135584 + struct qm_portal_config *pcfg;
135585 + const u32 *index_p;
135586 + u32 index, channel;
135587 + int irq, ret;
135588 + resource_size_t len;
135589 +
135590 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
135591 + if (!pcfg) {
135592 + pr_err("can't allocate portal config");
135593 + return NULL;
135594 + }
135595 +
135596 + /*
135597 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
135598 + * 'struct device' in order to get the PAMU stashing setup and the QMan
135599 + * portal [driver] won't function at all without ring stashing
135600 + *
135601 + * Making the QMan portal driver nice and proper is part of the
135602 + * upstreaming effort
135603 + */
135604 + pcfg->dev.bus = &platform_bus_type;
135605 + pcfg->dev.of_node = node;
135606 +#ifdef CONFIG_FSL_PAMU
135607 + pcfg->dev.archdata.iommu_domain = NULL;
135608 +#endif
135609 +
135610 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
135611 + &pcfg->addr_phys[DPA_PORTAL_CE]);
135612 + if (ret) {
135613 + pr_err("Can't get %s property '%s'\n", node->full_name,
135614 + "reg::CE");
135615 + goto err;
135616 + }
135617 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
135618 + &pcfg->addr_phys[DPA_PORTAL_CI]);
135619 + if (ret) {
135620 + pr_err("Can't get %s property '%s'\n", node->full_name,
135621 + "reg::CI");
135622 + goto err;
135623 + }
135624 + index_p = of_get_property(node, "cell-index", &ret);
135625 + if (!index_p || (ret != 4)) {
135626 + pr_err("Can't get %s property '%s'\n", node->full_name,
135627 + "cell-index");
135628 + goto err;
135629 + }
135630 + index = be32_to_cpu(*index_p);
135631 + if (index >= qman_portal_max) {
135632 + pr_err("QMan portal index %d is beyond max (%d)\n",
135633 + index, qman_portal_max);
135634 + goto err;
135635 + }
135636 +
135637 + channel = index + QM_CHANNEL_SWPORTAL0;
135638 + pcfg->public_cfg.channel = channel;
135639 + pcfg->public_cfg.cpu = -1;
135640 + irq = irq_of_parse_and_map(node, 0);
135641 + if (irq == 0) {
135642 + pr_err("Can't get %s property '%s'\n", node->full_name,
135643 + "interrupts");
135644 + goto err;
135645 + }
135646 + pcfg->public_cfg.irq = irq;
135647 + pcfg->public_cfg.index = index;
135648 +#ifdef CONFIG_FSL_QMAN_CONFIG
135649 + /* We need the same LIODN offset for all portals */
135650 + qman_liodn_fixup(pcfg->public_cfg.channel);
135651 +#endif
135652 +
135653 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
135654 + if (len != (unsigned long)len)
135655 + goto err;
135656 +
135657 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
135658 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
135659 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135660 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
135661 +
135662 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
135663 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135664 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
135665 +#else
135666 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
135667 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135668 + (unsigned long)len,
135669 + 0);
135670 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
135671 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135672 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
135673 + _PAGE_GUARDED | _PAGE_NO_CACHE);
135674 +#endif
135675 + return pcfg;
135676 +err:
135677 + kfree(pcfg);
135678 + return NULL;
135679 +}
135680 +
135681 +static struct qm_portal_config *get_pcfg(struct list_head *list)
135682 +{
135683 + struct qm_portal_config *pcfg;
135684 + if (list_empty(list))
135685 + return NULL;
135686 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
135687 + list_del(&pcfg->list);
135688 + return pcfg;
135689 +}
135690 +
135691 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
135692 +{
135693 + struct qm_portal_config *pcfg;
135694 + if (list_empty(list))
135695 + return NULL;
135696 + list_for_each_entry(pcfg, list, list) {
135697 + if (pcfg->public_cfg.index == idx) {
135698 + list_del(&pcfg->list);
135699 + return pcfg;
135700 + }
135701 + }
135702 + return NULL;
135703 +}
135704 +
135705 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
135706 +{
135707 +#ifdef CONFIG_FSL_PAMU
135708 + int ret;
135709 + int window_count = 1;
135710 + struct iommu_domain_geometry geom_attr;
135711 + struct pamu_stash_attribute stash_attr;
135712 +
135713 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135714 + if (!pcfg->iommu_domain) {
135715 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135716 + __func__);
135717 + goto _no_iommu;
135718 + }
135719 + geom_attr.aperture_start = 0;
135720 + geom_attr.aperture_end =
135721 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135722 + geom_attr.force_aperture = true;
135723 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135724 + &geom_attr);
135725 + if (ret < 0) {
135726 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135727 + __func__, ret);
135728 + goto _iommu_domain_free;
135729 + }
135730 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135731 + &window_count);
135732 + if (ret < 0) {
135733 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135734 + __func__, ret);
135735 + goto _iommu_domain_free;
135736 + }
135737 + stash_attr.cpu = cpu;
135738 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135739 + /* set stash information for the window */
135740 + stash_attr.window = 0;
135741 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135742 + DOMAIN_ATTR_FSL_PAMU_STASH,
135743 + &stash_attr);
135744 + if (ret < 0) {
135745 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135746 + __func__, ret);
135747 + goto _iommu_domain_free;
135748 + }
135749 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135750 + IOMMU_READ | IOMMU_WRITE);
135751 + if (ret < 0) {
135752 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135753 + __func__, ret);
135754 + goto _iommu_domain_free;
135755 + }
135756 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135757 + if (ret < 0) {
135758 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135759 + __func__, ret);
135760 + goto _iommu_domain_free;
135761 + }
135762 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135763 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135764 + &window_count);
135765 + if (ret < 0) {
135766 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135767 + __func__, ret);
135768 + goto _iommu_detach_device;
135769 + }
135770 +
135771 +_no_iommu:
135772 +#endif
135773 +#ifdef CONFIG_FSL_QMAN_CONFIG
135774 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135775 +#endif
135776 + pr_warn("Failed to set QMan portal's stash request queue\n");
135777 +
135778 + return;
135779 +
135780 +#ifdef CONFIG_FSL_PAMU
135781 +_iommu_detach_device:
135782 + iommu_detach_device(pcfg->iommu_domain, NULL);
135783 +_iommu_domain_free:
135784 + iommu_domain_free(pcfg->iommu_domain);
135785 +#endif
135786 +}
135787 +
135788 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135789 +{
135790 + struct qm_portal_config *ret;
135791 + spin_lock(&unused_pcfgs_lock);
135792 + if (idx == QBMAN_ANY_PORTAL_IDX)
135793 + ret = get_pcfg(&unused_pcfgs);
135794 + else
135795 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135796 + spin_unlock(&unused_pcfgs_lock);
135797 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
135798 + * set the portal to use the stashing request queue corresonding to the
135799 + * cpu as well. The user-space driver assumption is that the pthread has
135800 + * to already be affine to one cpu only before opening a portal. If that
135801 + * check is circumvented, the only risk is a performance degradation -
135802 + * stashing will go to whatever cpu they happened to be running on when
135803 + * opening the device file, and if that isn't the cpu they subsequently
135804 + * bind to and do their polling on, tough. */
135805 + if (ret)
135806 + portal_set_cpu(ret, hard_smp_processor_id());
135807 + return ret;
135808 +}
135809 +
135810 +struct qm_portal_config *qm_get_unused_portal(void)
135811 +{
135812 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
135813 +}
135814 +
135815 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
135816 +{
135817 + spin_lock(&unused_pcfgs_lock);
135818 + list_add(&pcfg->list, &unused_pcfgs);
135819 + spin_unlock(&unused_pcfgs_lock);
135820 +}
135821 +
135822 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
135823 +{
135824 + struct qman_portal *p;
135825 +
135826 + pcfg->iommu_domain = NULL;
135827 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
135828 + p = qman_create_affine_portal(pcfg, NULL);
135829 + if (p) {
135830 + u32 irq_sources = 0;
135831 + /* Determine what should be interrupt-vs-poll driven */
135832 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
135833 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
135834 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
135835 +#endif
135836 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
135837 + irq_sources |= QM_PIRQ_DQRI;
135838 +#endif
135839 + qman_p_irqsource_add(p, irq_sources);
135840 + pr_info("Qman portal %sinitialised, cpu %d\n",
135841 + pcfg->public_cfg.is_shared ? "(shared) " : "",
135842 + pcfg->public_cfg.cpu);
135843 + } else
135844 + pr_crit("Qman portal failure on cpu %d\n",
135845 + pcfg->public_cfg.cpu);
135846 + return p;
135847 +}
135848 +
135849 +static void init_slave(int cpu)
135850 +{
135851 + struct qman_portal *p;
135852 + struct cpumask oldmask = current->cpus_allowed;
135853 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
135854 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
135855 + if (!p)
135856 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
135857 + else
135858 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
135859 + set_cpus_allowed_ptr(current, &oldmask);
135860 + if (shared_portals_idx >= num_shared_portals)
135861 + shared_portals_idx = 0;
135862 +}
135863 +
135864 +static struct cpumask want_unshared __initdata;
135865 +static struct cpumask want_shared __initdata;
135866 +
135867 +static int __init parse_qportals(char *str)
135868 +{
135869 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
135870 + "qportals");
135871 +}
135872 +__setup("qportals=", parse_qportals);
135873 +
135874 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
135875 + unsigned int cpu)
135876 +{
135877 +#ifdef CONFIG_FSL_PAMU
135878 + struct pamu_stash_attribute stash_attr;
135879 + int ret;
135880 +
135881 + if (pcfg->iommu_domain) {
135882 + stash_attr.cpu = cpu;
135883 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135884 + /* set stash information for the window */
135885 + stash_attr.window = 0;
135886 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135887 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
135888 + if (ret < 0) {
135889 + pr_err("Failed to update pamu stash setting\n");
135890 + return;
135891 + }
135892 + }
135893 +#endif
135894 +#ifdef CONFIG_FSL_QMAN_CONFIG
135895 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135896 + pr_warn("Failed to update portal's stash request queue\n");
135897 +#endif
135898 +}
135899 +
135900 +static int qman_offline_cpu(unsigned int cpu)
135901 +{
135902 + struct qman_portal *p;
135903 + const struct qm_portal_config *pcfg;
135904 + p = (struct qman_portal *)affine_portals[cpu];
135905 + if (p) {
135906 + pcfg = qman_get_qm_portal_config(p);
135907 + if (pcfg) {
135908 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
135909 + qman_portal_update_sdest(pcfg, 0);
135910 + }
135911 + }
135912 + return 0;
135913 +}
135914 +
135915 +#ifdef CONFIG_HOTPLUG_CPU
135916 +static int qman_online_cpu(unsigned int cpu)
135917 +{
135918 + struct qman_portal *p;
135919 + const struct qm_portal_config *pcfg;
135920 + p = (struct qman_portal *)affine_portals[cpu];
135921 + if (p) {
135922 + pcfg = qman_get_qm_portal_config(p);
135923 + if (pcfg) {
135924 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
135925 + qman_portal_update_sdest(pcfg, cpu);
135926 + }
135927 + }
135928 + return 0;
135929 +}
135930 +
135931 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
135932 + unsigned long action, void *hcpu)
135933 +{
135934 + unsigned int cpu = (unsigned long)hcpu;
135935 +
135936 + switch (action) {
135937 + case CPU_ONLINE:
135938 + case CPU_ONLINE_FROZEN:
135939 + qman_online_cpu(cpu);
135940 + break;
135941 + case CPU_DOWN_PREPARE:
135942 + case CPU_DOWN_PREPARE_FROZEN:
135943 + qman_offline_cpu(cpu);
135944 + default:
135945 + break;
135946 + }
135947 + return NOTIFY_OK;
135948 +}
135949 +
135950 +static struct notifier_block qman_hotplug_cpu_notifier = {
135951 + .notifier_call = qman_hotplug_cpu_callback,
135952 +};
135953 +#endif /* CONFIG_HOTPLUG_CPU */
135954 +
135955 +__init int qman_init(void)
135956 +{
135957 + struct cpumask slave_cpus;
135958 + struct cpumask unshared_cpus = *cpu_none_mask;
135959 + struct cpumask shared_cpus = *cpu_none_mask;
135960 + LIST_HEAD(unshared_pcfgs);
135961 + LIST_HEAD(shared_pcfgs);
135962 + struct device_node *dn;
135963 + struct qm_portal_config *pcfg;
135964 + struct qman_portal *p;
135965 + int cpu, ret;
135966 + const u32 *clk;
135967 + struct cpumask offline_cpus;
135968 +
135969 + /* Initialise the Qman (CCSR) device */
135970 + for_each_compatible_node(dn, NULL, "fsl,qman") {
135971 + if (!qman_init_ccsr(dn))
135972 + pr_info("Qman err interrupt handler present\n");
135973 + else
135974 + pr_err("Qman CCSR setup failed\n");
135975 +
135976 + clk = of_get_property(dn, "clock-frequency", NULL);
135977 + if (!clk)
135978 + pr_warn("Can't find Qman clock frequency\n");
135979 + else
135980 + qman_clk = be32_to_cpu(*clk);
135981 + }
135982 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135983 + /* Setup lookup table for FQ demux */
135984 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
135985 + if (ret)
135986 + return ret;
135987 +#endif
135988 +
135989 + /* Get qman ip revision */
135990 + qman_get_ip_revision(dn);
135991 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
135992 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
135993 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
135994 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
135995 + }
135996 +
135997 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
135998 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
135999 +
136000 + /*
136001 + * Parse the ceetm node to get how many ceetm instances are supported
136002 + * on the current silicon. num_ceetms must be confirmed before portals
136003 + * are intiailized.
136004 + */
136005 + num_ceetms = 0;
136006 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
136007 + num_ceetms++;
136008 +
136009 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
136010 + * are initialised.) */
136011 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
136012 + ret = fsl_pool_channel_range_sdqcr(dn);
136013 + if (ret)
136014 + return ret;
136015 + }
136016 +
136017 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
136018 + /* Initialise portals. See bman_driver.c for comments */
136019 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
136020 + if (!of_device_is_available(dn))
136021 + continue;
136022 + pcfg = parse_pcfg(dn);
136023 + if (pcfg) {
136024 + pcfg->public_cfg.pools = pools_sdqcr;
136025 + list_add_tail(&pcfg->list, &unused_pcfgs);
136026 + }
136027 + }
136028 + for_each_possible_cpu(cpu) {
136029 + if (cpumask_test_cpu(cpu, &want_shared)) {
136030 + pcfg = get_pcfg(&unused_pcfgs);
136031 + if (!pcfg)
136032 + break;
136033 + pcfg->public_cfg.cpu = cpu;
136034 + list_add_tail(&pcfg->list, &shared_pcfgs);
136035 + cpumask_set_cpu(cpu, &shared_cpus);
136036 + }
136037 + if (cpumask_test_cpu(cpu, &want_unshared)) {
136038 + if (cpumask_test_cpu(cpu, &shared_cpus))
136039 + continue;
136040 + pcfg = get_pcfg(&unused_pcfgs);
136041 + if (!pcfg)
136042 + break;
136043 + pcfg->public_cfg.cpu = cpu;
136044 + list_add_tail(&pcfg->list, &unshared_pcfgs);
136045 + cpumask_set_cpu(cpu, &unshared_cpus);
136046 + }
136047 + }
136048 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
136049 + for_each_online_cpu(cpu) {
136050 + pcfg = get_pcfg(&unused_pcfgs);
136051 + if (!pcfg)
136052 + break;
136053 + pcfg->public_cfg.cpu = cpu;
136054 + list_add_tail(&pcfg->list, &unshared_pcfgs);
136055 + cpumask_set_cpu(cpu, &unshared_cpus);
136056 + }
136057 + }
136058 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
136059 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
136060 + if (cpumask_empty(&slave_cpus)) {
136061 + if (!list_empty(&shared_pcfgs)) {
136062 + cpumask_or(&unshared_cpus, &unshared_cpus,
136063 + &shared_cpus);
136064 + cpumask_clear(&shared_cpus);
136065 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
136066 + INIT_LIST_HEAD(&shared_pcfgs);
136067 + }
136068 + } else {
136069 + if (list_empty(&shared_pcfgs)) {
136070 + pcfg = get_pcfg(&unshared_pcfgs);
136071 + if (!pcfg) {
136072 + pr_crit("No QMan portals available!\n");
136073 + return 0;
136074 + }
136075 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
136076 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
136077 + list_add_tail(&pcfg->list, &shared_pcfgs);
136078 + }
136079 + }
136080 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
136081 + pcfg->public_cfg.is_shared = 0;
136082 + p = init_pcfg(pcfg);
136083 + if (!p) {
136084 + pr_crit("Unable to configure portals\n");
136085 + return 0;
136086 + }
136087 + }
136088 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
136089 + pcfg->public_cfg.is_shared = 1;
136090 + p = init_pcfg(pcfg);
136091 + if (p)
136092 + shared_portals[num_shared_portals++] = p;
136093 + }
136094 + if (!cpumask_empty(&slave_cpus))
136095 + for_each_cpu(cpu, &slave_cpus)
136096 + init_slave(cpu);
136097 + pr_info("Qman portals initialised\n");
136098 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
136099 + for_each_cpu(cpu, &offline_cpus)
136100 + qman_offline_cpu(cpu);
136101 +#ifdef CONFIG_HOTPLUG_CPU
136102 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
136103 +#endif
136104 + return 0;
136105 +}
136106 +
136107 +__init int qman_resource_init(void)
136108 +{
136109 + struct device_node *dn;
136110 + int ret;
136111 +
136112 + /* Initialise FQID allocation ranges */
136113 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
136114 + ret = fsl_fqid_range_init(dn);
136115 + if (ret)
136116 + return ret;
136117 + }
136118 + /* Initialise CGRID allocation ranges */
136119 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
136120 + ret = fsl_cgrid_range_init(dn);
136121 + if (ret)
136122 + return ret;
136123 + }
136124 + /* Parse pool channels into the allocator. (Must happen after portals
136125 + * are initialised.) */
136126 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
136127 + ret = fsl_pool_channel_range_init(dn);
136128 + if (ret)
136129 + return ret;
136130 + }
136131 +
136132 + /* Parse CEETM */
136133 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
136134 + ret = fsl_ceetm_init(dn);
136135 + if (ret)
136136 + return ret;
136137 + }
136138 + return 0;
136139 +}
136140 +
136141 +#ifdef CONFIG_SUSPEND
136142 +void suspend_unused_qportal(void)
136143 +{
136144 + struct qm_portal_config *pcfg;
136145 +
136146 + if (list_empty(&unused_pcfgs))
136147 + return;
136148 +
136149 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
136150 +#ifdef CONFIG_PM_DEBUG
136151 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
136152 +#endif
136153 + /* save isdr, disable all via isdr, clear isr */
136154 + pcfg->saved_isdr =
136155 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
136156 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
136157 + 0xe08);
136158 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
136159 + 0xe00);
136160 + }
136161 + return;
136162 +}
136163 +
136164 +void resume_unused_qportal(void)
136165 +{
136166 + struct qm_portal_config *pcfg;
136167 +
136168 + if (list_empty(&unused_pcfgs))
136169 + return;
136170 +
136171 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
136172 +#ifdef CONFIG_PM_DEBUG
136173 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
136174 +#endif
136175 + /* restore isdr */
136176 + __raw_writel(pcfg->saved_isdr,
136177 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
136178 + }
136179 + return;
136180 +}
136181 +#endif
136182 diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
136183 new file mode 100644
136184 index 00000000..1651e62c
136185 --- /dev/null
136186 +++ b/drivers/staging/fsl_qbman/qman_high.c
136187 @@ -0,0 +1,5669 @@
136188 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
136189 + *
136190 + * Redistribution and use in source and binary forms, with or without
136191 + * modification, are permitted provided that the following conditions are met:
136192 + * * Redistributions of source code must retain the above copyright
136193 + * notice, this list of conditions and the following disclaimer.
136194 + * * Redistributions in binary form must reproduce the above copyright
136195 + * notice, this list of conditions and the following disclaimer in the
136196 + * documentation and/or other materials provided with the distribution.
136197 + * * Neither the name of Freescale Semiconductor nor the
136198 + * names of its contributors may be used to endorse or promote products
136199 + * derived from this software without specific prior written permission.
136200 + *
136201 + *
136202 + * ALTERNATIVELY, this software may be distributed under the terms of the
136203 + * GNU General Public License ("GPL") as published by the Free Software
136204 + * Foundation, either version 2 of that License or (at your option) any
136205 + * later version.
136206 + *
136207 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
136208 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
136209 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
136210 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
136211 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
136212 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
136213 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
136214 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
136215 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
136216 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136217 + */
136218 +
136219 +#include "qman_low.h"
136220 +
136221 +/* Compilation constants */
136222 +#define DQRR_MAXFILL 15
136223 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
136224 +#define IRQNAME "QMan portal %d"
136225 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
136226 +
136227 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
136228 + * positive, and rounding to the closest value if it's zero. NB, this macro
136229 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
136230 + * that are compatible with this. NB, these arguments should not be expressions
136231 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
136232 + * in "some_value++" as a parameter to the macro! */
136233 +#define ROUNDING(n, d, r) \
136234 + (((r) < 0) ? div64_u64((n), (d)) : \
136235 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
136236 + div64_u64(((n) + ((d) / 2)), (d))))
136237 +
136238 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
136239 + * inter-processor locking only. Note, FQLOCK() is always called either under a
136240 + * local_irq_save() or from interrupt context - hence there's no need for irq
136241 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
136242 + * the "irq en/disable" machinery isn't recursive...). */
136243 +#define FQLOCK(fq) \
136244 + do { \
136245 + struct qman_fq *__fq478 = (fq); \
136246 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136247 + spin_lock(&__fq478->fqlock); \
136248 + } while (0)
136249 +#define FQUNLOCK(fq) \
136250 + do { \
136251 + struct qman_fq *__fq478 = (fq); \
136252 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136253 + spin_unlock(&__fq478->fqlock); \
136254 + } while (0)
136255 +
136256 +static inline void fq_set(struct qman_fq *fq, u32 mask)
136257 +{
136258 + set_bits(mask, &fq->flags);
136259 +}
136260 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
136261 +{
136262 + clear_bits(mask, &fq->flags);
136263 +}
136264 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
136265 +{
136266 + return fq->flags & mask;
136267 +}
136268 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
136269 +{
136270 + return !(fq->flags & mask);
136271 +}
136272 +
136273 +struct qman_portal {
136274 + struct qm_portal p;
136275 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
136276 + unsigned long irq_sources;
136277 + u32 use_eqcr_ci_stashing;
136278 + u32 slowpoll; /* only used when interrupts are off */
136279 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
136280 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136281 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
136282 +#endif
136283 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136284 + raw_spinlock_t sharing_lock; /* only used if is_shared */
136285 + int is_shared;
136286 + struct qman_portal *sharing_redirect;
136287 +#endif
136288 + u32 sdqcr;
136289 + int dqrr_disable_ref;
136290 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
136291 + * handler is called instead. */
136292 + qman_cb_dc_ern cb_dc_ern;
136293 + /* When the cpu-affine portal is activated, this is non-NULL */
136294 + const struct qm_portal_config *config;
136295 + /* This is needed for providing a non-NULL device to dma_map_***() */
136296 + struct platform_device *pdev;
136297 + struct dpa_rbtree retire_table;
136298 + char irqname[MAX_IRQNAME];
136299 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
136300 + struct qman_cgrs *cgrs;
136301 + /* linked-list of CSCN handlers. */
136302 + struct list_head cgr_cbs;
136303 + /* list lock */
136304 + spinlock_t cgr_lock;
136305 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
136306 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
136307 + /* 256-element array, each is a linked-list of CCSCN handlers. */
136308 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
136309 + /* list lock */
136310 + spinlock_t ccgr_lock;
136311 + /* track if memory was allocated by the driver */
136312 + u8 alloced;
136313 + /* power management data */
136314 + u32 save_isdr;
136315 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136316 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
136317 + * do byte swaps of DQRR read only memory. First entry must be aligned
136318 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
136319 + * address (6 bits for address shift + 4 bits for the DQRR size).
136320 + */
136321 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
136322 +#endif
136323 +};
136324 +
136325 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136326 +#define PORTAL_IRQ_LOCK(p, irqflags) \
136327 + do { \
136328 + if ((p)->is_shared) \
136329 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
136330 + else \
136331 + local_irq_save(irqflags); \
136332 + } while (0)
136333 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
136334 + do { \
136335 + if ((p)->is_shared) \
136336 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
136337 + irqflags); \
136338 + else \
136339 + local_irq_restore(irqflags); \
136340 + } while (0)
136341 +#else
136342 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
136343 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
136344 +#endif
136345 +
136346 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
136347 + * not have a portal-specific handler. */
136348 +static qman_cb_dc_ern cb_dc_ern;
136349 +
136350 +static cpumask_t affine_mask;
136351 +static DEFINE_SPINLOCK(affine_mask_lock);
136352 +static u16 affine_channels[NR_CPUS];
136353 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
136354 +void *affine_portals[NR_CPUS];
136355 +
136356 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
136357 +static inline struct qman_portal *get_raw_affine_portal(void)
136358 +{
136359 + return &get_cpu_var(qman_affine_portal);
136360 +}
136361 +/* For ops that can redirect, this obtains the portal to use */
136362 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136363 +static inline struct qman_portal *get_affine_portal(void)
136364 +{
136365 + struct qman_portal *p = get_raw_affine_portal();
136366 + if (p->sharing_redirect)
136367 + return p->sharing_redirect;
136368 + return p;
136369 +}
136370 +#else
136371 +#define get_affine_portal() get_raw_affine_portal()
136372 +#endif
136373 +/* For every "get", there must be a "put" */
136374 +static inline void put_affine_portal(void)
136375 +{
136376 + put_cpu_var(qman_affine_portal);
136377 +}
136378 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
136379 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
136380 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
136381 + * context to remain as non-atomic during poll-triggered callbacks as it was
136382 + * when the poll API was first called (eg. NAPI), so we go out of our way in
136383 + * this case to not disable pre-emption. */
136384 +static inline struct qman_portal *get_poll_portal(void)
136385 +{
136386 + return &get_cpu_var(qman_affine_portal);
136387 +}
136388 +#define put_poll_portal()
136389 +
136390 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
136391 + * retirement notifications (the fact they are sometimes h/w-consumed means that
136392 + * contextB isn't always a s/w demux - and as we can't know which case it is
136393 + * when looking at the notification, we have to use the slow lookup for all of
136394 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
136395 + * (though at most one of them should be the consumer), so this table isn't for
136396 + * all FQs - FQs are added when retirement commands are issued, and removed when
136397 + * they complete, which also massively reduces the size of this table. */
136398 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
136399 +
136400 +/* This is what everything can wait on, even if it migrates to a different cpu
136401 + * to the one whose affine portal it is waiting on. */
136402 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
136403 +
136404 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
136405 +{
136406 + int ret = fqtree_push(&p->retire_table, fq);
136407 + if (ret)
136408 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
136409 + return ret;
136410 +}
136411 +
136412 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
136413 +{
136414 + fqtree_del(&p->retire_table, fq);
136415 +}
136416 +
136417 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
136418 +{
136419 + return fqtree_find(&p->retire_table, fqid);
136420 +}
136421 +
136422 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136423 +static void **qman_fq_lookup_table;
136424 +static size_t qman_fq_lookup_table_size;
136425 +
136426 +int qman_setup_fq_lookup_table(size_t num_entries)
136427 +{
136428 + num_entries++;
136429 + /* Allocate 1 more entry since the first entry is not used */
136430 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
136431 + if (!qman_fq_lookup_table) {
136432 + pr_err("QMan: Could not allocate fq lookup table\n");
136433 + return -ENOMEM;
136434 + }
136435 + qman_fq_lookup_table_size = num_entries;
136436 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
136437 + qman_fq_lookup_table,
136438 + (unsigned long)qman_fq_lookup_table_size);
136439 + return 0;
136440 +}
136441 +
136442 +/* global structure that maintains fq object mapping */
136443 +static DEFINE_SPINLOCK(fq_hash_table_lock);
136444 +
136445 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
136446 +{
136447 + u32 i;
136448 +
136449 + spin_lock(&fq_hash_table_lock);
136450 + /* Can't use index zero because this has special meaning
136451 + * in context_b field. */
136452 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
136453 + if (qman_fq_lookup_table[i] == NULL) {
136454 + *entry = i;
136455 + qman_fq_lookup_table[i] = fq;
136456 + spin_unlock(&fq_hash_table_lock);
136457 + return 0;
136458 + }
136459 + }
136460 + spin_unlock(&fq_hash_table_lock);
136461 + return -ENOMEM;
136462 +}
136463 +
136464 +static void clear_fq_table_entry(u32 entry)
136465 +{
136466 + spin_lock(&fq_hash_table_lock);
136467 + BUG_ON(entry >= qman_fq_lookup_table_size);
136468 + qman_fq_lookup_table[entry] = NULL;
136469 + spin_unlock(&fq_hash_table_lock);
136470 +}
136471 +
136472 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
136473 +{
136474 + BUG_ON(entry >= qman_fq_lookup_table_size);
136475 + return qman_fq_lookup_table[entry];
136476 +}
136477 +#endif
136478 +
136479 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
136480 +{
136481 + /* Byteswap the FQD to HW format */
136482 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
136483 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
136484 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
136485 + fqd->context_b = cpu_to_be32(fqd->context_b);
136486 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
136487 +}
136488 +
136489 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
136490 +{
136491 + /* Byteswap the FQD to CPU format */
136492 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
136493 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
136494 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
136495 + fqd->context_b = be32_to_cpu(fqd->context_b);
136496 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
136497 +}
136498 +
136499 +/* Swap a 40 bit address */
136500 +static inline u64 cpu_to_be40(u64 in)
136501 +{
136502 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136503 + return in;
136504 +#else
136505 + u64 out = 0;
136506 + u8 *p = (u8 *) &out;
136507 + p[0] = in >> 32;
136508 + p[1] = in >> 24;
136509 + p[2] = in >> 16;
136510 + p[3] = in >> 8;
136511 + p[4] = in >> 0;
136512 + return out;
136513 +#endif
136514 +}
136515 +static inline u64 be40_to_cpu(u64 in)
136516 +{
136517 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136518 + return in;
136519 +#else
136520 + u64 out = 0;
136521 + u8 *pout = (u8 *) &out;
136522 + u8 *pin = (u8 *) &in;
136523 + pout[0] = pin[4];
136524 + pout[1] = pin[3];
136525 + pout[2] = pin[2];
136526 + pout[3] = pin[1];
136527 + pout[4] = pin[0];
136528 + return out;
136529 +#endif
136530 +}
136531 +
136532 +/* Swap a 24 bit value */
136533 +static inline u32 cpu_to_be24(u32 in)
136534 +{
136535 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136536 + return in;
136537 +#else
136538 + u32 out = 0;
136539 + u8 *p = (u8 *) &out;
136540 + p[0] = in >> 16;
136541 + p[1] = in >> 8;
136542 + p[2] = in >> 0;
136543 + return out;
136544 +#endif
136545 +}
136546 +
136547 +static inline u32 be24_to_cpu(u32 in)
136548 +{
136549 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136550 + return in;
136551 +#else
136552 + u32 out = 0;
136553 + u8 *pout = (u8 *) &out;
136554 + u8 *pin = (u8 *) &in;
136555 + pout[0] = pin[2];
136556 + pout[1] = pin[1];
136557 + pout[2] = pin[0];
136558 + return out;
136559 +#endif
136560 +}
136561 +
136562 +static inline u64 be48_to_cpu(u64 in)
136563 +{
136564 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136565 + return in;
136566 +#else
136567 + u64 out = 0;
136568 + u8 *pout = (u8 *) &out;
136569 + u8 *pin = (u8 *) &in;
136570 +
136571 + pout[0] = pin[5];
136572 + pout[1] = pin[4];
136573 + pout[2] = pin[3];
136574 + pout[3] = pin[2];
136575 + pout[4] = pin[1];
136576 + pout[5] = pin[0];
136577 + return out;
136578 +#endif
136579 +}
136580 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
136581 +{
136582 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
136583 + fd->status = cpu_to_be32(fd->status);
136584 + fd->opaque = cpu_to_be32(fd->opaque);
136585 +}
136586 +
136587 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
136588 +{
136589 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
136590 + fd->status = be32_to_cpu(fd->status);
136591 + fd->opaque = be32_to_cpu(fd->opaque);
136592 +}
136593 +
136594 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
136595 +{
136596 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
136597 + cq_query->state = be16_to_cpu(cq_query->state);
136598 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
136599 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
136600 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
136601 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
136602 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
136603 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
136604 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
136605 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
136606 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
136607 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
136608 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
136609 +}
136610 +
136611 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
136612 +{
136613 + int i;
136614 +
136615 + ccgr_q->cm_query.cs_thres.hword =
136616 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
136617 + ccgr_q->cm_query.cs_thres_x.hword =
136618 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
136619 + ccgr_q->cm_query.td_thres.hword =
136620 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
136621 + ccgr_q->cm_query.wr_parm_g.word =
136622 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
136623 + ccgr_q->cm_query.wr_parm_y.word =
136624 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
136625 + ccgr_q->cm_query.wr_parm_r.word =
136626 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
136627 + ccgr_q->cm_query.cscn_targ_dcp =
136628 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
136629 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
136630 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
136631 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
136632 + ccgr_q->cm_query.cscn_targ_swp[i] =
136633 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
136634 +}
136635 +
136636 +/* In the case that slow- and fast-path handling are both done by qman_poll()
136637 + * (ie. because there is no interrupt handling), we ought to balance how often
136638 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
136639 + * sources, so we call the fast poll 'n' times before calling the slow poll
136640 + * once. The idle decrementer constant is used when the last slow-poll detected
136641 + * no work to do, and the busy decrementer constant when the last slow-poll had
136642 + * work to do. */
136643 +#define SLOW_POLL_IDLE 1000
136644 +#define SLOW_POLL_BUSY 10
136645 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
136646 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136647 + unsigned int poll_limit);
136648 +
136649 +/* Portal interrupt handler */
136650 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
136651 +{
136652 + struct qman_portal *p = ptr;
136653 + /*
136654 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
136655 + * it could race against a Query Congestion State command also given
136656 + * as part of the handling of this interrupt source. We mustn't
136657 + * clear it a second time in this top-level function.
136658 + */
136659 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
136660 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
136661 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
136662 + /* DQRR-handling if it's interrupt-driven */
136663 + if (is & QM_PIRQ_DQRI)
136664 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136665 + /* Handling of anything else that's interrupt-driven */
136666 + clear |= __poll_portal_slow(p, is);
136667 + qm_isr_status_clear(&p->p, clear);
136668 + return IRQ_HANDLED;
136669 +}
136670 +
136671 +/* This inner version is used privately by qman_create_affine_portal(), as well
136672 + * as by the exported qman_stop_dequeues(). */
136673 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
136674 +{
136675 + unsigned long irqflags __maybe_unused;
136676 + PORTAL_IRQ_LOCK(p, irqflags);
136677 + if (!(p->dqrr_disable_ref++))
136678 + qm_dqrr_set_maxfill(&p->p, 0);
136679 + PORTAL_IRQ_UNLOCK(p, irqflags);
136680 +}
136681 +
136682 +static int drain_mr_fqrni(struct qm_portal *p)
136683 +{
136684 + const struct qm_mr_entry *msg;
136685 +loop:
136686 + msg = qm_mr_current(p);
136687 + if (!msg) {
136688 + /* if MR was full and h/w had other FQRNI entries to produce, we
136689 + * need to allow it time to produce those entries once the
136690 + * existing entries are consumed. A worst-case situation
136691 + * (fully-loaded system) means h/w sequencers may have to do 3-4
136692 + * other things before servicing the portal's MR pump, each of
136693 + * which (if slow) may take ~50 qman cycles (which is ~200
136694 + * processor cycles). So rounding up and then multiplying this
136695 + * worst-case estimate by a factor of 10, just to be
136696 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
136697 + * one entry at a time, so h/w has an opportunity to produce new
136698 + * entries well before the ring has been fully consumed, so
136699 + * we're being *really* paranoid here. */
136700 + u64 now, then = mfatb();
136701 + do {
136702 + now = mfatb();
136703 + } while ((then + 10000) > now);
136704 + msg = qm_mr_current(p);
136705 + if (!msg)
136706 + return 0;
136707 + }
136708 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
136709 + /* We aren't draining anything but FQRNIs */
136710 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136711 + return -1;
136712 + }
136713 + qm_mr_next(p);
136714 + qm_mr_cci_consume(p, 1);
136715 + goto loop;
136716 +}
136717 +
136718 +#ifdef CONFIG_SUSPEND
136719 +static int _qman_portal_suspend_noirq(struct device *dev)
136720 +{
136721 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136722 +#ifdef CONFIG_PM_DEBUG
136723 + struct platform_device *pdev = to_platform_device(dev);
136724 +#endif
136725 +
136726 + p->save_isdr = qm_isr_disable_read(&p->p);
136727 + qm_isr_disable_write(&p->p, 0xffffffff);
136728 + qm_isr_status_clear(&p->p, 0xffffffff);
136729 +#ifdef CONFIG_PM_DEBUG
136730 + pr_info("Suspend for %s\n", pdev->name);
136731 +#endif
136732 + return 0;
136733 +}
136734 +
136735 +static int _qman_portal_resume_noirq(struct device *dev)
136736 +{
136737 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136738 +
136739 + /* restore isdr */
136740 + qm_isr_disable_write(&p->p, p->save_isdr);
136741 + return 0;
136742 +}
136743 +#else
136744 +#define _qman_portal_suspend_noirq NULL
136745 +#define _qman_portal_resume_noirq NULL
136746 +#endif
136747 +
136748 +struct dev_pm_domain qman_portal_device_pm_domain = {
136749 + .ops = {
136750 + USE_PLATFORM_PM_SLEEP_OPS
136751 + .suspend_noirq = _qman_portal_suspend_noirq,
136752 + .resume_noirq = _qman_portal_resume_noirq,
136753 + }
136754 +};
136755 +
136756 +struct qman_portal *qman_create_portal(
136757 + struct qman_portal *portal,
136758 + const struct qm_portal_config *config,
136759 + const struct qman_cgrs *cgrs)
136760 +{
136761 + struct qm_portal *__p;
136762 + char buf[16];
136763 + int ret;
136764 + u32 isdr;
136765 +
136766 + if (!portal) {
136767 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136768 + if (!portal)
136769 + return portal;
136770 + portal->alloced = 1;
136771 + } else
136772 + portal->alloced = 0;
136773 +
136774 + __p = &portal->p;
136775 +
136776 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136777 + /* PAMU is required for stashing */
136778 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136779 + 1 : 0);
136780 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136781 + portal->use_eqcr_ci_stashing = 1;
136782 +#else
136783 + portal->use_eqcr_ci_stashing = 0;
136784 +#endif
136785 +
136786 + /* prep the low-level portal struct with the mapped addresses from the
136787 + * config, everything that follows depends on it and "config" is more
136788 + * for (de)reference... */
136789 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136790 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136791 + /*
136792 + * If CI-stashing is used, the current defaults use a threshold of 3,
136793 + * and stash with high-than-DQRR priority.
136794 + */
136795 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136796 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
136797 + pr_err("Qman EQCR initialisation failed\n");
136798 + goto fail_eqcr;
136799 + }
136800 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
136801 + qm_dqrr_cdc, DQRR_MAXFILL)) {
136802 + pr_err("Qman DQRR initialisation failed\n");
136803 + goto fail_dqrr;
136804 + }
136805 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
136806 + pr_err("Qman MR initialisation failed\n");
136807 + goto fail_mr;
136808 + }
136809 + if (qm_mc_init(__p)) {
136810 + pr_err("Qman MC initialisation failed\n");
136811 + goto fail_mc;
136812 + }
136813 + if (qm_isr_init(__p)) {
136814 + pr_err("Qman ISR initialisation failed\n");
136815 + goto fail_isr;
136816 + }
136817 + /* static interrupt-gating controls */
136818 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
136819 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
136820 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
136821 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
136822 + if (!portal->cgrs)
136823 + goto fail_cgrs;
136824 + /* initial snapshot is no-depletion */
136825 + qman_cgrs_init(&portal->cgrs[1]);
136826 + if (cgrs)
136827 + portal->cgrs[0] = *cgrs;
136828 + else
136829 + /* if the given mask is NULL, assume all CGRs can be seen */
136830 + qman_cgrs_fill(&portal->cgrs[0]);
136831 + INIT_LIST_HEAD(&portal->cgr_cbs);
136832 + spin_lock_init(&portal->cgr_lock);
136833 + if (num_ceetms) {
136834 + for (ret = 0; ret < num_ceetms; ret++) {
136835 + portal->ccgrs[ret] = kmalloc(2 *
136836 + sizeof(struct qman_ccgrs), GFP_KERNEL);
136837 + if (!portal->ccgrs[ret])
136838 + goto fail_ccgrs;
136839 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
136840 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
136841 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
136842 + }
136843 + }
136844 + spin_lock_init(&portal->ccgr_lock);
136845 + portal->bits = 0;
136846 + portal->slowpoll = 0;
136847 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136848 + portal->eqci_owned = NULL;
136849 +#endif
136850 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136851 + raw_spin_lock_init(&portal->sharing_lock);
136852 + portal->is_shared = config->public_cfg.is_shared;
136853 + portal->sharing_redirect = NULL;
136854 +#endif
136855 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
136856 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
136857 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
136858 + portal->dqrr_disable_ref = 0;
136859 + portal->cb_dc_ern = NULL;
136860 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
136861 + portal->pdev = platform_device_alloc(buf, -1);
136862 + if (!portal->pdev) {
136863 + pr_err("qman_portal - platform_device_alloc() failed\n");
136864 + goto fail_devalloc;
136865 + }
136866 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136867 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
136868 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
136869 +#else
136870 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
136871 + pr_err("qman_portal - dma_set_mask() failed\n");
136872 + goto fail_devadd;
136873 + }
136874 +#endif
136875 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
136876 + portal->pdev->dev.platform_data = portal;
136877 + ret = platform_device_add(portal->pdev);
136878 + if (ret) {
136879 + pr_err("qman_portal - platform_device_add() failed\n");
136880 + goto fail_devadd;
136881 + }
136882 + dpa_rbtree_init(&portal->retire_table);
136883 + isdr = 0xffffffff;
136884 + qm_isr_disable_write(__p, isdr);
136885 + portal->irq_sources = 0;
136886 + qm_isr_enable_write(__p, portal->irq_sources);
136887 + qm_isr_status_clear(__p, 0xffffffff);
136888 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
136889 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
136890 + portal)) {
136891 + pr_err("request_irq() failed\n");
136892 + goto fail_irq;
136893 + }
136894 + if ((config->public_cfg.cpu != -1) &&
136895 + irq_can_set_affinity(config->public_cfg.irq) &&
136896 + irq_set_affinity(config->public_cfg.irq,
136897 + cpumask_of(config->public_cfg.cpu))) {
136898 + pr_err("irq_set_affinity() failed\n");
136899 + goto fail_affinity;
136900 + }
136901 +
136902 + /* Need EQCR to be empty before continuing */
136903 + isdr ^= QM_PIRQ_EQCI;
136904 + qm_isr_disable_write(__p, isdr);
136905 + ret = qm_eqcr_get_fill(__p);
136906 + if (ret) {
136907 + pr_err("Qman EQCR unclean\n");
136908 + goto fail_eqcr_empty;
136909 + }
136910 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
136911 + qm_isr_disable_write(__p, isdr);
136912 + if (qm_dqrr_current(__p) != NULL) {
136913 + pr_err("Qman DQRR unclean\n");
136914 + qm_dqrr_cdc_consume_n(__p, 0xffff);
136915 + }
136916 + if (qm_mr_current(__p) != NULL) {
136917 + /* special handling, drain just in case it's a few FQRNIs */
136918 + if (drain_mr_fqrni(__p)) {
136919 + const struct qm_mr_entry *e = qm_mr_current(__p);
136920 + /*
136921 + * Message ring cannot be empty no need to check
136922 + * qm_mr_current returned successfully
136923 + */
136924 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
136925 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
136926 + goto fail_dqrr_mr_empty;
136927 + }
136928 + }
136929 + /* Success */
136930 + portal->config = config;
136931 + qm_isr_disable_write(__p, 0);
136932 + qm_isr_uninhibit(__p);
136933 + /* Write a sane SDQCR */
136934 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
136935 + return portal;
136936 +fail_dqrr_mr_empty:
136937 +fail_eqcr_empty:
136938 +fail_affinity:
136939 + free_irq(config->public_cfg.irq, portal);
136940 +fail_irq:
136941 + platform_device_del(portal->pdev);
136942 +fail_devadd:
136943 + platform_device_put(portal->pdev);
136944 +fail_devalloc:
136945 + if (num_ceetms)
136946 + for (ret = 0; ret < num_ceetms; ret++)
136947 + kfree(portal->ccgrs[ret]);
136948 +fail_ccgrs:
136949 + kfree(portal->cgrs);
136950 +fail_cgrs:
136951 + qm_isr_finish(__p);
136952 +fail_isr:
136953 + qm_mc_finish(__p);
136954 +fail_mc:
136955 + qm_mr_finish(__p);
136956 +fail_mr:
136957 + qm_dqrr_finish(__p);
136958 +fail_dqrr:
136959 + qm_eqcr_finish(__p);
136960 +fail_eqcr:
136961 + if (portal->alloced)
136962 + kfree(portal);
136963 + return NULL;
136964 +}
136965 +
136966 +struct qman_portal *qman_create_affine_portal(
136967 + const struct qm_portal_config *config,
136968 + const struct qman_cgrs *cgrs)
136969 +{
136970 + struct qman_portal *res;
136971 + struct qman_portal *portal;
136972 +
136973 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
136974 + res = qman_create_portal(portal, config, cgrs);
136975 + if (res) {
136976 + spin_lock(&affine_mask_lock);
136977 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
136978 + affine_channels[config->public_cfg.cpu] =
136979 + config->public_cfg.channel;
136980 + affine_portals[config->public_cfg.cpu] = portal;
136981 + spin_unlock(&affine_mask_lock);
136982 + }
136983 + return res;
136984 +}
136985 +
136986 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
136987 + * these cases. */
136988 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
136989 + int cpu)
136990 +{
136991 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136992 + struct qman_portal *p;
136993 + p = &per_cpu(qman_affine_portal, cpu);
136994 + /* Check that we don't already have our own portal */
136995 + BUG_ON(p->config);
136996 + /* Check that we aren't already slaving to another portal */
136997 + BUG_ON(p->is_shared);
136998 + /* Check that 'redirect' is prepared to have us */
136999 + BUG_ON(!redirect->config->public_cfg.is_shared);
137000 + /* These are the only elements to initialise when redirecting */
137001 + p->irq_sources = 0;
137002 + p->sharing_redirect = redirect;
137003 + affine_portals[cpu] = p;
137004 + return p;
137005 +#else
137006 + BUG();
137007 + return NULL;
137008 +#endif
137009 +}
137010 +
137011 +void qman_destroy_portal(struct qman_portal *qm)
137012 +{
137013 + const struct qm_portal_config *pcfg;
137014 + int i;
137015 +
137016 + /* Stop dequeues on the portal */
137017 + qm_dqrr_sdqcr_set(&qm->p, 0);
137018 +
137019 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
137020 + * something related to QM_PIRQ_EQCI, this may need fixing.
137021 + * Also, due to the prefetching model used for CI updates in the enqueue
137022 + * path, this update will only invalidate the CI cacheline *after*
137023 + * working on it, so we need to call this twice to ensure a full update
137024 + * irrespective of where the enqueue processing was at when the teardown
137025 + * began. */
137026 + qm_eqcr_cce_update(&qm->p);
137027 + qm_eqcr_cce_update(&qm->p);
137028 + pcfg = qm->config;
137029 +
137030 + free_irq(pcfg->public_cfg.irq, qm);
137031 +
137032 + kfree(qm->cgrs);
137033 + if (num_ceetms)
137034 + for (i = 0; i < num_ceetms; i++)
137035 + kfree(qm->ccgrs[i]);
137036 + qm_isr_finish(&qm->p);
137037 + qm_mc_finish(&qm->p);
137038 + qm_mr_finish(&qm->p);
137039 + qm_dqrr_finish(&qm->p);
137040 + qm_eqcr_finish(&qm->p);
137041 +
137042 + platform_device_del(qm->pdev);
137043 + platform_device_put(qm->pdev);
137044 +
137045 + qm->config = NULL;
137046 + if (qm->alloced)
137047 + kfree(qm);
137048 +}
137049 +
137050 +const struct qm_portal_config *qman_destroy_affine_portal(void)
137051 +{
137052 + /* We don't want to redirect if we're a slave, use "raw" */
137053 + struct qman_portal *qm = get_raw_affine_portal();
137054 + const struct qm_portal_config *pcfg;
137055 + int cpu;
137056 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137057 + if (qm->sharing_redirect) {
137058 + qm->sharing_redirect = NULL;
137059 + put_affine_portal();
137060 + return NULL;
137061 + }
137062 + qm->is_shared = 0;
137063 +#endif
137064 + pcfg = qm->config;
137065 + cpu = pcfg->public_cfg.cpu;
137066 +
137067 + qman_destroy_portal(qm);
137068 +
137069 + spin_lock(&affine_mask_lock);
137070 + cpumask_clear_cpu(cpu, &affine_mask);
137071 + spin_unlock(&affine_mask_lock);
137072 + put_affine_portal();
137073 + return pcfg;
137074 +}
137075 +
137076 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
137077 +{
137078 + return &p->config->public_cfg;
137079 +}
137080 +EXPORT_SYMBOL(qman_p_get_portal_config);
137081 +
137082 +const struct qman_portal_config *qman_get_portal_config(void)
137083 +{
137084 + struct qman_portal *p = get_affine_portal();
137085 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
137086 + put_affine_portal();
137087 + return ret;
137088 +}
137089 +EXPORT_SYMBOL(qman_get_portal_config);
137090 +
137091 +/* Inline helper to reduce nesting in __poll_portal_slow() */
137092 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
137093 + const struct qm_mr_entry *msg, u8 verb)
137094 +{
137095 + FQLOCK(fq);
137096 + switch (verb) {
137097 + case QM_MR_VERB_FQRL:
137098 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
137099 + fq_clear(fq, QMAN_FQ_STATE_ORL);
137100 + table_del_fq(p, fq);
137101 + break;
137102 + case QM_MR_VERB_FQRN:
137103 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
137104 + (fq->state == qman_fq_state_sched));
137105 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
137106 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
137107 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
137108 + fq_set(fq, QMAN_FQ_STATE_NE);
137109 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
137110 + fq_set(fq, QMAN_FQ_STATE_ORL);
137111 + else
137112 + table_del_fq(p, fq);
137113 + fq->state = qman_fq_state_retired;
137114 + break;
137115 + case QM_MR_VERB_FQPN:
137116 + DPA_ASSERT(fq->state == qman_fq_state_sched);
137117 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
137118 + fq->state = qman_fq_state_parked;
137119 + }
137120 + FQUNLOCK(fq);
137121 +}
137122 +
137123 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
137124 +{
137125 + const struct qm_mr_entry *msg;
137126 + struct qm_mr_entry swapped_msg;
137127 + int k;
137128 +
137129 + if (is & QM_PIRQ_CSCI) {
137130 + struct qman_cgrs rr, c;
137131 + struct qm_mc_result *mcr;
137132 + struct qman_cgr *cgr;
137133 + unsigned long irqflags __maybe_unused;
137134 +
137135 + spin_lock_irqsave(&p->cgr_lock, irqflags);
137136 + /*
137137 + * The CSCI bit must be cleared _before_ issuing the
137138 + * Query Congestion State command, to ensure that a long
137139 + * CGR State Change callback cannot miss an intervening
137140 + * state change.
137141 + */
137142 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
137143 + qm_mc_start(&p->p);
137144 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
137145 + while (!(mcr = qm_mc_result(&p->p)))
137146 + cpu_relax();
137147 + for (k = 0; k < 8; k++)
137148 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
137149 + mcr->querycongestion.state.__state[k]);
137150 + /* mask out the ones I'm not interested in */
137151 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
137152 + &mcr->querycongestion.state, &p->cgrs[0]);
137153 + /* check previous snapshot for delta, enter/exit congestion */
137154 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
137155 + /* update snapshot */
137156 + qman_cgrs_cp(&p->cgrs[1], &rr);
137157 + /* Invoke callback */
137158 + list_for_each_entry(cgr, &p->cgr_cbs, node)
137159 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
137160 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
137161 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
137162 + }
137163 + if (is & QM_PIRQ_CCSCI) {
137164 + struct qman_ccgrs rr, c, congestion_result;
137165 + struct qm_mc_result *mcr;
137166 + struct qm_mc_command *mcc;
137167 + struct qm_ceetm_ccg *ccg;
137168 + unsigned long irqflags __maybe_unused;
137169 + int i, j;
137170 +
137171 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
137172 + /*
137173 + * The CCSCI bit must be cleared _before_ issuing the
137174 + * Query Congestion State command, to ensure that a long
137175 + * CCGR State Change callback cannot miss an intervening
137176 + * state change.
137177 + */
137178 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
137179 +
137180 + for (i = 0; i < num_ceetms; i++) {
137181 + for (j = 0; j < 2; j++) {
137182 + mcc = qm_mc_start(&p->p);
137183 + mcc->ccgr_query.ccgrid = cpu_to_be16(
137184 + CEETM_QUERY_CONGESTION_STATE | j);
137185 + mcc->ccgr_query.dcpid = i;
137186 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
137187 + while (!(mcr = qm_mc_result(&p->p)))
137188 + cpu_relax();
137189 + for (k = 0; k < 8; k++)
137190 + mcr->ccgr_query.congestion_state.state.
137191 + __state[k] = be32_to_cpu(
137192 + mcr->ccgr_query.
137193 + congestion_state.state.
137194 + __state[k]);
137195 + congestion_result.q[j] =
137196 + mcr->ccgr_query.congestion_state.state;
137197 + }
137198 + /* mask out the ones I'm not interested in */
137199 + qman_ccgrs_and(&rr, &congestion_result,
137200 + &p->ccgrs[i][0]);
137201 + /*
137202 + * check previous snapshot for delta, enter/exit
137203 + * congestion.
137204 + */
137205 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
137206 + /* update snapshot */
137207 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
137208 + /* Invoke callback */
137209 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
137210 + if (ccg->cb && qman_ccgrs_get(&c,
137211 + (ccg->parent->idx << 4) | ccg->idx))
137212 + ccg->cb(ccg, ccg->cb_ctx,
137213 + qman_ccgrs_get(&rr,
137214 + (ccg->parent->idx << 4)
137215 + | ccg->idx));
137216 + }
137217 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
137218 + }
137219 +
137220 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137221 + if (is & QM_PIRQ_EQCI) {
137222 + unsigned long irqflags;
137223 + PORTAL_IRQ_LOCK(p, irqflags);
137224 + p->eqci_owned = NULL;
137225 + PORTAL_IRQ_UNLOCK(p, irqflags);
137226 + wake_up(&affine_queue);
137227 + }
137228 +#endif
137229 +
137230 + if (is & QM_PIRQ_EQRI) {
137231 + unsigned long irqflags __maybe_unused;
137232 + PORTAL_IRQ_LOCK(p, irqflags);
137233 + qm_eqcr_cce_update(&p->p);
137234 + qm_eqcr_set_ithresh(&p->p, 0);
137235 + PORTAL_IRQ_UNLOCK(p, irqflags);
137236 + wake_up(&affine_queue);
137237 + }
137238 +
137239 + if (is & QM_PIRQ_MRI) {
137240 + struct qman_fq *fq;
137241 + u8 verb, num = 0;
137242 +mr_loop:
137243 + qm_mr_pvb_update(&p->p);
137244 + msg = qm_mr_current(&p->p);
137245 + if (!msg)
137246 + goto mr_done;
137247 + swapped_msg = *msg;
137248 + hw_fd_to_cpu(&swapped_msg.ern.fd);
137249 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
137250 + /* The message is a software ERN iff the 0x20 bit is set */
137251 + if (verb & 0x20) {
137252 + switch (verb) {
137253 + case QM_MR_VERB_FQRNI:
137254 + /* nada, we drop FQRNIs on the floor */
137255 + break;
137256 + case QM_MR_VERB_FQRN:
137257 + case QM_MR_VERB_FQRL:
137258 + /* Lookup in the retirement table */
137259 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
137260 + BUG_ON(!fq);
137261 + fq_state_change(p, fq, &swapped_msg, verb);
137262 + if (fq->cb.fqs)
137263 + fq->cb.fqs(p, fq, &swapped_msg);
137264 + break;
137265 + case QM_MR_VERB_FQPN:
137266 + /* Parked */
137267 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137268 + fq = get_fq_table_entry(
137269 + be32_to_cpu(msg->fq.contextB));
137270 +#else
137271 + fq = (void *)(uintptr_t)
137272 + be32_to_cpu(msg->fq.contextB);
137273 +#endif
137274 + fq_state_change(p, fq, msg, verb);
137275 + if (fq->cb.fqs)
137276 + fq->cb.fqs(p, fq, &swapped_msg);
137277 + break;
137278 + case QM_MR_VERB_DC_ERN:
137279 + /* DCP ERN */
137280 + if (p->cb_dc_ern)
137281 + p->cb_dc_ern(p, msg);
137282 + else if (cb_dc_ern)
137283 + cb_dc_ern(p, msg);
137284 + else {
137285 + static int warn_once;
137286 + if (!warn_once) {
137287 + pr_crit("Leaking DCP ERNs!\n");
137288 + warn_once = 1;
137289 + }
137290 + }
137291 + break;
137292 + default:
137293 + pr_crit("Invalid MR verb 0x%02x\n", verb);
137294 + }
137295 + } else {
137296 + /* Its a software ERN */
137297 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137298 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
137299 +#else
137300 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
137301 +#endif
137302 + fq->cb.ern(p, fq, &swapped_msg);
137303 + }
137304 + num++;
137305 + qm_mr_next(&p->p);
137306 + goto mr_loop;
137307 +mr_done:
137308 + qm_mr_cci_consume(&p->p, num);
137309 + }
137310 + /*
137311 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
137312 + * processing. If that interrupt source has meanwhile been re-asserted,
137313 + * we mustn't clear it here (or in the top-level interrupt handler).
137314 + */
137315 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
137316 +}
137317 +
137318 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
137319 + * inlined. */
137320 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
137321 +{
137322 + p->vdqcr_owned = NULL;
137323 + FQLOCK(fq);
137324 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
137325 + FQUNLOCK(fq);
137326 + wake_up(&affine_queue);
137327 +}
137328 +
137329 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
137330 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
137331 + const struct qm_dqrr_entry *src)
137332 +{
137333 + int i = 0;
137334 + const u64 *s64 = (u64*)src;
137335 + u64 *d64 = (u64*)dst;
137336 +
137337 + /* DQRR only has 32 bytes of valid data so only need to
137338 + * copy 4 - 64 bit values */
137339 + *d64 = *s64;
137340 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137341 + {
137342 + u32 res, zero = 0;
137343 + /* Create a dependancy after copying first bytes ensures no wrap
137344 + transaction generated to QBMan */
137345 + /* Logical AND the value pointed to by s64 with 0x0 and
137346 + store the result in res */
137347 + asm volatile("and %[result], %[in1], %[in2]"
137348 + : [result] "=r" (res)
137349 + : [in1] "r" (zero), [in2] "r" (*s64)
137350 + : "memory");
137351 + /* Add res to s64 - this creates a dependancy on the result of
137352 + reading the value of s64 before the next read. The side
137353 + effect of this is that the core must stall until the first
137354 + aligned read is complete therefore preventing a WRAP
137355 + transaction to be seen by the QBMan */
137356 + asm volatile("add %[result], %[in1], %[in2]"
137357 + : [result] "=r" (s64)
137358 + : [in1] "r" (res), [in2] "r" (s64)
137359 + : "memory");
137360 + }
137361 +#endif
137362 + /* Copy the last 3 64 bit parts */
137363 + d64++; s64++;
137364 + for (;i<3; i++)
137365 + *d64++ = *s64++;
137366 +}
137367 +
137368 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
137369 + * that would conflict with other things if they ran at the same time on the
137370 + * same cpu are;
137371 + *
137372 + * (i) setting/clearing vdqcr_owned, and
137373 + * (ii) clearing the NE (Not Empty) flag.
137374 + *
137375 + * Both are safe. Because;
137376 + *
137377 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
137378 + * vdqcr_owned field (which it does before setting VDQCR), and
137379 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
137380 + * done so that we can't interfere.
137381 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
137382 + * with (i) that API prevents us from interfering until it's safe.
137383 + *
137384 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
137385 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
137386 + * advantage comes from this function not having to "lock" anything at all.
137387 + *
137388 + * Note also that the callbacks are invoked at points which are safe against the
137389 + * above potential conflicts, but that this function itself is not re-entrant
137390 + * (this is because the function tracks one end of each FIFO in the portal and
137391 + * we do *not* want to lock that). So the consequence is that it is safe for
137392 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
137393 + * sole API that could be invoking the callback through this function).
137394 + */
137395 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
137396 + unsigned int poll_limit)
137397 +{
137398 + const struct qm_dqrr_entry *dq;
137399 + struct qman_fq *fq;
137400 + enum qman_cb_dqrr_result res;
137401 + unsigned int limit = 0;
137402 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137403 + struct qm_dqrr_entry *shadow;
137404 + const struct qm_dqrr_entry *orig_dq;
137405 +#endif
137406 +loop:
137407 + qm_dqrr_pvb_update(&p->p);
137408 + dq = qm_dqrr_current(&p->p);
137409 + if (!dq)
137410 + goto done;
137411 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137412 + /* If running on an LE system the fields of the
137413 + dequeue entry must be swapped. Because the
137414 + QMan HW will ignore writes the DQRR entry is
137415 + copied and the index stored within the copy */
137416 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
137417 + /* Use safe copy here to avoid WRAP transaction */
137418 + safe_copy_dqrr(shadow, dq);
137419 + orig_dq = dq;
137420 + dq = shadow;
137421 + shadow->fqid = be32_to_cpu(shadow->fqid);
137422 + shadow->contextB = be32_to_cpu(shadow->contextB);
137423 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
137424 + hw_fd_to_cpu(&shadow->fd);
137425 +#endif
137426 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
137427 + /* VDQCR: don't trust contextB as the FQ may have been
137428 + * configured for h/w consumption and we're draining it
137429 + * post-retirement. */
137430 + fq = p->vdqcr_owned;
137431 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
137432 + * to check for clearing it when doing volatile dequeues. It's
137433 + * one less thing to check in the critical path (SDQCR). */
137434 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
137435 + fq_clear(fq, QMAN_FQ_STATE_NE);
137436 + /* this is duplicated from the SDQCR code, but we have stuff to
137437 + * do before *and* after this callback, and we don't want
137438 + * multiple if()s in the critical path (SDQCR). */
137439 + res = fq->cb.dqrr(p, fq, dq);
137440 + if (res == qman_cb_dqrr_stop)
137441 + goto done;
137442 + /* Check for VDQCR completion */
137443 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
137444 + clear_vdqcr(p, fq);
137445 + } else {
137446 + /* SDQCR: contextB points to the FQ */
137447 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137448 + fq = get_fq_table_entry(dq->contextB);
137449 +#else
137450 + fq = (void *)(uintptr_t)dq->contextB;
137451 +#endif
137452 + /* Now let the callback do its stuff */
137453 + res = fq->cb.dqrr(p, fq, dq);
137454 +
137455 + /* The callback can request that we exit without consuming this
137456 + * entry nor advancing; */
137457 + if (res == qman_cb_dqrr_stop)
137458 + goto done;
137459 + }
137460 + /* Interpret 'dq' from a driver perspective. */
137461 + /* Parking isn't possible unless HELDACTIVE was set. NB,
137462 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
137463 + * check for HELDACTIVE to cover both. */
137464 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
137465 + (res != qman_cb_dqrr_park));
137466 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137467 + if (res != qman_cb_dqrr_defer)
137468 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
137469 + (res == qman_cb_dqrr_park));
137470 +#else
137471 + /* Defer just means "skip it, I'll consume it myself later on" */
137472 + if (res != qman_cb_dqrr_defer)
137473 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
137474 +#endif
137475 + /* Move forward */
137476 + qm_dqrr_next(&p->p);
137477 + /* Entry processed and consumed, increment our counter. The callback can
137478 + * request that we exit after consuming the entry, and we also exit if
137479 + * we reach our processing limit, so loop back only if neither of these
137480 + * conditions is met. */
137481 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
137482 + goto loop;
137483 +done:
137484 + return limit;
137485 +}
137486 +
137487 +u32 qman_irqsource_get(void)
137488 +{
137489 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
137490 + * should shut the user out if they are not the primary CPU hosting the
137491 + * portal. That's why we use the "raw" interface. */
137492 + struct qman_portal *p = get_raw_affine_portal();
137493 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
137494 + put_affine_portal();
137495 + return ret;
137496 +}
137497 +EXPORT_SYMBOL(qman_irqsource_get);
137498 +
137499 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
137500 +{
137501 + __maybe_unused unsigned long irqflags;
137502 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137503 + if (p->sharing_redirect)
137504 + return -EINVAL;
137505 + else
137506 +#endif
137507 + {
137508 + bits = bits & QM_PIRQ_VISIBLE;
137509 + PORTAL_IRQ_LOCK(p, irqflags);
137510 +
137511 + /* Clear any previously remaining interrupt conditions in
137512 + * QCSP_ISR. This prevents raising a false interrupt when
137513 + * interrupt conditions are enabled in QCSP_IER.
137514 + */
137515 + qm_isr_status_clear(&p->p, bits);
137516 + set_bits(bits, &p->irq_sources);
137517 + qm_isr_enable_write(&p->p, p->irq_sources);
137518 + PORTAL_IRQ_UNLOCK(p, irqflags);
137519 + }
137520 + return 0;
137521 +}
137522 +EXPORT_SYMBOL(qman_p_irqsource_add);
137523 +
137524 +int qman_irqsource_add(u32 bits __maybe_unused)
137525 +{
137526 + struct qman_portal *p = get_raw_affine_portal();
137527 + int ret;
137528 + ret = qman_p_irqsource_add(p, bits);
137529 + put_affine_portal();
137530 + return ret;
137531 +}
137532 +EXPORT_SYMBOL(qman_irqsource_add);
137533 +
137534 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
137535 +{
137536 + __maybe_unused unsigned long irqflags;
137537 + u32 ier;
137538 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137539 + if (p->sharing_redirect) {
137540 + put_affine_portal();
137541 + return -EINVAL;
137542 + }
137543 +#endif
137544 + /* Our interrupt handler only processes+clears status register bits that
137545 + * are in p->irq_sources. As we're trimming that mask, if one of them
137546 + * were to assert in the status register just before we remove it from
137547 + * the enable register, there would be an interrupt-storm when we
137548 + * release the IRQ lock. So we wait for the enable register update to
137549 + * take effect in h/w (by reading it back) and then clear all other bits
137550 + * in the status register. Ie. we clear them from ISR once it's certain
137551 + * IER won't allow them to reassert. */
137552 + PORTAL_IRQ_LOCK(p, irqflags);
137553 + bits &= QM_PIRQ_VISIBLE;
137554 + clear_bits(bits, &p->irq_sources);
137555 + qm_isr_enable_write(&p->p, p->irq_sources);
137556 +
137557 + ier = qm_isr_enable_read(&p->p);
137558 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
137559 + * data-dependency, ie. to protect against re-ordering. */
137560 + qm_isr_status_clear(&p->p, ~ier);
137561 + PORTAL_IRQ_UNLOCK(p, irqflags);
137562 + return 0;
137563 +}
137564 +EXPORT_SYMBOL(qman_p_irqsource_remove);
137565 +
137566 +int qman_irqsource_remove(u32 bits)
137567 +{
137568 + struct qman_portal *p = get_raw_affine_portal();
137569 + int ret;
137570 + ret = qman_p_irqsource_remove(p, bits);
137571 + put_affine_portal();
137572 + return ret;
137573 +}
137574 +EXPORT_SYMBOL(qman_irqsource_remove);
137575 +
137576 +const cpumask_t *qman_affine_cpus(void)
137577 +{
137578 + return &affine_mask;
137579 +}
137580 +EXPORT_SYMBOL(qman_affine_cpus);
137581 +
137582 +u16 qman_affine_channel(int cpu)
137583 +{
137584 + if (cpu < 0) {
137585 + struct qman_portal *portal = get_raw_affine_portal();
137586 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137587 + BUG_ON(portal->sharing_redirect);
137588 +#endif
137589 + cpu = portal->config->public_cfg.cpu;
137590 + put_affine_portal();
137591 + }
137592 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
137593 + return affine_channels[cpu];
137594 +}
137595 +EXPORT_SYMBOL(qman_affine_channel);
137596 +
137597 +void *qman_get_affine_portal(int cpu)
137598 +{
137599 + return affine_portals[cpu];
137600 +}
137601 +EXPORT_SYMBOL(qman_get_affine_portal);
137602 +
137603 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
137604 +{
137605 + int ret;
137606 +
137607 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137608 + if (unlikely(p->sharing_redirect))
137609 + ret = -EINVAL;
137610 + else
137611 +#endif
137612 + {
137613 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
137614 + ret = __poll_portal_fast(p, limit);
137615 + }
137616 + return ret;
137617 +}
137618 +EXPORT_SYMBOL(qman_p_poll_dqrr);
137619 +
137620 +int qman_poll_dqrr(unsigned int limit)
137621 +{
137622 + struct qman_portal *p = get_poll_portal();
137623 + int ret;
137624 + ret = qman_p_poll_dqrr(p, limit);
137625 + put_poll_portal();
137626 + return ret;
137627 +}
137628 +EXPORT_SYMBOL(qman_poll_dqrr);
137629 +
137630 +u32 qman_p_poll_slow(struct qman_portal *p)
137631 +{
137632 + u32 ret;
137633 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137634 + if (unlikely(p->sharing_redirect))
137635 + ret = (u32)-1;
137636 + else
137637 +#endif
137638 + {
137639 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137640 + ret = __poll_portal_slow(p, is);
137641 + qm_isr_status_clear(&p->p, ret);
137642 + }
137643 + return ret;
137644 +}
137645 +EXPORT_SYMBOL(qman_p_poll_slow);
137646 +
137647 +u32 qman_poll_slow(void)
137648 +{
137649 + struct qman_portal *p = get_poll_portal();
137650 + u32 ret;
137651 + ret = qman_p_poll_slow(p);
137652 + put_poll_portal();
137653 + return ret;
137654 +}
137655 +EXPORT_SYMBOL(qman_poll_slow);
137656 +
137657 +/* Legacy wrapper */
137658 +void qman_p_poll(struct qman_portal *p)
137659 +{
137660 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137661 + if (unlikely(p->sharing_redirect))
137662 + return;
137663 +#endif
137664 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
137665 + if (!(p->slowpoll--)) {
137666 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137667 + u32 active = __poll_portal_slow(p, is);
137668 + if (active) {
137669 + qm_isr_status_clear(&p->p, active);
137670 + p->slowpoll = SLOW_POLL_BUSY;
137671 + } else
137672 + p->slowpoll = SLOW_POLL_IDLE;
137673 + }
137674 + }
137675 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
137676 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137677 +}
137678 +EXPORT_SYMBOL(qman_p_poll);
137679 +
137680 +void qman_poll(void)
137681 +{
137682 + struct qman_portal *p = get_poll_portal();
137683 + qman_p_poll(p);
137684 + put_poll_portal();
137685 +}
137686 +EXPORT_SYMBOL(qman_poll);
137687 +
137688 +void qman_p_stop_dequeues(struct qman_portal *p)
137689 +{
137690 + qman_stop_dequeues_ex(p);
137691 +}
137692 +EXPORT_SYMBOL(qman_p_stop_dequeues);
137693 +
137694 +void qman_stop_dequeues(void)
137695 +{
137696 + struct qman_portal *p = get_affine_portal();
137697 + qman_p_stop_dequeues(p);
137698 + put_affine_portal();
137699 +}
137700 +EXPORT_SYMBOL(qman_stop_dequeues);
137701 +
137702 +void qman_p_start_dequeues(struct qman_portal *p)
137703 +{
137704 + unsigned long irqflags __maybe_unused;
137705 + PORTAL_IRQ_LOCK(p, irqflags);
137706 + DPA_ASSERT(p->dqrr_disable_ref > 0);
137707 + if (!(--p->dqrr_disable_ref))
137708 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
137709 + PORTAL_IRQ_UNLOCK(p, irqflags);
137710 +}
137711 +EXPORT_SYMBOL(qman_p_start_dequeues);
137712 +
137713 +void qman_start_dequeues(void)
137714 +{
137715 + struct qman_portal *p = get_affine_portal();
137716 + qman_p_start_dequeues(p);
137717 + put_affine_portal();
137718 +}
137719 +EXPORT_SYMBOL(qman_start_dequeues);
137720 +
137721 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137722 +{
137723 + unsigned long irqflags __maybe_unused;
137724 + PORTAL_IRQ_LOCK(p, irqflags);
137725 + pools &= p->config->public_cfg.pools;
137726 + p->sdqcr |= pools;
137727 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137728 + PORTAL_IRQ_UNLOCK(p, irqflags);
137729 +}
137730 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137731 +
137732 +void qman_static_dequeue_add(u32 pools)
137733 +{
137734 + struct qman_portal *p = get_affine_portal();
137735 + qman_p_static_dequeue_add(p, pools);
137736 + put_affine_portal();
137737 +}
137738 +EXPORT_SYMBOL(qman_static_dequeue_add);
137739 +
137740 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137741 +{
137742 + unsigned long irqflags __maybe_unused;
137743 + PORTAL_IRQ_LOCK(p, irqflags);
137744 + pools &= p->config->public_cfg.pools;
137745 + p->sdqcr &= ~pools;
137746 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137747 + PORTAL_IRQ_UNLOCK(p, irqflags);
137748 +}
137749 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137750 +
137751 +void qman_static_dequeue_del(u32 pools)
137752 +{
137753 + struct qman_portal *p = get_affine_portal();
137754 + qman_p_static_dequeue_del(p, pools);
137755 + put_affine_portal();
137756 +}
137757 +EXPORT_SYMBOL(qman_static_dequeue_del);
137758 +
137759 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137760 +{
137761 + return p->sdqcr;
137762 +}
137763 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137764 +
137765 +u32 qman_static_dequeue_get(void)
137766 +{
137767 + struct qman_portal *p = get_affine_portal();
137768 + u32 ret = qman_p_static_dequeue_get(p);
137769 + put_affine_portal();
137770 + return ret;
137771 +}
137772 +EXPORT_SYMBOL(qman_static_dequeue_get);
137773 +
137774 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137775 + int park_request)
137776 +{
137777 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137778 +}
137779 +EXPORT_SYMBOL(qman_p_dca);
137780 +
137781 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137782 +{
137783 + struct qman_portal *p = get_affine_portal();
137784 + qman_p_dca(p, dq, park_request);
137785 + put_affine_portal();
137786 +}
137787 +EXPORT_SYMBOL(qman_dca);
137788 +
137789 +/*******************/
137790 +/* Frame queue API */
137791 +/*******************/
137792 +
137793 +static const char *mcr_result_str(u8 result)
137794 +{
137795 + switch (result) {
137796 + case QM_MCR_RESULT_NULL:
137797 + return "QM_MCR_RESULT_NULL";
137798 + case QM_MCR_RESULT_OK:
137799 + return "QM_MCR_RESULT_OK";
137800 + case QM_MCR_RESULT_ERR_FQID:
137801 + return "QM_MCR_RESULT_ERR_FQID";
137802 + case QM_MCR_RESULT_ERR_FQSTATE:
137803 + return "QM_MCR_RESULT_ERR_FQSTATE";
137804 + case QM_MCR_RESULT_ERR_NOTEMPTY:
137805 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
137806 + case QM_MCR_RESULT_PENDING:
137807 + return "QM_MCR_RESULT_PENDING";
137808 + case QM_MCR_RESULT_ERR_BADCOMMAND:
137809 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
137810 + }
137811 + return "<unknown MCR result>";
137812 +}
137813 +
137814 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
137815 +{
137816 + struct qm_fqd fqd;
137817 + struct qm_mcr_queryfq_np np;
137818 + struct qm_mc_command *mcc;
137819 + struct qm_mc_result *mcr;
137820 + struct qman_portal *p;
137821 + unsigned long irqflags __maybe_unused;
137822 +
137823 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
137824 + int ret = qman_alloc_fqid(&fqid);
137825 + if (ret)
137826 + return ret;
137827 + }
137828 + spin_lock_init(&fq->fqlock);
137829 + fq->fqid = fqid;
137830 + fq->flags = flags;
137831 + fq->state = qman_fq_state_oos;
137832 + fq->cgr_groupid = 0;
137833 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137834 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
137835 + return -ENOMEM;
137836 +#endif
137837 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
137838 + return 0;
137839 + /* Everything else is AS_IS support */
137840 + p = get_affine_portal();
137841 + PORTAL_IRQ_LOCK(p, irqflags);
137842 + mcc = qm_mc_start(&p->p);
137843 + mcc->queryfq.fqid = cpu_to_be32(fqid);
137844 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137845 + while (!(mcr = qm_mc_result(&p->p)))
137846 + cpu_relax();
137847 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
137848 + if (mcr->result != QM_MCR_RESULT_OK) {
137849 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
137850 + goto err;
137851 + }
137852 + fqd = mcr->queryfq.fqd;
137853 + hw_fqd_to_cpu(&fqd);
137854 + mcc = qm_mc_start(&p->p);
137855 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
137856 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137857 + while (!(mcr = qm_mc_result(&p->p)))
137858 + cpu_relax();
137859 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
137860 + if (mcr->result != QM_MCR_RESULT_OK) {
137861 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
137862 + goto err;
137863 + }
137864 + np = mcr->queryfq_np;
137865 + /* Phew, have queryfq and queryfq_np results, stitch together
137866 + * the FQ object from those. */
137867 + fq->cgr_groupid = fqd.cgid;
137868 + switch (np.state & QM_MCR_NP_STATE_MASK) {
137869 + case QM_MCR_NP_STATE_OOS:
137870 + break;
137871 + case QM_MCR_NP_STATE_RETIRED:
137872 + fq->state = qman_fq_state_retired;
137873 + if (np.frm_cnt)
137874 + fq_set(fq, QMAN_FQ_STATE_NE);
137875 + break;
137876 + case QM_MCR_NP_STATE_TEN_SCHED:
137877 + case QM_MCR_NP_STATE_TRU_SCHED:
137878 + case QM_MCR_NP_STATE_ACTIVE:
137879 + fq->state = qman_fq_state_sched;
137880 + if (np.state & QM_MCR_NP_STATE_R)
137881 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137882 + break;
137883 + case QM_MCR_NP_STATE_PARKED:
137884 + fq->state = qman_fq_state_parked;
137885 + break;
137886 + default:
137887 + DPA_ASSERT(NULL == "invalid FQ state");
137888 + }
137889 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
137890 + fq->state |= QMAN_FQ_STATE_CGR_EN;
137891 + PORTAL_IRQ_UNLOCK(p, irqflags);
137892 + put_affine_portal();
137893 + return 0;
137894 +err:
137895 + PORTAL_IRQ_UNLOCK(p, irqflags);
137896 + put_affine_portal();
137897 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
137898 + qman_release_fqid(fqid);
137899 + return -EIO;
137900 +}
137901 +EXPORT_SYMBOL(qman_create_fq);
137902 +
137903 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
137904 +{
137905 +
137906 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
137907 + * quiesced. Instead, run some checks. */
137908 + switch (fq->state) {
137909 + case qman_fq_state_parked:
137910 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
137911 + case qman_fq_state_oos:
137912 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
137913 + qman_release_fqid(fq->fqid);
137914 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137915 + clear_fq_table_entry(fq->key);
137916 +#endif
137917 + return;
137918 + default:
137919 + break;
137920 + }
137921 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
137922 +}
137923 +EXPORT_SYMBOL(qman_destroy_fq);
137924 +
137925 +u32 qman_fq_fqid(struct qman_fq *fq)
137926 +{
137927 + return fq->fqid;
137928 +}
137929 +EXPORT_SYMBOL(qman_fq_fqid);
137930 +
137931 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
137932 +{
137933 + if (state)
137934 + *state = fq->state;
137935 + if (flags)
137936 + *flags = fq->flags;
137937 +}
137938 +EXPORT_SYMBOL(qman_fq_state);
137939 +
137940 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
137941 +{
137942 + struct qm_mc_command *mcc;
137943 + struct qm_mc_result *mcr;
137944 + struct qman_portal *p;
137945 + unsigned long irqflags __maybe_unused;
137946 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137947 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
137948 +
137949 + if ((fq->state != qman_fq_state_oos) &&
137950 + (fq->state != qman_fq_state_parked))
137951 + return -EINVAL;
137952 +#ifdef CONFIG_FSL_DPA_CHECKING
137953 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137954 + return -EINVAL;
137955 +#endif
137956 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
137957 + /* And can't be set at the same time as TDTHRESH */
137958 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
137959 + return -EINVAL;
137960 + }
137961 + /* Issue an INITFQ_[PARKED|SCHED] management command */
137962 + p = get_affine_portal();
137963 + PORTAL_IRQ_LOCK(p, irqflags);
137964 + FQLOCK(fq);
137965 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137966 + ((fq->state != qman_fq_state_oos) &&
137967 + (fq->state != qman_fq_state_parked)))) {
137968 + FQUNLOCK(fq);
137969 + PORTAL_IRQ_UNLOCK(p, irqflags);
137970 + put_affine_portal();
137971 + return -EBUSY;
137972 + }
137973 + mcc = qm_mc_start(&p->p);
137974 + if (opts)
137975 + mcc->initfq = *opts;
137976 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
137977 + mcc->initfq.count = 0;
137978 +
137979 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
137980 + * demux pointer. Otherwise, the caller-provided value is allowed to
137981 + * stand, don't overwrite it. */
137982 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
137983 + dma_addr_t phys_fq;
137984 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
137985 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137986 + mcc->initfq.fqd.context_b = fq->key;
137987 +#else
137988 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
137989 +#endif
137990 + /* and the physical address - NB, if the user wasn't trying to
137991 + * set CONTEXTA, clear the stashing settings. */
137992 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
137993 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
137994 + memset(&mcc->initfq.fqd.context_a, 0,
137995 + sizeof(mcc->initfq.fqd.context_a));
137996 + } else {
137997 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
137998 + DMA_TO_DEVICE);
137999 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
138000 + }
138001 + }
138002 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
138003 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
138004 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
138005 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
138006 + mcc->initfq.fqd.dest.wq = 4;
138007 + }
138008 + }
138009 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
138010 + cpu_to_hw_fqd(&mcc->initfq.fqd);
138011 + qm_mc_commit(&p->p, myverb);
138012 + while (!(mcr = qm_mc_result(&p->p)))
138013 + cpu_relax();
138014 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138015 + res = mcr->result;
138016 + if (res != QM_MCR_RESULT_OK) {
138017 + FQUNLOCK(fq);
138018 + PORTAL_IRQ_UNLOCK(p, irqflags);
138019 + put_affine_portal();
138020 + return -EIO;
138021 + }
138022 + if (opts) {
138023 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
138024 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
138025 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
138026 + else
138027 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
138028 + }
138029 + if (opts->we_mask & QM_INITFQ_WE_CGID)
138030 + fq->cgr_groupid = opts->fqd.cgid;
138031 + }
138032 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
138033 + qman_fq_state_sched : qman_fq_state_parked;
138034 + FQUNLOCK(fq);
138035 + PORTAL_IRQ_UNLOCK(p, irqflags);
138036 + put_affine_portal();
138037 + return 0;
138038 +}
138039 +EXPORT_SYMBOL(qman_init_fq);
138040 +
138041 +int qman_schedule_fq(struct qman_fq *fq)
138042 +{
138043 + struct qm_mc_command *mcc;
138044 + struct qm_mc_result *mcr;
138045 + struct qman_portal *p;
138046 + unsigned long irqflags __maybe_unused;
138047 + int ret = 0;
138048 + u8 res;
138049 +
138050 + if (fq->state != qman_fq_state_parked)
138051 + return -EINVAL;
138052 +#ifdef CONFIG_FSL_DPA_CHECKING
138053 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138054 + return -EINVAL;
138055 +#endif
138056 + /* Issue a ALTERFQ_SCHED management command */
138057 + p = get_affine_portal();
138058 + PORTAL_IRQ_LOCK(p, irqflags);
138059 + FQLOCK(fq);
138060 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138061 + (fq->state != qman_fq_state_parked))) {
138062 + ret = -EBUSY;
138063 + goto out;
138064 + }
138065 + mcc = qm_mc_start(&p->p);
138066 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138067 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
138068 + while (!(mcr = qm_mc_result(&p->p)))
138069 + cpu_relax();
138070 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
138071 + res = mcr->result;
138072 + if (res != QM_MCR_RESULT_OK) {
138073 + ret = -EIO;
138074 + goto out;
138075 + }
138076 + fq->state = qman_fq_state_sched;
138077 +out:
138078 + FQUNLOCK(fq);
138079 + PORTAL_IRQ_UNLOCK(p, irqflags);
138080 + put_affine_portal();
138081 + return ret;
138082 +}
138083 +EXPORT_SYMBOL(qman_schedule_fq);
138084 +
138085 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
138086 +{
138087 + struct qm_mc_command *mcc;
138088 + struct qm_mc_result *mcr;
138089 + struct qman_portal *p;
138090 + unsigned long irqflags __maybe_unused;
138091 + int rval;
138092 + u8 res;
138093 +
138094 + if ((fq->state != qman_fq_state_parked) &&
138095 + (fq->state != qman_fq_state_sched))
138096 + return -EINVAL;
138097 +#ifdef CONFIG_FSL_DPA_CHECKING
138098 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138099 + return -EINVAL;
138100 +#endif
138101 + p = get_affine_portal();
138102 + PORTAL_IRQ_LOCK(p, irqflags);
138103 + FQLOCK(fq);
138104 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138105 + (fq->state == qman_fq_state_retired) ||
138106 + (fq->state == qman_fq_state_oos))) {
138107 + rval = -EBUSY;
138108 + goto out;
138109 + }
138110 + rval = table_push_fq(p, fq);
138111 + if (rval)
138112 + goto out;
138113 + mcc = qm_mc_start(&p->p);
138114 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138115 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
138116 + while (!(mcr = qm_mc_result(&p->p)))
138117 + cpu_relax();
138118 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
138119 + res = mcr->result;
138120 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
138121 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
138122 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
138123 + * friendly, otherwise the caller doesn't necessarily have a fully
138124 + * "retired" FQ on return even if the retirement was immediate. However
138125 + * this does mean some code duplication between here and
138126 + * fq_state_change(). */
138127 + if (likely(res == QM_MCR_RESULT_OK)) {
138128 + rval = 0;
138129 + /* Process 'fq' right away, we'll ignore FQRNI */
138130 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
138131 + fq_set(fq, QMAN_FQ_STATE_NE);
138132 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
138133 + fq_set(fq, QMAN_FQ_STATE_ORL);
138134 + else
138135 + table_del_fq(p, fq);
138136 + if (flags)
138137 + *flags = fq->flags;
138138 + fq->state = qman_fq_state_retired;
138139 + if (fq->cb.fqs) {
138140 + /* Another issue with supporting "immediate" retirement
138141 + * is that we're forced to drop FQRNIs, because by the
138142 + * time they're seen it may already be "too late" (the
138143 + * fq may have been OOS'd and free()'d already). But if
138144 + * the upper layer wants a callback whether it's
138145 + * immediate or not, we have to fake a "MR" entry to
138146 + * look like an FQRNI... */
138147 + struct qm_mr_entry msg;
138148 + msg.verb = QM_MR_VERB_FQRNI;
138149 + msg.fq.fqs = mcr->alterfq.fqs;
138150 + msg.fq.fqid = fq->fqid;
138151 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138152 + msg.fq.contextB = fq->key;
138153 +#else
138154 + msg.fq.contextB = (u32)(uintptr_t)fq;
138155 +#endif
138156 + fq->cb.fqs(p, fq, &msg);
138157 + }
138158 + } else if (res == QM_MCR_RESULT_PENDING) {
138159 + rval = 1;
138160 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
138161 + } else {
138162 + rval = -EIO;
138163 + table_del_fq(p, fq);
138164 + }
138165 +out:
138166 + FQUNLOCK(fq);
138167 + PORTAL_IRQ_UNLOCK(p, irqflags);
138168 + put_affine_portal();
138169 + return rval;
138170 +}
138171 +EXPORT_SYMBOL(qman_retire_fq);
138172 +
138173 +int qman_oos_fq(struct qman_fq *fq)
138174 +{
138175 + struct qm_mc_command *mcc;
138176 + struct qm_mc_result *mcr;
138177 + struct qman_portal *p;
138178 + unsigned long irqflags __maybe_unused;
138179 + int ret = 0;
138180 + u8 res;
138181 +
138182 + if (fq->state != qman_fq_state_retired)
138183 + return -EINVAL;
138184 +#ifdef CONFIG_FSL_DPA_CHECKING
138185 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138186 + return -EINVAL;
138187 +#endif
138188 + p = get_affine_portal();
138189 + PORTAL_IRQ_LOCK(p, irqflags);
138190 + FQLOCK(fq);
138191 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
138192 + (fq->state != qman_fq_state_retired))) {
138193 + ret = -EBUSY;
138194 + goto out;
138195 + }
138196 + mcc = qm_mc_start(&p->p);
138197 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138198 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
138199 + while (!(mcr = qm_mc_result(&p->p)))
138200 + cpu_relax();
138201 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
138202 + res = mcr->result;
138203 + if (res != QM_MCR_RESULT_OK) {
138204 + ret = -EIO;
138205 + goto out;
138206 + }
138207 + fq->state = qman_fq_state_oos;
138208 +out:
138209 + FQUNLOCK(fq);
138210 + PORTAL_IRQ_UNLOCK(p, irqflags);
138211 + put_affine_portal();
138212 + return ret;
138213 +}
138214 +EXPORT_SYMBOL(qman_oos_fq);
138215 +
138216 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
138217 +{
138218 + struct qm_mc_command *mcc;
138219 + struct qm_mc_result *mcr;
138220 + struct qman_portal *p;
138221 + unsigned long irqflags __maybe_unused;
138222 + int ret = 0;
138223 + u8 res;
138224 + u8 myverb;
138225 +
138226 + if ((fq->state == qman_fq_state_oos) ||
138227 + (fq->state == qman_fq_state_retired) ||
138228 + (fq->state == qman_fq_state_parked))
138229 + return -EINVAL;
138230 +
138231 +#ifdef CONFIG_FSL_DPA_CHECKING
138232 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138233 + return -EINVAL;
138234 +#endif
138235 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
138236 + p = get_affine_portal();
138237 + PORTAL_IRQ_LOCK(p, irqflags);
138238 + FQLOCK(fq);
138239 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138240 + (fq->state == qman_fq_state_parked) ||
138241 + (fq->state == qman_fq_state_oos) ||
138242 + (fq->state == qman_fq_state_retired))) {
138243 + ret = -EBUSY;
138244 + goto out;
138245 + }
138246 + mcc = qm_mc_start(&p->p);
138247 + mcc->alterfq.fqid = fq->fqid;
138248 + mcc->alterfq.count = 0;
138249 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
138250 +
138251 + qm_mc_commit(&p->p, myverb);
138252 + while (!(mcr = qm_mc_result(&p->p)))
138253 + cpu_relax();
138254 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138255 +
138256 + res = mcr->result;
138257 + if (res != QM_MCR_RESULT_OK) {
138258 + ret = -EIO;
138259 + goto out;
138260 + }
138261 +out:
138262 + FQUNLOCK(fq);
138263 + PORTAL_IRQ_UNLOCK(p, irqflags);
138264 + put_affine_portal();
138265 + return ret;
138266 +}
138267 +EXPORT_SYMBOL(qman_fq_flow_control);
138268 +
138269 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
138270 +{
138271 + struct qm_mc_command *mcc;
138272 + struct qm_mc_result *mcr;
138273 + struct qman_portal *p = get_affine_portal();
138274 + unsigned long irqflags __maybe_unused;
138275 + u8 res;
138276 +
138277 + PORTAL_IRQ_LOCK(p, irqflags);
138278 + mcc = qm_mc_start(&p->p);
138279 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138280 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
138281 + while (!(mcr = qm_mc_result(&p->p)))
138282 + cpu_relax();
138283 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
138284 + res = mcr->result;
138285 + if (res == QM_MCR_RESULT_OK)
138286 + *fqd = mcr->queryfq.fqd;
138287 + hw_fqd_to_cpu(fqd);
138288 + PORTAL_IRQ_UNLOCK(p, irqflags);
138289 + put_affine_portal();
138290 + if (res != QM_MCR_RESULT_OK)
138291 + return -EIO;
138292 + return 0;
138293 +}
138294 +EXPORT_SYMBOL(qman_query_fq);
138295 +
138296 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
138297 +{
138298 + struct qm_mc_command *mcc;
138299 + struct qm_mc_result *mcr;
138300 + struct qman_portal *p = get_affine_portal();
138301 + unsigned long irqflags __maybe_unused;
138302 + u8 res;
138303 +
138304 + PORTAL_IRQ_LOCK(p, irqflags);
138305 + mcc = qm_mc_start(&p->p);
138306 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138307 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
138308 + while (!(mcr = qm_mc_result(&p->p)))
138309 + cpu_relax();
138310 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
138311 + res = mcr->result;
138312 + if (res == QM_MCR_RESULT_OK) {
138313 + *np = mcr->queryfq_np;
138314 + np->fqd_link = be24_to_cpu(np->fqd_link);
138315 + np->odp_seq = be16_to_cpu(np->odp_seq);
138316 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
138317 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
138318 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
138319 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
138320 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
138321 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
138322 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
138323 + np->ics_surp = be16_to_cpu(np->ics_surp);
138324 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
138325 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
138326 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
138327 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
138328 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
138329 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
138330 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
138331 + }
138332 + PORTAL_IRQ_UNLOCK(p, irqflags);
138333 + put_affine_portal();
138334 + if (res == QM_MCR_RESULT_ERR_FQID)
138335 + return -ERANGE;
138336 + else if (res != QM_MCR_RESULT_OK)
138337 + return -EIO;
138338 + return 0;
138339 +}
138340 +EXPORT_SYMBOL(qman_query_fq_np);
138341 +
138342 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
138343 +{
138344 + struct qm_mc_command *mcc;
138345 + struct qm_mc_result *mcr;
138346 + struct qman_portal *p = get_affine_portal();
138347 + unsigned long irqflags __maybe_unused;
138348 + u8 res, myverb;
138349 +
138350 + PORTAL_IRQ_LOCK(p, irqflags);
138351 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
138352 + QM_MCR_VERB_QUERYWQ;
138353 + mcc = qm_mc_start(&p->p);
138354 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
138355 + qm_mc_commit(&p->p, myverb);
138356 + while (!(mcr = qm_mc_result(&p->p)))
138357 + cpu_relax();
138358 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138359 + res = mcr->result;
138360 + if (res == QM_MCR_RESULT_OK) {
138361 + int i, array_len;
138362 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
138363 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
138364 + for (i = 0; i < array_len; i++)
138365 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
138366 + }
138367 + PORTAL_IRQ_UNLOCK(p, irqflags);
138368 + put_affine_portal();
138369 + if (res != QM_MCR_RESULT_OK) {
138370 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
138371 + return -EIO;
138372 + }
138373 + return 0;
138374 +}
138375 +EXPORT_SYMBOL(qman_query_wq);
138376 +
138377 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
138378 + struct qm_mcr_cgrtestwrite *result)
138379 +{
138380 + struct qm_mc_command *mcc;
138381 + struct qm_mc_result *mcr;
138382 + struct qman_portal *p = get_affine_portal();
138383 + unsigned long irqflags __maybe_unused;
138384 + u8 res;
138385 +
138386 + PORTAL_IRQ_LOCK(p, irqflags);
138387 + mcc = qm_mc_start(&p->p);
138388 + mcc->cgrtestwrite.cgid = cgr->cgrid;
138389 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
138390 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
138391 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
138392 + while (!(mcr = qm_mc_result(&p->p)))
138393 + cpu_relax();
138394 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
138395 + res = mcr->result;
138396 + if (res == QM_MCR_RESULT_OK)
138397 + *result = mcr->cgrtestwrite;
138398 + PORTAL_IRQ_UNLOCK(p, irqflags);
138399 + put_affine_portal();
138400 + if (res != QM_MCR_RESULT_OK) {
138401 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
138402 + return -EIO;
138403 + }
138404 + return 0;
138405 +}
138406 +EXPORT_SYMBOL(qman_testwrite_cgr);
138407 +
138408 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
138409 +{
138410 + struct qm_mc_command *mcc;
138411 + struct qm_mc_result *mcr;
138412 + struct qman_portal *p = get_affine_portal();
138413 + unsigned long irqflags __maybe_unused;
138414 + u8 res;
138415 + int i;
138416 +
138417 + PORTAL_IRQ_LOCK(p, irqflags);
138418 + mcc = qm_mc_start(&p->p);
138419 + mcc->querycgr.cgid = cgr->cgrid;
138420 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
138421 + while (!(mcr = qm_mc_result(&p->p)))
138422 + cpu_relax();
138423 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
138424 + res = mcr->result;
138425 + if (res == QM_MCR_RESULT_OK)
138426 + *cgrd = mcr->querycgr;
138427 + PORTAL_IRQ_UNLOCK(p, irqflags);
138428 + put_affine_portal();
138429 + if (res != QM_MCR_RESULT_OK) {
138430 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
138431 + return -EIO;
138432 + }
138433 + cgrd->cgr.wr_parm_g.word =
138434 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
138435 + cgrd->cgr.wr_parm_y.word =
138436 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
138437 + cgrd->cgr.wr_parm_r.word =
138438 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
138439 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
138440 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
138441 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
138442 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
138443 + return 0;
138444 +}
138445 +EXPORT_SYMBOL(qman_query_cgr);
138446 +
138447 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
138448 +{
138449 + struct qm_mc_result *mcr;
138450 + struct qman_portal *p = get_affine_portal();
138451 + unsigned long irqflags __maybe_unused;
138452 + u8 res;
138453 + int i;
138454 +
138455 + PORTAL_IRQ_LOCK(p, irqflags);
138456 + qm_mc_start(&p->p);
138457 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138458 + while (!(mcr = qm_mc_result(&p->p)))
138459 + cpu_relax();
138460 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138461 + QM_MCC_VERB_QUERYCONGESTION);
138462 + res = mcr->result;
138463 + if (res == QM_MCR_RESULT_OK)
138464 + memcpy_fromio(congestion, &mcr->querycongestion,
138465 + sizeof(*congestion));
138466 + PORTAL_IRQ_UNLOCK(p, irqflags);
138467 + put_affine_portal();
138468 + if (res != QM_MCR_RESULT_OK) {
138469 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
138470 + return -EIO;
138471 + }
138472 +
138473 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
138474 + be32_to_cpus(&congestion->state.__state[i]);
138475 + return 0;
138476 +}
138477 +EXPORT_SYMBOL(qman_query_congestion);
138478 +
138479 +/* internal function used as a wait_event() expression */
138480 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
138481 +{
138482 + unsigned long irqflags __maybe_unused;
138483 + int ret = -EBUSY;
138484 + PORTAL_IRQ_LOCK(p, irqflags);
138485 + if (!p->vdqcr_owned) {
138486 + FQLOCK(fq);
138487 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138488 + goto escape;
138489 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
138490 + FQUNLOCK(fq);
138491 + p->vdqcr_owned = fq;
138492 + ret = 0;
138493 + }
138494 +escape:
138495 + PORTAL_IRQ_UNLOCK(p, irqflags);
138496 + if (!ret)
138497 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
138498 + return ret;
138499 +}
138500 +
138501 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
138502 +{
138503 + int ret;
138504 + *p = get_affine_portal();
138505 + ret = set_p_vdqcr(*p, fq, vdqcr);
138506 + put_affine_portal();
138507 + return ret;
138508 +}
138509 +
138510 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138511 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
138512 + u32 vdqcr, u32 flags)
138513 +{
138514 + int ret = 0;
138515 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138516 + ret = wait_event_interruptible(affine_queue,
138517 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
138518 + else
138519 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
138520 + return ret;
138521 +}
138522 +
138523 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
138524 + u32 vdqcr, u32 flags)
138525 +{
138526 + int ret = 0;
138527 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138528 + ret = wait_event_interruptible(affine_queue,
138529 + !(ret = set_vdqcr(p, fq, vdqcr)));
138530 + else
138531 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
138532 + return ret;
138533 +}
138534 +#endif
138535 +
138536 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
138537 + u32 flags __maybe_unused, u32 vdqcr)
138538 +{
138539 + int ret;
138540 +
138541 + if ((fq->state != qman_fq_state_parked) &&
138542 + (fq->state != qman_fq_state_retired))
138543 + return -EINVAL;
138544 + if (vdqcr & QM_VDQCR_FQID_MASK)
138545 + return -EINVAL;
138546 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138547 + return -EBUSY;
138548 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138549 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138550 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138551 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
138552 + else
138553 +#endif
138554 + ret = set_p_vdqcr(p, fq, vdqcr);
138555 + if (ret)
138556 + return ret;
138557 + /* VDQCR is set */
138558 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138559 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138560 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138561 + /* NB: don't propagate any error - the caller wouldn't
138562 + * know whether the VDQCR was issued or not. A signal
138563 + * could arrive after returning anyway, so the caller
138564 + * can check signal_pending() if that's an issue. */
138565 + wait_event_interruptible(affine_queue,
138566 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138567 + else
138568 + wait_event(affine_queue,
138569 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138570 + }
138571 +#endif
138572 + return 0;
138573 +}
138574 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
138575 +
138576 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
138577 + u32 vdqcr)
138578 +{
138579 + struct qman_portal *p;
138580 + int ret;
138581 +
138582 + if ((fq->state != qman_fq_state_parked) &&
138583 + (fq->state != qman_fq_state_retired))
138584 + return -EINVAL;
138585 + if (vdqcr & QM_VDQCR_FQID_MASK)
138586 + return -EINVAL;
138587 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138588 + return -EBUSY;
138589 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138590 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138591 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138592 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
138593 + else
138594 +#endif
138595 + ret = set_vdqcr(&p, fq, vdqcr);
138596 + if (ret)
138597 + return ret;
138598 + /* VDQCR is set */
138599 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138600 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138601 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138602 + /* NB: don't propagate any error - the caller wouldn't
138603 + * know whether the VDQCR was issued or not. A signal
138604 + * could arrive after returning anyway, so the caller
138605 + * can check signal_pending() if that's an issue. */
138606 + wait_event_interruptible(affine_queue,
138607 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138608 + else
138609 + wait_event(affine_queue,
138610 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138611 + }
138612 +#endif
138613 + return 0;
138614 +}
138615 +EXPORT_SYMBOL(qman_volatile_dequeue);
138616 +
138617 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
138618 +{
138619 + if (avail)
138620 + qm_eqcr_cce_prefetch(&p->p);
138621 + else
138622 + qm_eqcr_cce_update(&p->p);
138623 +}
138624 +
138625 +int qman_eqcr_is_empty(void)
138626 +{
138627 + unsigned long irqflags __maybe_unused;
138628 + struct qman_portal *p = get_affine_portal();
138629 + u8 avail;
138630 +
138631 + PORTAL_IRQ_LOCK(p, irqflags);
138632 + update_eqcr_ci(p, 0);
138633 + avail = qm_eqcr_get_fill(&p->p);
138634 + PORTAL_IRQ_UNLOCK(p, irqflags);
138635 + put_affine_portal();
138636 + return avail == 0;
138637 +}
138638 +EXPORT_SYMBOL(qman_eqcr_is_empty);
138639 +
138640 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
138641 +{
138642 + if (affine) {
138643 + unsigned long irqflags __maybe_unused;
138644 + struct qman_portal *p = get_affine_portal();
138645 + PORTAL_IRQ_LOCK(p, irqflags);
138646 + p->cb_dc_ern = handler;
138647 + PORTAL_IRQ_UNLOCK(p, irqflags);
138648 + put_affine_portal();
138649 + } else
138650 + cb_dc_ern = handler;
138651 +}
138652 +EXPORT_SYMBOL(qman_set_dc_ern);
138653 +
138654 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
138655 + unsigned long *irqflags __maybe_unused,
138656 + struct qman_fq *fq,
138657 + const struct qm_fd *fd,
138658 + u32 flags)
138659 +{
138660 + struct qm_eqcr_entry *eq;
138661 + u8 avail;
138662 + PORTAL_IRQ_LOCK(p, (*irqflags));
138663 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138664 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138665 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138666 + if (p->eqci_owned) {
138667 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138668 + return NULL;
138669 + }
138670 + p->eqci_owned = fq;
138671 + }
138672 +#endif
138673 + if (p->use_eqcr_ci_stashing) {
138674 + /*
138675 + * The stashing case is easy, only update if we need to in
138676 + * order to try and liberate ring entries.
138677 + */
138678 + eq = qm_eqcr_start_stash(&p->p);
138679 + } else {
138680 + /*
138681 + * The non-stashing case is harder, need to prefetch ahead of
138682 + * time.
138683 + */
138684 + avail = qm_eqcr_get_avail(&p->p);
138685 + if (avail < 2)
138686 + update_eqcr_ci(p, avail);
138687 + eq = qm_eqcr_start_no_stash(&p->p);
138688 + }
138689 +
138690 + if (unlikely(!eq)) {
138691 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138692 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138693 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
138694 + p->eqci_owned = NULL;
138695 +#endif
138696 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138697 + return NULL;
138698 + }
138699 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
138700 + eq->dca = QM_EQCR_DCA_ENABLE |
138701 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
138702 + QM_EQCR_DCA_PARK : 0) |
138703 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
138704 + eq->fqid = cpu_to_be32(fq->fqid);
138705 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138706 + eq->tag = cpu_to_be32(fq->key);
138707 +#else
138708 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
138709 +#endif
138710 + eq->fd = *fd;
138711 + cpu_to_hw_fd(&eq->fd);
138712 + return eq;
138713 +}
138714 +
138715 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138716 + unsigned long *irqflags __maybe_unused,
138717 + struct qman_fq *fq,
138718 + const struct qm_fd *fd,
138719 + u32 flags)
138720 +{
138721 + struct qm_eqcr_entry *eq;
138722 + *p = get_affine_portal();
138723 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138724 + if (!eq)
138725 + put_affine_portal();
138726 + return eq;
138727 +}
138728 +
138729 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138730 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138731 + unsigned long *irqflags __maybe_unused,
138732 + struct qman_fq *fq,
138733 + const struct qm_fd *fd,
138734 + u32 flags)
138735 +{
138736 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138737 + if (!eq)
138738 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138739 + return eq;
138740 +}
138741 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138742 + unsigned long *irqflags __maybe_unused,
138743 + struct qman_fq *fq,
138744 + const struct qm_fd *fd,
138745 + u32 flags)
138746 +{
138747 + struct qm_eqcr_entry *eq;
138748 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138749 + /* NB: return NULL if signal occurs before completion. Signal
138750 + * can occur during return. Caller must check for signal */
138751 + wait_event_interruptible(affine_queue,
138752 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138753 + else
138754 + wait_event(affine_queue,
138755 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138756 + return eq;
138757 +}
138758 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138759 + unsigned long *irqflags __maybe_unused,
138760 + struct qman_fq *fq,
138761 + const struct qm_fd *fd,
138762 + u32 flags)
138763 +{
138764 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138765 + if (!eq)
138766 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138767 + return eq;
138768 +}
138769 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138770 + unsigned long *irqflags __maybe_unused,
138771 + struct qman_fq *fq,
138772 + const struct qm_fd *fd,
138773 + u32 flags)
138774 +{
138775 + struct qm_eqcr_entry *eq;
138776 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138777 + /* NB: return NULL if signal occurs before completion. Signal
138778 + * can occur during return. Caller must check for signal */
138779 + wait_event_interruptible(affine_queue,
138780 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138781 + else
138782 + wait_event(affine_queue,
138783 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138784 + return eq;
138785 +}
138786 +#endif
138787 +
138788 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138789 + const struct qm_fd *fd, u32 flags)
138790 +{
138791 + struct qm_eqcr_entry *eq;
138792 + unsigned long irqflags __maybe_unused;
138793 +
138794 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138795 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138796 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138797 + else
138798 +#endif
138799 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138800 + if (!eq)
138801 + return -EBUSY;
138802 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138803 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138804 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138805 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138806 + PORTAL_IRQ_UNLOCK(p, irqflags);
138807 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138808 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138809 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138810 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138811 + /* NB: return success even if signal occurs before
138812 + * condition is true. pvb_commit guarantees success */
138813 + wait_event_interruptible(affine_queue,
138814 + (p->eqci_owned != fq));
138815 + else
138816 + wait_event(affine_queue, (p->eqci_owned != fq));
138817 + }
138818 +#endif
138819 + return 0;
138820 +}
138821 +EXPORT_SYMBOL(qman_p_enqueue);
138822 +
138823 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
138824 +{
138825 + struct qman_portal *p;
138826 + struct qm_eqcr_entry *eq;
138827 + unsigned long irqflags __maybe_unused;
138828 +
138829 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138830 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138831 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138832 + else
138833 +#endif
138834 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138835 + if (!eq)
138836 + return -EBUSY;
138837 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138838 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138839 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138840 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138841 + PORTAL_IRQ_UNLOCK(p, irqflags);
138842 + put_affine_portal();
138843 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138844 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138845 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138846 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138847 + /* NB: return success even if signal occurs before
138848 + * condition is true. pvb_commit guarantees success */
138849 + wait_event_interruptible(affine_queue,
138850 + (p->eqci_owned != fq));
138851 + else
138852 + wait_event(affine_queue, (p->eqci_owned != fq));
138853 + }
138854 +#endif
138855 + return 0;
138856 +}
138857 +EXPORT_SYMBOL(qman_enqueue);
138858 +
138859 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
138860 + const struct qm_fd *fd, u32 flags,
138861 + struct qman_fq *orp, u16 orp_seqnum)
138862 +{
138863 + struct qm_eqcr_entry *eq;
138864 + unsigned long irqflags __maybe_unused;
138865 +
138866 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138867 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138868 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138869 + else
138870 +#endif
138871 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138872 + if (!eq)
138873 + return -EBUSY;
138874 + /* Process ORP-specifics here */
138875 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138876 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138877 + else {
138878 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138879 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138880 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138881 + else
138882 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138883 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138884 + }
138885 + eq->seqnum = cpu_to_be16(orp_seqnum);
138886 + eq->orp = cpu_to_be32(orp->fqid);
138887 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138888 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138889 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138890 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138891 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138892 + PORTAL_IRQ_UNLOCK(p, irqflags);
138893 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138894 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138895 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138896 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138897 + /* NB: return success even if signal occurs before
138898 + * condition is true. pvb_commit guarantees success */
138899 + wait_event_interruptible(affine_queue,
138900 + (p->eqci_owned != fq));
138901 + else
138902 + wait_event(affine_queue, (p->eqci_owned != fq));
138903 + }
138904 +#endif
138905 + return 0;
138906 +}
138907 +EXPORT_SYMBOL(qman_p_enqueue_orp);
138908 +
138909 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
138910 + struct qman_fq *orp, u16 orp_seqnum)
138911 +{
138912 + struct qman_portal *p;
138913 + struct qm_eqcr_entry *eq;
138914 + unsigned long irqflags __maybe_unused;
138915 +
138916 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138917 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138918 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138919 + else
138920 +#endif
138921 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138922 + if (!eq)
138923 + return -EBUSY;
138924 + /* Process ORP-specifics here */
138925 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138926 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138927 + else {
138928 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138929 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138930 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138931 + else
138932 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138933 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138934 + }
138935 + eq->seqnum = cpu_to_be16(orp_seqnum);
138936 + eq->orp = cpu_to_be32(orp->fqid);
138937 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138938 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138939 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138940 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138941 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138942 + PORTAL_IRQ_UNLOCK(p, irqflags);
138943 + put_affine_portal();
138944 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138945 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138946 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138947 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138948 + /* NB: return success even if signal occurs before
138949 + * condition is true. pvb_commit guarantees success */
138950 + wait_event_interruptible(affine_queue,
138951 + (p->eqci_owned != fq));
138952 + else
138953 + wait_event(affine_queue, (p->eqci_owned != fq));
138954 + }
138955 +#endif
138956 + return 0;
138957 +}
138958 +EXPORT_SYMBOL(qman_enqueue_orp);
138959 +
138960 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
138961 + const struct qm_fd *fd, u32 flags,
138962 + qman_cb_precommit cb, void *cb_arg)
138963 +{
138964 + struct qm_eqcr_entry *eq;
138965 + unsigned long irqflags __maybe_unused;
138966 +
138967 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138968 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138969 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138970 + else
138971 +#endif
138972 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138973 + if (!eq)
138974 + return -EBUSY;
138975 + /* invoke user supplied callback function before writing commit verb */
138976 + if (cb(cb_arg)) {
138977 + PORTAL_IRQ_UNLOCK(p, irqflags);
138978 + return -EINVAL;
138979 + }
138980 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138981 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138982 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138983 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138984 + PORTAL_IRQ_UNLOCK(p, irqflags);
138985 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138986 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138987 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138988 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138989 + /* NB: return success even if signal occurs before
138990 + * condition is true. pvb_commit guarantees success */
138991 + wait_event_interruptible(affine_queue,
138992 + (p->eqci_owned != fq));
138993 + else
138994 + wait_event(affine_queue, (p->eqci_owned != fq));
138995 + }
138996 +#endif
138997 + return 0;
138998 +}
138999 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
139000 +
139001 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
139002 + u32 flags, qman_cb_precommit cb, void *cb_arg)
139003 +{
139004 + struct qman_portal *p;
139005 + struct qm_eqcr_entry *eq;
139006 + unsigned long irqflags __maybe_unused;
139007 +
139008 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139009 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139010 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139011 + else
139012 +#endif
139013 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139014 + if (!eq)
139015 + return -EBUSY;
139016 + /* invoke user supplied callback function before writing commit verb */
139017 + if (cb(cb_arg)) {
139018 + PORTAL_IRQ_UNLOCK(p, irqflags);
139019 + put_affine_portal();
139020 + return -EINVAL;
139021 + }
139022 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139023 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139024 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139025 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139026 + PORTAL_IRQ_UNLOCK(p, irqflags);
139027 + put_affine_portal();
139028 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139029 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139030 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139031 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139032 + /* NB: return success even if signal occurs before
139033 + * condition is true. pvb_commit guarantees success */
139034 + wait_event_interruptible(affine_queue,
139035 + (p->eqci_owned != fq));
139036 + else
139037 + wait_event(affine_queue, (p->eqci_owned != fq));
139038 + }
139039 +#endif
139040 + return 0;
139041 +}
139042 +EXPORT_SYMBOL(qman_enqueue_precommit);
139043 +
139044 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
139045 + struct qm_mcc_initcgr *opts)
139046 +{
139047 + struct qm_mc_command *mcc;
139048 + struct qm_mc_result *mcr;
139049 + struct qman_portal *p = get_affine_portal();
139050 + unsigned long irqflags __maybe_unused;
139051 + u8 res;
139052 + u8 verb = QM_MCC_VERB_MODIFYCGR;
139053 +
139054 + PORTAL_IRQ_LOCK(p, irqflags);
139055 + mcc = qm_mc_start(&p->p);
139056 + if (opts)
139057 + mcc->initcgr = *opts;
139058 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
139059 + mcc->initcgr.cgr.wr_parm_g.word =
139060 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
139061 + mcc->initcgr.cgr.wr_parm_y.word =
139062 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
139063 + mcc->initcgr.cgr.wr_parm_r.word =
139064 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
139065 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
139066 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
139067 +
139068 + mcc->initcgr.cgid = cgr->cgrid;
139069 + if (flags & QMAN_CGR_FLAG_USE_INIT)
139070 + verb = QM_MCC_VERB_INITCGR;
139071 + qm_mc_commit(&p->p, verb);
139072 + while (!(mcr = qm_mc_result(&p->p)))
139073 + cpu_relax();
139074 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
139075 + res = mcr->result;
139076 + PORTAL_IRQ_UNLOCK(p, irqflags);
139077 + put_affine_portal();
139078 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
139079 +}
139080 +EXPORT_SYMBOL(qman_modify_cgr);
139081 +
139082 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
139083 + QM_CHANNEL_SWPORTAL0))
139084 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
139085 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
139086 +
139087 +static u8 qman_cgr_cpus[__CGR_NUM];
139088 +
139089 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
139090 + struct qm_mcc_initcgr *opts)
139091 +{
139092 + unsigned long irqflags __maybe_unused;
139093 + struct qm_mcr_querycgr cgr_state;
139094 + struct qm_mcc_initcgr local_opts;
139095 + int ret;
139096 + struct qman_portal *p;
139097 +
139098 + /* We have to check that the provided CGRID is within the limits of the
139099 + * data-structures, for obvious reasons. However we'll let h/w take
139100 + * care of determining whether it's within the limits of what exists on
139101 + * the SoC. */
139102 + if (cgr->cgrid >= __CGR_NUM)
139103 + return -EINVAL;
139104 +
139105 + preempt_disable();
139106 + p = get_affine_portal();
139107 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
139108 + preempt_enable();
139109 +
139110 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139111 + cgr->chan = p->config->public_cfg.channel;
139112 + spin_lock_irqsave(&p->cgr_lock, irqflags);
139113 +
139114 + /* if no opts specified, just add it to the list */
139115 + if (!opts)
139116 + goto add_list;
139117 +
139118 + ret = qman_query_cgr(cgr, &cgr_state);
139119 + if (ret)
139120 + goto release_lock;
139121 + if (opts)
139122 + local_opts = *opts;
139123 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139124 + local_opts.cgr.cscn_targ_upd_ctrl =
139125 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
139126 + else
139127 + /* Overwrite TARG */
139128 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
139129 + TARG_MASK(p);
139130 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
139131 +
139132 + /* send init if flags indicate so */
139133 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
139134 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
139135 + else
139136 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139137 + if (ret)
139138 + goto release_lock;
139139 +add_list:
139140 + list_add(&cgr->node, &p->cgr_cbs);
139141 +
139142 + /* Determine if newly added object requires its callback to be called */
139143 + ret = qman_query_cgr(cgr, &cgr_state);
139144 + if (ret) {
139145 + /* we can't go back, so proceed and return success, but screen
139146 + * and wail to the log file */
139147 + pr_crit("CGR HW state partially modified\n");
139148 + ret = 0;
139149 + goto release_lock;
139150 + }
139151 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
139152 + cgr->cgrid))
139153 + cgr->cb(p, cgr, 1);
139154 +release_lock:
139155 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
139156 + put_affine_portal();
139157 + return ret;
139158 +}
139159 +EXPORT_SYMBOL(qman_create_cgr);
139160 +
139161 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
139162 + struct qm_mcc_initcgr *opts)
139163 +{
139164 + unsigned long irqflags __maybe_unused;
139165 + struct qm_mcc_initcgr local_opts;
139166 + struct qm_mcr_querycgr cgr_state;
139167 + int ret;
139168 +
139169 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
139170 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
139171 + return -EINVAL;
139172 + }
139173 + /* We have to check that the provided CGRID is within the limits of the
139174 + * data-structures, for obvious reasons. However we'll let h/w take
139175 + * care of determining whether it's within the limits of what exists on
139176 + * the SoC.
139177 + */
139178 + if (cgr->cgrid >= __CGR_NUM)
139179 + return -EINVAL;
139180 +
139181 + ret = qman_query_cgr(cgr, &cgr_state);
139182 + if (ret)
139183 + return ret;
139184 +
139185 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139186 + if (opts)
139187 + local_opts = *opts;
139188 +
139189 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139190 + local_opts.cgr.cscn_targ_upd_ctrl =
139191 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
139192 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
139193 + else
139194 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
139195 + TARG_DCP_MASK(dcp_portal);
139196 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
139197 +
139198 + /* send init if flags indicate so */
139199 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
139200 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
139201 + &local_opts);
139202 + else
139203 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139204 +
139205 + return ret;
139206 +}
139207 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
139208 +
139209 +int qman_delete_cgr(struct qman_cgr *cgr)
139210 +{
139211 + unsigned long irqflags __maybe_unused;
139212 + struct qm_mcr_querycgr cgr_state;
139213 + struct qm_mcc_initcgr local_opts;
139214 + int ret = 0;
139215 + struct qman_cgr *i;
139216 + struct qman_portal *p = get_affine_portal();
139217 +
139218 + if (cgr->chan != p->config->public_cfg.channel) {
139219 + pr_crit("Attempting to delete cgr from different portal "
139220 + "than it was create: create 0x%x, delete 0x%x\n",
139221 + cgr->chan, p->config->public_cfg.channel);
139222 + ret = -EINVAL;
139223 + goto put_portal;
139224 + }
139225 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139226 + spin_lock_irqsave(&p->cgr_lock, irqflags);
139227 + list_del(&cgr->node);
139228 + /*
139229 + * If there are no other CGR objects for this CGRID in the list, update
139230 + * CSCN_TARG accordingly
139231 + */
139232 + list_for_each_entry(i, &p->cgr_cbs, node)
139233 + if ((i->cgrid == cgr->cgrid) && i->cb)
139234 + goto release_lock;
139235 + ret = qman_query_cgr(cgr, &cgr_state);
139236 + if (ret) {
139237 + /* add back to the list */
139238 + list_add(&cgr->node, &p->cgr_cbs);
139239 + goto release_lock;
139240 + }
139241 + /* Overwrite TARG */
139242 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
139243 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139244 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
139245 + else
139246 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
139247 + ~(TARG_MASK(p));
139248 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139249 + if (ret)
139250 + /* add back to the list */
139251 + list_add(&cgr->node, &p->cgr_cbs);
139252 +release_lock:
139253 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
139254 +put_portal:
139255 + put_affine_portal();
139256 + return ret;
139257 +}
139258 +EXPORT_SYMBOL(qman_delete_cgr);
139259 +
139260 +struct cgr_comp {
139261 + struct qman_cgr *cgr;
139262 + struct completion completion;
139263 +};
139264 +
139265 +static int qman_delete_cgr_thread(void *p)
139266 +{
139267 + struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
139268 + int res;
139269 +
139270 + res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
139271 + complete(&cgr_comp->completion);
139272 +
139273 + return res;
139274 +}
139275 +
139276 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
139277 +{
139278 + struct task_struct *thread;
139279 + struct cgr_comp cgr_comp;
139280 +
139281 + preempt_disable();
139282 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
139283 + init_completion(&cgr_comp.completion);
139284 + cgr_comp.cgr = cgr;
139285 + thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
139286 + "cgr_del");
139287 +
139288 + if (likely(!IS_ERR(thread))) {
139289 + kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
139290 + wake_up_process(thread);
139291 + wait_for_completion(&cgr_comp.completion);
139292 + preempt_enable();
139293 + return;
139294 + }
139295 + }
139296 + qman_delete_cgr(cgr);
139297 + preempt_enable();
139298 +}
139299 +EXPORT_SYMBOL(qman_delete_cgr_safe);
139300 +
139301 +int qm_get_clock(u64 *clock_hz)
139302 +{
139303 + if (!qman_clk) {
139304 + pr_warn("Qman clock speed is unknown\n");
139305 + return -EINVAL;
139306 + }
139307 + *clock_hz = (u64)qman_clk;
139308 + return 0;
139309 +}
139310 +EXPORT_SYMBOL(qm_get_clock);
139311 +
139312 +int qm_set_clock(u64 clock_hz)
139313 +{
139314 + if (qman_clk)
139315 + return -1;
139316 + qman_clk = (u32)clock_hz;
139317 + return 0;
139318 +}
139319 +EXPORT_SYMBOL(qm_set_clock);
139320 +
139321 +/* CEETM management command */
139322 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
139323 +{
139324 + struct qm_mc_command *mcc;
139325 + struct qm_mc_result *mcr;
139326 + struct qman_portal *p;
139327 + unsigned long irqflags __maybe_unused;
139328 + u8 res;
139329 +
139330 + p = get_affine_portal();
139331 + PORTAL_IRQ_LOCK(p, irqflags);
139332 +
139333 + mcc = qm_mc_start(&p->p);
139334 + mcc->lfqmt_config = *opts;
139335 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
139336 + while (!(mcr = qm_mc_result(&p->p)))
139337 + cpu_relax();
139338 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139339 + QM_CEETM_VERB_LFQMT_CONFIG);
139340 + PORTAL_IRQ_UNLOCK(p, irqflags);
139341 + put_affine_portal();
139342 +
139343 + res = mcr->result;
139344 + if (res != QM_MCR_RESULT_OK) {
139345 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
139346 + return -EIO;
139347 + }
139348 + return 0;
139349 +}
139350 +
139351 +int qman_ceetm_query_lfqmt(int lfqid,
139352 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
139353 +{
139354 + struct qm_mc_command *mcc;
139355 + struct qm_mc_result *mcr;
139356 + struct qman_portal *p;
139357 + unsigned long irqflags __maybe_unused;
139358 + u8 res;
139359 +
139360 + p = get_affine_portal();
139361 + PORTAL_IRQ_LOCK(p, irqflags);
139362 +
139363 + mcc = qm_mc_start(&p->p);
139364 + mcc->lfqmt_query.lfqid = lfqid;
139365 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
139366 + while (!(mcr = qm_mc_result(&p->p)))
139367 + cpu_relax();
139368 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
139369 + res = mcr->result;
139370 + if (res == QM_MCR_RESULT_OK)
139371 + *lfqmt_query = mcr->lfqmt_query;
139372 +
139373 + PORTAL_IRQ_UNLOCK(p, irqflags);
139374 + put_affine_portal();
139375 + if (res != QM_MCR_RESULT_OK) {
139376 + pr_err("CEETM: QUERY LFQMT failed\n");
139377 + return -EIO;
139378 + }
139379 + return 0;
139380 +}
139381 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
139382 +
139383 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
139384 +{
139385 + struct qm_mc_command *mcc;
139386 + struct qm_mc_result *mcr;
139387 + struct qman_portal *p;
139388 + unsigned long irqflags __maybe_unused;
139389 + u8 res;
139390 +
139391 + p = get_affine_portal();
139392 + PORTAL_IRQ_LOCK(p, irqflags);
139393 +
139394 + mcc = qm_mc_start(&p->p);
139395 + mcc->cq_config = *opts;
139396 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
139397 + while (!(mcr = qm_mc_result(&p->p)))
139398 + cpu_relax();
139399 + res = mcr->result;
139400 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
139401 +
139402 + PORTAL_IRQ_UNLOCK(p, irqflags);
139403 + put_affine_portal();
139404 +
139405 + if (res != QM_MCR_RESULT_OK) {
139406 + pr_err("CEETM: CONFIGURE CQ failed\n");
139407 + return -EIO;
139408 + }
139409 + return 0;
139410 +}
139411 +
139412 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
139413 + struct qm_mcr_ceetm_cq_query *cq_query)
139414 +{
139415 + struct qm_mc_command *mcc;
139416 + struct qm_mc_result *mcr;
139417 + struct qman_portal *p;
139418 + unsigned long irqflags __maybe_unused;
139419 + u8 res;
139420 +
139421 + p = get_affine_portal();
139422 + PORTAL_IRQ_LOCK(p, irqflags);
139423 +
139424 + mcc = qm_mc_start(&p->p);
139425 + mcc->cq_query.cqid = cpu_to_be16(cqid);
139426 + mcc->cq_query.dcpid = dcpid;
139427 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
139428 + while (!(mcr = qm_mc_result(&p->p)))
139429 + cpu_relax();
139430 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
139431 + res = mcr->result;
139432 + if (res == QM_MCR_RESULT_OK) {
139433 + *cq_query = mcr->cq_query;
139434 + hw_cq_query_to_cpu(cq_query);
139435 + }
139436 +
139437 + PORTAL_IRQ_UNLOCK(p, irqflags);
139438 + put_affine_portal();
139439 +
139440 + if (res != QM_MCR_RESULT_OK) {
139441 + pr_err("CEETM: QUERY CQ failed\n");
139442 + return -EIO;
139443 + }
139444 +
139445 + return 0;
139446 +}
139447 +EXPORT_SYMBOL(qman_ceetm_query_cq);
139448 +
139449 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
139450 +{
139451 + struct qm_mc_command *mcc;
139452 + struct qm_mc_result *mcr;
139453 + struct qman_portal *p;
139454 + unsigned long irqflags __maybe_unused;
139455 + u8 res;
139456 +
139457 + p = get_affine_portal();
139458 + PORTAL_IRQ_LOCK(p, irqflags);
139459 +
139460 + mcc = qm_mc_start(&p->p);
139461 + mcc->dct_config = *opts;
139462 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
139463 + while (!(mcr = qm_mc_result(&p->p)))
139464 + cpu_relax();
139465 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
139466 + res = mcr->result;
139467 +
139468 + PORTAL_IRQ_UNLOCK(p, irqflags);
139469 + put_affine_portal();
139470 +
139471 + if (res != QM_MCR_RESULT_OK) {
139472 + pr_err("CEETM: CONFIGURE DCT failed\n");
139473 + return -EIO;
139474 + }
139475 + return 0;
139476 +}
139477 +
139478 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
139479 + struct qm_mcr_ceetm_dct_query *dct_query)
139480 +{
139481 + struct qm_mc_command *mcc;
139482 + struct qm_mc_result *mcr;
139483 + struct qman_portal *p = get_affine_portal();
139484 + unsigned long irqflags __maybe_unused;
139485 + u8 res;
139486 +
139487 + PORTAL_IRQ_LOCK(p, irqflags);
139488 +
139489 + mcc = qm_mc_start(&p->p);
139490 + mcc->dct_query = *opts;
139491 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
139492 + while (!(mcr = qm_mc_result(&p->p)))
139493 + cpu_relax();
139494 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
139495 + res = mcr->result;
139496 +
139497 + PORTAL_IRQ_UNLOCK(p, irqflags);
139498 + put_affine_portal();
139499 +
139500 + if (res != QM_MCR_RESULT_OK) {
139501 + pr_err("CEETM: QUERY DCT failed\n");
139502 + return -EIO;
139503 + }
139504 +
139505 + *dct_query = mcr->dct_query;
139506 + return 0;
139507 +}
139508 +
139509 +static int qman_ceetm_configure_class_scheduler(
139510 + struct qm_mcc_ceetm_class_scheduler_config *opts)
139511 +{
139512 + struct qm_mc_command *mcc;
139513 + struct qm_mc_result *mcr;
139514 + struct qman_portal *p;
139515 + unsigned long irqflags __maybe_unused;
139516 + u8 res;
139517 +
139518 + p = get_affine_portal();
139519 + PORTAL_IRQ_LOCK(p, irqflags);
139520 +
139521 + mcc = qm_mc_start(&p->p);
139522 + mcc->csch_config = *opts;
139523 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139524 + while (!(mcr = qm_mc_result(&p->p)))
139525 + cpu_relax();
139526 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139527 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139528 + res = mcr->result;
139529 +
139530 + PORTAL_IRQ_UNLOCK(p, irqflags);
139531 + put_affine_portal();
139532 +
139533 + if (res != QM_MCR_RESULT_OK) {
139534 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
139535 + return -EIO;
139536 + }
139537 + return 0;
139538 +}
139539 +
139540 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
139541 + struct qm_mcr_ceetm_class_scheduler_query *query)
139542 +{
139543 + struct qm_mc_command *mcc;
139544 + struct qm_mc_result *mcr;
139545 + struct qman_portal *p;
139546 + unsigned long irqflags __maybe_unused;
139547 + u8 res;
139548 +
139549 + p = get_affine_portal();
139550 + PORTAL_IRQ_LOCK(p, irqflags);
139551 +
139552 + mcc = qm_mc_start(&p->p);
139553 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
139554 + mcc->csch_query.dcpid = channel->dcp_idx;
139555 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139556 + while (!(mcr = qm_mc_result(&p->p)))
139557 + cpu_relax();
139558 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139559 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139560 + res = mcr->result;
139561 +
139562 + PORTAL_IRQ_UNLOCK(p, irqflags);
139563 + put_affine_portal();
139564 +
139565 + if (res != QM_MCR_RESULT_OK) {
139566 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
139567 + return -EIO;
139568 + }
139569 + *query = mcr->csch_query;
139570 + return 0;
139571 +}
139572 +
139573 +static int qman_ceetm_configure_mapping_shaper_tcfc(
139574 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
139575 +{
139576 + struct qm_mc_command *mcc;
139577 + struct qm_mc_result *mcr;
139578 + struct qman_portal *p;
139579 + unsigned long irqflags __maybe_unused;
139580 + u8 res;
139581 +
139582 + p = get_affine_portal();
139583 + PORTAL_IRQ_LOCK(p, irqflags);
139584 +
139585 + mcc = qm_mc_start(&p->p);
139586 + mcc->mst_config = *opts;
139587 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139588 + while (!(mcr = qm_mc_result(&p->p)))
139589 + cpu_relax();
139590 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139591 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139592 + res = mcr->result;
139593 +
139594 + PORTAL_IRQ_UNLOCK(p, irqflags);
139595 + put_affine_portal();
139596 +
139597 + if (res != QM_MCR_RESULT_OK) {
139598 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
139599 + return -EIO;
139600 + }
139601 + return 0;
139602 +}
139603 +
139604 +static int qman_ceetm_query_mapping_shaper_tcfc(
139605 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
139606 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
139607 +{
139608 + struct qm_mc_command *mcc;
139609 + struct qm_mc_result *mcr;
139610 + struct qman_portal *p;
139611 + unsigned long irqflags __maybe_unused;
139612 + u8 res;
139613 +
139614 + p = get_affine_portal();
139615 + PORTAL_IRQ_LOCK(p, irqflags);
139616 +
139617 + mcc = qm_mc_start(&p->p);
139618 + mcc->mst_query = *opts;
139619 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139620 + while (!(mcr = qm_mc_result(&p->p)))
139621 + cpu_relax();
139622 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139623 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139624 + res = mcr->result;
139625 +
139626 + PORTAL_IRQ_UNLOCK(p, irqflags);
139627 + put_affine_portal();
139628 +
139629 + if (res != QM_MCR_RESULT_OK) {
139630 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
139631 + return -EIO;
139632 + }
139633 +
139634 + *response = mcr->mst_query;
139635 + return 0;
139636 +}
139637 +
139638 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
139639 +{
139640 + struct qm_mc_command *mcc;
139641 + struct qm_mc_result *mcr;
139642 + struct qman_portal *p;
139643 + unsigned long irqflags __maybe_unused;
139644 + u8 res;
139645 +
139646 + p = get_affine_portal();
139647 + PORTAL_IRQ_LOCK(p, irqflags);
139648 +
139649 + mcc = qm_mc_start(&p->p);
139650 + mcc->ccgr_config = *opts;
139651 +
139652 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
139653 + while (!(mcr = qm_mc_result(&p->p)))
139654 + cpu_relax();
139655 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
139656 +
139657 + PORTAL_IRQ_UNLOCK(p, irqflags);
139658 + put_affine_portal();
139659 +
139660 + res = mcr->result;
139661 + if (res != QM_MCR_RESULT_OK) {
139662 + pr_err("CEETM: CONFIGURE CCGR failed\n");
139663 + return -EIO;
139664 + }
139665 + return 0;
139666 +}
139667 +
139668 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
139669 + struct qm_mcr_ceetm_ccgr_query *response)
139670 +{
139671 + struct qm_mc_command *mcc;
139672 + struct qm_mc_result *mcr;
139673 + struct qman_portal *p;
139674 + unsigned long irqflags __maybe_unused;
139675 + u8 res;
139676 +
139677 + p = get_affine_portal();
139678 + PORTAL_IRQ_LOCK(p, irqflags);
139679 +
139680 + mcc = qm_mc_start(&p->p);
139681 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
139682 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
139683 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
139684 +
139685 + while (!(mcr = qm_mc_result(&p->p)))
139686 + cpu_relax();
139687 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
139688 + res = mcr->result;
139689 + if (res == QM_MCR_RESULT_OK) {
139690 + *response = mcr->ccgr_query;
139691 + hw_ccgr_query_to_cpu(response);
139692 + }
139693 +
139694 + PORTAL_IRQ_UNLOCK(p, irqflags);
139695 + put_affine_portal();
139696 + if (res != QM_MCR_RESULT_OK) {
139697 + pr_err("CEETM: QUERY CCGR failed\n");
139698 + return -EIO;
139699 + }
139700 + return 0;
139701 +}
139702 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
139703 +
139704 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
139705 + u8 command_type, u16 xsfdr,
139706 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
139707 +{
139708 + struct qm_mc_command *mcc;
139709 + struct qm_mc_result *mcr;
139710 + struct qman_portal *p;
139711 + unsigned long irqflags __maybe_unused;
139712 + u8 res;
139713 +
139714 + p = get_affine_portal();
139715 + PORTAL_IRQ_LOCK(p, irqflags);
139716 +
139717 + mcc = qm_mc_start(&p->p);
139718 + switch (command_type) {
139719 + case 0:
139720 + case 1:
139721 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139722 + break;
139723 + case 2:
139724 + mcc->cq_ppxr.xsfdr = xsfdr;
139725 + break;
139726 + default:
139727 + break;
139728 + }
139729 + mcc->cq_ppxr.ct = command_type;
139730 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139731 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139732 + while (!(mcr = qm_mc_result(&p->p)))
139733 + cpu_relax();
139734 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139735 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139736 +
139737 + PORTAL_IRQ_UNLOCK(p, irqflags);
139738 + put_affine_portal();
139739 +
139740 + res = mcr->result;
139741 + if (res != QM_MCR_RESULT_OK) {
139742 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139743 + return -EIO;
139744 + }
139745 + *cq_ppxr = mcr->cq_ppxr;
139746 + return 0;
139747 +}
139748 +
139749 +static int qman_ceetm_query_statistics(u16 cid,
139750 + enum qm_dc_portal dcp_idx,
139751 + u16 command_type,
139752 + struct qm_mcr_ceetm_statistics_query *query_result)
139753 +{
139754 + struct qm_mc_command *mcc;
139755 + struct qm_mc_result *mcr;
139756 + struct qman_portal *p;
139757 + unsigned long irqflags __maybe_unused;
139758 + u8 res;
139759 +
139760 + p = get_affine_portal();
139761 + PORTAL_IRQ_LOCK(p, irqflags);
139762 +
139763 + mcc = qm_mc_start(&p->p);
139764 + mcc->stats_query_write.cid = cid;
139765 + mcc->stats_query_write.dcpid = dcp_idx;
139766 + mcc->stats_query_write.ct = command_type;
139767 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139768 +
139769 + while (!(mcr = qm_mc_result(&p->p)))
139770 + cpu_relax();
139771 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139772 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139773 +
139774 + PORTAL_IRQ_UNLOCK(p, irqflags);
139775 + put_affine_portal();
139776 +
139777 + res = mcr->result;
139778 + if (res != QM_MCR_RESULT_OK) {
139779 + pr_err("CEETM: STATISTICS QUERY failed\n");
139780 + return -EIO;
139781 + }
139782 + *query_result = mcr->stats_query;
139783 + return 0;
139784 +}
139785 +
139786 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139787 + u16 command_type, u64 frame_count,
139788 + u64 byte_count)
139789 +{
139790 + struct qm_mc_command *mcc;
139791 + struct qm_mc_result *mcr;
139792 + struct qman_portal *p;
139793 + unsigned long irqflags __maybe_unused;
139794 + u8 res;
139795 +
139796 + p = get_affine_portal();
139797 + PORTAL_IRQ_LOCK(p, irqflags);
139798 +
139799 + mcc = qm_mc_start(&p->p);
139800 + mcc->stats_query_write.cid = cid;
139801 + mcc->stats_query_write.dcpid = dcp_idx;
139802 + mcc->stats_query_write.ct = command_type;
139803 + mcc->stats_query_write.frm_cnt = frame_count;
139804 + mcc->stats_query_write.byte_cnt = byte_count;
139805 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139806 +
139807 + while (!(mcr = qm_mc_result(&p->p)))
139808 + cpu_relax();
139809 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139810 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139811 +
139812 + PORTAL_IRQ_UNLOCK(p, irqflags);
139813 + put_affine_portal();
139814 +
139815 + res = mcr->result;
139816 + if (res != QM_MCR_RESULT_OK) {
139817 + pr_err("CEETM: STATISTICS WRITE failed\n");
139818 + return -EIO;
139819 + }
139820 + return 0;
139821 +}
139822 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
139823 +
139824 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
139825 + int rounding)
139826 +{
139827 + u16 pres;
139828 + u64 temp;
139829 + u64 qman_freq;
139830 + int ret;
139831 +
139832 + /* Read PRES from CEET_CFG_PRES register */
139833 + ret = qman_ceetm_get_prescaler(&pres);
139834 + if (ret)
139835 + return -EINVAL;
139836 +
139837 + ret = qm_get_clock(&qman_freq);
139838 + if (ret)
139839 + return -EINVAL;
139840 +
139841 + /* token-rate = bytes-per-second * update-reference-period
139842 + *
139843 + * Where token-rate is N/8192 for a integer N, and
139844 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
139845 + * is the prescalar value and QHz is the QMan clock frequency.
139846 + * So:
139847 + *
139848 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
139849 + *
139850 + * Converting to bits-per-second gives;
139851 + *
139852 + * token-rate = (bps*2^19) / (PRES*QHZ)
139853 + * N = (bps*2^32) / (PRES*QHz)
139854 + *
139855 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
139856 + * (yet minimise rounding error if 'bps' is small), we reorganise
139857 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
139858 + * N = (((bps*2^16)/PRES)*2^16)/QHz
139859 + */
139860 + temp = ROUNDING((bps << 16), pres, rounding);
139861 + temp = ROUNDING((temp << 16), qman_freq, rounding);
139862 + token_rate->whole = temp >> 13;
139863 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
139864 + return 0;
139865 +}
139866 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
139867 +
139868 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
139869 + int rounding)
139870 +{
139871 + u16 pres;
139872 + u64 temp;
139873 + u64 qman_freq;
139874 + int ret;
139875 +
139876 + /* Read PRES from CEET_CFG_PRES register */
139877 + ret = qman_ceetm_get_prescaler(&pres);
139878 + if (ret)
139879 + return -EINVAL;
139880 +
139881 + ret = qm_get_clock(&qman_freq);
139882 + if (ret)
139883 + return -EINVAL;
139884 +
139885 + /* bytes-per-second = token-rate / update-reference-period
139886 + *
139887 + * where "token-rate" is N/8192 for an integer N, and
139888 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
139889 + * the prescalar value and QHz is the QMan clock frequency. So;
139890 + *
139891 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
139892 + * = N*PRES*QHz / (4194304*8192)
139893 + * = N*PRES*QHz / (2^35)
139894 + *
139895 + * Converting to bits-per-second gives;
139896 + *
139897 + * bps = N*PRES*QHZ / (2^32)
139898 + *
139899 + * Note, the numerator has a maximum width of 72 bits! So to
139900 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
139901 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
139902 + * multiplying by N (goes to maximum of 63 bits).
139903 + *
139904 + * temp = PRES*QHZ / (2^16)
139905 + * kbps = temp*N / (2^16)
139906 + */
139907 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
139908 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
139909 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
139910 + return 0;
139911 +}
139912 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
139913 +
139914 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
139915 + unsigned int sp_idx)
139916 +{
139917 + struct qm_ceetm_sp *p;
139918 +
139919 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
139920 + (dcp_idx == qm_dc_portal_fman1));
139921 +
139922 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
139923 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
139924 + qman_ceetms[dcp_idx].sp_range[1]))) {
139925 + pr_err("Sub-portal index doesn't exist\n");
139926 + return -EINVAL;
139927 + }
139928 +
139929 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
139930 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
139931 + p->is_claimed = 1;
139932 + *sp = p;
139933 + return 0;
139934 + }
139935 + }
139936 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
139937 + return -ENODEV;
139938 +}
139939 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
139940 +
139941 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
139942 +{
139943 + struct qm_ceetm_sp *p;
139944 +
139945 + if (sp->lni && sp->lni->is_claimed == 1) {
139946 + pr_err("The dependency of sub-portal has not been released!\n");
139947 + return -EBUSY;
139948 + }
139949 +
139950 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
139951 + if (p->idx == sp->idx) {
139952 + p->is_claimed = 0;
139953 + p->lni = NULL;
139954 + }
139955 + }
139956 + /* Disable CEETM mode of this sub-portal */
139957 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
139958 +
139959 + return 0;
139960 +}
139961 +EXPORT_SYMBOL(qman_ceetm_sp_release);
139962 +
139963 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
139964 + unsigned int lni_idx)
139965 +{
139966 + struct qm_ceetm_lni *p;
139967 +
139968 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
139969 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
139970 + qman_ceetms[dcp_idx].lni_range[1]))) {
139971 + pr_err("The lni index is out of range\n");
139972 + return -EINVAL;
139973 + }
139974 +
139975 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
139976 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
139977 + *lni = p;
139978 + p->is_claimed = 1;
139979 + return 0;
139980 + }
139981 + }
139982 +
139983 + pr_err("The LNI#%d is not available!\n", lni_idx);
139984 + return -EINVAL;
139985 +}
139986 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
139987 +
139988 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
139989 +{
139990 + struct qm_ceetm_lni *p;
139991 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139992 +
139993 + if (!list_empty(&lni->channels)) {
139994 + pr_err("The LNI dependencies are not released!\n");
139995 + return -EBUSY;
139996 + }
139997 +
139998 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
139999 + if (p->idx == lni->idx) {
140000 + p->shaper_enable = 0;
140001 + p->shaper_couple = 0;
140002 + p->cr_token_rate.whole = 0;
140003 + p->cr_token_rate.fraction = 0;
140004 + p->er_token_rate.whole = 0;
140005 + p->er_token_rate.fraction = 0;
140006 + p->cr_token_bucket_limit = 0;
140007 + p->er_token_bucket_limit = 0;
140008 + p->is_claimed = 0;
140009 + }
140010 + }
140011 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140012 + config_opts.dcpid = lni->dcp_idx;
140013 + memset(&config_opts.shaper_config, 0,
140014 + sizeof(config_opts.shaper_config));
140015 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140016 +}
140017 +EXPORT_SYMBOL(qman_ceetm_lni_release);
140018 +
140019 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
140020 +{
140021 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140022 +
140023 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
140024 + config_opts.dcpid = sp->dcp_idx;
140025 + config_opts.sp_mapping.map_lni_id = lni->idx;
140026 + sp->lni = lni;
140027 +
140028 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
140029 + return -EINVAL;
140030 +
140031 + /* Enable CEETM mode for this sub-portal */
140032 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
140033 +}
140034 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
140035 +
140036 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
140037 +{
140038 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140039 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140040 +
140041 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
140042 + query_opts.dcpid = sp->dcp_idx;
140043 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140044 + pr_err("Can't get SP <-> LNI mapping\n");
140045 + return -EINVAL;
140046 + }
140047 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
140048 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
140049 + return 0;
140050 +}
140051 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
140052 +
140053 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
140054 + int oal)
140055 +{
140056 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140057 +
140058 + if (lni->shaper_enable) {
140059 + pr_err("The shaper has already been enabled\n");
140060 + return -EINVAL;
140061 + }
140062 + lni->shaper_enable = 1;
140063 + lni->shaper_couple = coupled;
140064 + lni->oal = oal;
140065 +
140066 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140067 + config_opts.dcpid = lni->dcp_idx;
140068 + config_opts.shaper_config.cpl = coupled;
140069 + config_opts.shaper_config.oal = oal;
140070 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
140071 + << 13) | lni->cr_token_rate.fraction);
140072 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
140073 + << 13) | lni->er_token_rate.fraction);
140074 + config_opts.shaper_config.crtbl =
140075 + cpu_to_be16(lni->cr_token_bucket_limit);
140076 + config_opts.shaper_config.ertbl =
140077 + cpu_to_be16(lni->er_token_bucket_limit);
140078 + config_opts.shaper_config.mps = 60;
140079 +
140080 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140081 +}
140082 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
140083 +
140084 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
140085 +{
140086 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140087 +
140088 + if (!lni->shaper_enable) {
140089 + pr_err("The shaper has been disabled\n");
140090 + return -EINVAL;
140091 + }
140092 +
140093 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140094 + config_opts.dcpid = lni->dcp_idx;
140095 + config_opts.shaper_config.cpl = lni->shaper_couple;
140096 + config_opts.shaper_config.oal = lni->oal;
140097 + config_opts.shaper_config.crtbl =
140098 + cpu_to_be16(lni->cr_token_bucket_limit);
140099 + config_opts.shaper_config.ertbl =
140100 + cpu_to_be16(lni->er_token_bucket_limit);
140101 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
140102 + * disable the shaping.
140103 + */
140104 + config_opts.shaper_config.crtcr = 0xFFFFFF;
140105 + config_opts.shaper_config.ertcr = 0xFFFFFF;
140106 + config_opts.shaper_config.mps = 60;
140107 + lni->shaper_enable = 0;
140108 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140109 +}
140110 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
140111 +
140112 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
140113 +{
140114 + return lni->shaper_enable;
140115 +}
140116 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
140117 +
140118 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
140119 + const struct qm_ceetm_rate *token_rate,
140120 + u16 token_limit)
140121 +{
140122 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140123 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140124 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140125 + int ret;
140126 +
140127 + lni->cr_token_rate.whole = token_rate->whole;
140128 + lni->cr_token_rate.fraction = token_rate->fraction;
140129 + lni->cr_token_bucket_limit = token_limit;
140130 + if (!lni->shaper_enable)
140131 + return 0;
140132 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140133 + query_opts.dcpid = lni->dcp_idx;
140134 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
140135 + &query_result);
140136 + if (ret) {
140137 + pr_err("Fail to get current LNI shaper setting\n");
140138 + return -EINVAL;
140139 + }
140140 +
140141 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140142 + config_opts.dcpid = lni->dcp_idx;
140143 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
140144 + | (token_rate->fraction));
140145 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140146 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140147 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
140148 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140149 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140150 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
140151 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140152 +}
140153 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
140154 +
140155 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
140156 + u64 bps,
140157 + u16 token_limit)
140158 +{
140159 + struct qm_ceetm_rate token_rate;
140160 + int ret;
140161 +
140162 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140163 + if (ret) {
140164 + pr_err("Can not convert bps to token rate\n");
140165 + return -EINVAL;
140166 + }
140167 +
140168 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
140169 +}
140170 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
140171 +
140172 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
140173 + struct qm_ceetm_rate *token_rate,
140174 + u16 *token_limit)
140175 +{
140176 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140177 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140178 + int ret;
140179 +
140180 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140181 + query_opts.dcpid = lni->dcp_idx;
140182 +
140183 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140184 + if (ret) {
140185 + pr_err("The LNI CR rate or limit is not set\n");
140186 + return -EINVAL;
140187 + }
140188 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140189 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140190 + 0x1FFF;
140191 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140192 + return 0;
140193 +}
140194 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
140195 +
140196 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
140197 + u64 *bps, u16 *token_limit)
140198 +{
140199 + struct qm_ceetm_rate token_rate;
140200 + int ret;
140201 +
140202 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
140203 + if (ret) {
140204 + pr_err("The LNI CR rate or limit is not available\n");
140205 + return -EINVAL;
140206 + }
140207 +
140208 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140209 +}
140210 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
140211 +
140212 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
140213 + const struct qm_ceetm_rate *token_rate,
140214 + u16 token_limit)
140215 +{
140216 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140217 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140218 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140219 + int ret;
140220 +
140221 + lni->er_token_rate.whole = token_rate->whole;
140222 + lni->er_token_rate.fraction = token_rate->fraction;
140223 + lni->er_token_bucket_limit = token_limit;
140224 + if (!lni->shaper_enable)
140225 + return 0;
140226 +
140227 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140228 + query_opts.dcpid = lni->dcp_idx;
140229 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
140230 + &query_result);
140231 + if (ret) {
140232 + pr_err("Fail to get current LNI shaper setting\n");
140233 + return -EINVAL;
140234 + }
140235 +
140236 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140237 + config_opts.dcpid = lni->dcp_idx;
140238 + config_opts.shaper_config.ertcr = cpu_to_be24(
140239 + (token_rate->whole << 13) | (token_rate->fraction));
140240 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140241 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140242 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
140243 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140244 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140245 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
140246 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140247 +}
140248 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
140249 +
140250 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
140251 + u64 bps,
140252 + u16 token_limit)
140253 +{
140254 + struct qm_ceetm_rate token_rate;
140255 + int ret;
140256 +
140257 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140258 + if (ret) {
140259 + pr_err("Can not convert bps to token rate\n");
140260 + return -EINVAL;
140261 + }
140262 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
140263 +}
140264 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
140265 +
140266 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
140267 + struct qm_ceetm_rate *token_rate,
140268 + u16 *token_limit)
140269 +{
140270 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140271 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140272 + int ret;
140273 +
140274 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140275 + query_opts.dcpid = lni->dcp_idx;
140276 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140277 + if (ret) {
140278 + pr_err("The LNI ER rate or limit is not set\n");
140279 + return -EINVAL;
140280 + }
140281 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140282 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140283 + 0x1FFF;
140284 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140285 + return 0;
140286 +}
140287 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
140288 +
140289 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
140290 + u64 *bps, u16 *token_limit)
140291 +{
140292 + struct qm_ceetm_rate token_rate;
140293 + int ret;
140294 +
140295 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
140296 + if (ret) {
140297 + pr_err("The LNI ER rate or limit is not available\n");
140298 + return -EINVAL;
140299 + }
140300 +
140301 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140302 +}
140303 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
140304 +
140305 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
140306 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
140307 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
140308 + unsigned int cq_level,
140309 + int traffic_class)
140310 +{
140311 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140312 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140313 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140314 + u64 lnitcfcc;
140315 +
140316 + if ((cq_level > 15) | (traffic_class > 7)) {
140317 + pr_err("The CQ or traffic class id is out of range\n");
140318 + return -EINVAL;
140319 + }
140320 +
140321 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140322 + query_opts.dcpid = lni->dcp_idx;
140323 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140324 + pr_err("Fail to query tcfcc\n");
140325 + return -EINVAL;
140326 + }
140327 +
140328 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
140329 + if (traffic_class == -1) {
140330 + /* disable tcfc for this CQ */
140331 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
140332 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140333 + } else {
140334 + lnitcfcc &= ~((u64)0xF <<
140335 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140336 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
140337 + traffic_class)) <<
140338 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
140339 + }
140340 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
140341 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140342 + config_opts.dcpid = lni->dcp_idx;
140343 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140344 +}
140345 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
140346 +
140347 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
140348 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
140349 + int *traffic_class)
140350 +{
140351 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140352 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140353 + int ret;
140354 + u8 lnitcfcc;
140355 +
140356 + if (cq_level > 15) {
140357 + pr_err("the CQ level is out of range\n");
140358 + return -EINVAL;
140359 + }
140360 +
140361 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140362 + query_opts.dcpid = lni->dcp_idx;
140363 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140364 + if (ret)
140365 + return ret;
140366 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
140367 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140368 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
140369 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
140370 + else
140371 + *traffic_class = -1;
140372 + return 0;
140373 +}
140374 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
140375 +
140376 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
140377 + struct qm_ceetm_lni *lni)
140378 +{
140379 + struct qm_ceetm_channel *p;
140380 + u32 channel_idx;
140381 + int ret = 0;
140382 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140383 +
140384 + if (lni->dcp_idx == qm_dc_portal_fman0) {
140385 + ret = qman_alloc_ceetm0_channel(&channel_idx);
140386 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
140387 + ret = qman_alloc_ceetm1_channel(&channel_idx);
140388 + } else {
140389 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140390 + lni->dcp_idx);
140391 + return -EINVAL;
140392 + }
140393 +
140394 + if (ret) {
140395 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
140396 + return -ENODEV;
140397 + }
140398 +
140399 + p = kzalloc(sizeof(*p), GFP_KERNEL);
140400 + if (!p)
140401 + return -ENOMEM;
140402 + p->idx = channel_idx;
140403 + p->dcp_idx = lni->dcp_idx;
140404 + p->lni_idx = lni->idx;
140405 + list_add_tail(&p->node, &lni->channels);
140406 + INIT_LIST_HEAD(&p->class_queues);
140407 + INIT_LIST_HEAD(&p->ccgs);
140408 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140409 + channel_idx);
140410 + config_opts.dcpid = lni->dcp_idx;
140411 + config_opts.channel_mapping.map_lni_id = lni->idx;
140412 + config_opts.channel_mapping.map_shaped = 0;
140413 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140414 + pr_err("Can't map channel#%d for LNI#%d\n",
140415 + channel_idx, lni->idx);
140416 + return -EINVAL;
140417 + }
140418 + *channel = p;
140419 + return 0;
140420 +}
140421 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
140422 +
140423 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
140424 +{
140425 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140426 + if (!list_empty(&channel->class_queues)) {
140427 + pr_err("CEETM channel#%d has class queue unreleased!\n",
140428 + channel->idx);
140429 + return -EBUSY;
140430 + }
140431 + if (!list_empty(&channel->ccgs)) {
140432 + pr_err("CEETM channel#%d has ccg unreleased!\n",
140433 + channel->idx);
140434 + return -EBUSY;
140435 + }
140436 +
140437 + /* channel->dcp_idx corresponds to known fman validation */
140438 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
140439 + (channel->dcp_idx != qm_dc_portal_fman1)) {
140440 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140441 + channel->dcp_idx);
140442 + return -EINVAL;
140443 + }
140444 +
140445 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140446 + channel->idx);
140447 + config_opts.dcpid = channel->dcp_idx;
140448 + memset(&config_opts.shaper_config, 0,
140449 + sizeof(config_opts.shaper_config));
140450 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140451 + pr_err("Can't reset channel shapping parameters\n");
140452 + return -EINVAL;
140453 + }
140454 +
140455 + if (channel->dcp_idx == qm_dc_portal_fman0) {
140456 + qman_release_ceetm0_channelid(channel->idx);
140457 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
140458 + qman_release_ceetm1_channelid(channel->idx);
140459 + } else {
140460 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140461 + channel->dcp_idx);
140462 + return -EINVAL;
140463 + }
140464 + list_del(&channel->node);
140465 + kfree(channel);
140466 +
140467 + return 0;
140468 +}
140469 +EXPORT_SYMBOL(qman_ceetm_channel_release);
140470 +
140471 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
140472 + int coupled)
140473 +{
140474 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140475 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140476 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140477 +
140478 + if (channel->shaper_enable == 1) {
140479 + pr_err("This channel shaper has been enabled!\n");
140480 + return -EINVAL;
140481 + }
140482 +
140483 + channel->shaper_enable = 1;
140484 + channel->shaper_couple = coupled;
140485 +
140486 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140487 + channel->idx);
140488 + query_opts.dcpid = channel->dcp_idx;
140489 +
140490 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140491 + pr_err("Can't query channel mapping\n");
140492 + return -EINVAL;
140493 + }
140494 +
140495 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140496 + channel->idx);
140497 + config_opts.dcpid = channel->dcp_idx;
140498 + config_opts.channel_mapping.map_lni_id =
140499 + query_result.channel_mapping_query.map_lni_id;
140500 + config_opts.channel_mapping.map_shaped = 1;
140501 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140502 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
140503 + return -EINVAL;
140504 + }
140505 +
140506 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140507 + channel->idx);
140508 + config_opts.shaper_config.cpl = coupled;
140509 + config_opts.shaper_config.crtcr =
140510 + cpu_to_be24((channel->cr_token_rate.whole
140511 + << 13) |
140512 + channel->cr_token_rate.fraction);
140513 + config_opts.shaper_config.ertcr =
140514 + cpu_to_be24(channel->er_token_rate.whole
140515 + << 13 |
140516 + channel->er_token_rate.fraction);
140517 + config_opts.shaper_config.crtbl =
140518 + cpu_to_be16(channel->cr_token_bucket_limit);
140519 + config_opts.shaper_config.ertbl =
140520 + cpu_to_be16(channel->er_token_bucket_limit);
140521 +
140522 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140523 +}
140524 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
140525 +
140526 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
140527 +{
140528 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140529 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140530 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140531 +
140532 +
140533 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140534 + channel->idx);
140535 + query_opts.dcpid = channel->dcp_idx;
140536 +
140537 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140538 + pr_err("Can't query channel mapping\n");
140539 + return -EINVAL;
140540 + }
140541 +
140542 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140543 + channel->idx);
140544 + config_opts.dcpid = channel->dcp_idx;
140545 + config_opts.channel_mapping.map_shaped = 0;
140546 + config_opts.channel_mapping.map_lni_id =
140547 + query_result.channel_mapping_query.map_lni_id;
140548 +
140549 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140550 +}
140551 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
140552 +
140553 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
140554 +{
140555 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140556 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140557 +
140558 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140559 + channel->idx);
140560 + query_opts.dcpid = channel->dcp_idx;
140561 +
140562 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140563 + pr_err("Can't query channel mapping\n");
140564 + return -EINVAL;
140565 + }
140566 +
140567 + return query_result.channel_mapping_query.map_shaped;
140568 +}
140569 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
140570 +
140571 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
140572 + const struct qm_ceetm_rate *token_rate,
140573 + u16 token_limit)
140574 +{
140575 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140576 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140577 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140578 + int ret;
140579 +
140580 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140581 + channel->idx);
140582 + query_opts.dcpid = channel->dcp_idx;
140583 +
140584 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140585 + if (ret) {
140586 + pr_err("Fail to get the current channel shaper setting\n");
140587 + return -EINVAL;
140588 + }
140589 +
140590 + channel->cr_token_rate.whole = token_rate->whole;
140591 + channel->cr_token_rate.fraction = token_rate->fraction;
140592 + channel->cr_token_bucket_limit = token_limit;
140593 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140594 + channel->idx);
140595 + config_opts.dcpid = channel->dcp_idx;
140596 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
140597 + << 13) | (token_rate->fraction));
140598 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140599 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140600 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140601 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140602 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140603 +}
140604 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
140605 +
140606 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
140607 + u64 bps, u16 token_limit)
140608 +{
140609 + struct qm_ceetm_rate token_rate;
140610 + int ret;
140611 +
140612 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140613 + if (ret) {
140614 + pr_err("Can not convert bps to token rate\n");
140615 + return -EINVAL;
140616 + }
140617 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
140618 + token_limit);
140619 +}
140620 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
140621 +
140622 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
140623 + struct qm_ceetm_rate *token_rate,
140624 + u16 *token_limit)
140625 +{
140626 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140627 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140628 + int ret;
140629 +
140630 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140631 + channel->idx);
140632 + query_opts.dcpid = channel->dcp_idx;
140633 +
140634 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140635 + if (ret | !query_result.shaper_query.crtcr |
140636 + !query_result.shaper_query.crtbl) {
140637 + pr_err("The channel commit rate or limit is not set\n");
140638 + return -EINVAL;
140639 + }
140640 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140641 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140642 + 0x1FFF;
140643 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140644 + return 0;
140645 +}
140646 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
140647 +
140648 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
140649 + u64 *bps, u16 *token_limit)
140650 +{
140651 + struct qm_ceetm_rate token_rate;
140652 + int ret;
140653 +
140654 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
140655 + token_limit);
140656 + if (ret) {
140657 + pr_err("The channel CR rate or limit is not available\n");
140658 + return -EINVAL;
140659 + }
140660 +
140661 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140662 +}
140663 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
140664 +
140665 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
140666 + const struct qm_ceetm_rate *token_rate,
140667 + u16 token_limit)
140668 +{
140669 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140670 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140671 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140672 + int ret;
140673 +
140674 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140675 + channel->idx);
140676 + query_opts.dcpid = channel->dcp_idx;
140677 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140678 + if (ret) {
140679 + pr_err("Fail to get the current channel shaper setting\n");
140680 + return -EINVAL;
140681 + }
140682 +
140683 + channel->er_token_rate.whole = token_rate->whole;
140684 + channel->er_token_rate.fraction = token_rate->fraction;
140685 + channel->er_token_bucket_limit = token_limit;
140686 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140687 + channel->idx);
140688 + config_opts.dcpid = channel->dcp_idx;
140689 + config_opts.shaper_config.ertcr = cpu_to_be24(
140690 + (token_rate->whole << 13) | (token_rate->fraction));
140691 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140692 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140693 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140694 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140695 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140696 +}
140697 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
140698 +
140699 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
140700 + u64 bps, u16 token_limit)
140701 +{
140702 + struct qm_ceetm_rate token_rate;
140703 + int ret;
140704 +
140705 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140706 + if (ret) {
140707 + pr_err("Can not convert bps to token rate\n");
140708 + return -EINVAL;
140709 + }
140710 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140711 + token_limit);
140712 +}
140713 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140714 +
140715 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140716 + struct qm_ceetm_rate *token_rate,
140717 + u16 *token_limit)
140718 +{
140719 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140720 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140721 + int ret;
140722 +
140723 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140724 + channel->idx);
140725 + query_opts.dcpid = channel->dcp_idx;
140726 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140727 + if (ret | !query_result.shaper_query.ertcr |
140728 + !query_result.shaper_query.ertbl) {
140729 + pr_err("The channel excess rate or limit is not set\n");
140730 + return -EINVAL;
140731 + }
140732 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140733 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140734 + 0x1FFF;
140735 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140736 + return 0;
140737 +}
140738 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140739 +
140740 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140741 + u64 *bps, u16 *token_limit)
140742 +{
140743 + struct qm_ceetm_rate token_rate;
140744 + int ret;
140745 +
140746 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140747 + token_limit);
140748 + if (ret) {
140749 + pr_err("The channel ER rate or limit is not available\n");
140750 + return -EINVAL;
140751 + }
140752 +
140753 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140754 +}
140755 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140756 +
140757 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140758 + u16 token_limit)
140759 +{
140760 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140761 +
140762 + if (channel->shaper_enable) {
140763 + pr_err("This channel is a shaped one\n");
140764 + return -EINVAL;
140765 + }
140766 +
140767 + channel->cr_token_bucket_limit = token_limit;
140768 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140769 + channel->idx);
140770 + config_opts.dcpid = channel->dcp_idx;
140771 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140772 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140773 +}
140774 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140775 +
140776 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140777 + u16 *token_limit)
140778 +{
140779 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140780 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140781 + int ret;
140782 +
140783 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140784 + channel->idx);
140785 + query_opts.dcpid = channel->dcp_idx;
140786 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140787 + if (ret | !query_result.shaper_query.crtbl) {
140788 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140789 + return -EINVAL;
140790 + }
140791 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140792 + return 0;
140793 +}
140794 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140795 +
140796 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
140797 + unsigned int prio_a, unsigned int prio_b)
140798 +{
140799 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140800 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140801 + int i;
140802 +
140803 + if (prio_a > 7) {
140804 + pr_err("The priority of group A is out of range\n");
140805 + return -EINVAL;
140806 + }
140807 + if (group_b && (prio_b > 7)) {
140808 + pr_err("The priority of group B is out of range\n");
140809 + return -EINVAL;
140810 + }
140811 +
140812 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140813 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140814 + return -EINVAL;
140815 + }
140816 +
140817 + config_opts.cqcid = cpu_to_be16(channel->idx);
140818 + config_opts.dcpid = channel->dcp_idx;
140819 + config_opts.gpc_combine_flag = !group_b;
140820 + config_opts.gpc_prio_a = prio_a;
140821 + config_opts.gpc_prio_b = prio_b;
140822 +
140823 + for (i = 0; i < 8; i++)
140824 + config_opts.w[i] = query_result.w[i];
140825 + config_opts.crem = query_result.crem;
140826 + config_opts.erem = query_result.erem;
140827 +
140828 + return qman_ceetm_configure_class_scheduler(&config_opts);
140829 +}
140830 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
140831 +
140832 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
140833 + unsigned int *prio_a, unsigned int *prio_b)
140834 +{
140835 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140836 +
140837 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140838 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140839 + return -EINVAL;
140840 + }
140841 + *group_b = !query_result.gpc_combine_flag;
140842 + *prio_a = query_result.gpc_prio_a;
140843 + *prio_b = query_result.gpc_prio_b;
140844 +
140845 + return 0;
140846 +}
140847 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
140848 +
140849 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
140850 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
140851 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
140852 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
140853 + *channel, int group_b, int cre)
140854 +{
140855 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140856 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140857 + int i;
140858 +
140859 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140860 + pr_err("Cannot get the channel %d scheduler setting.\n",
140861 + channel->idx);
140862 + return -EINVAL;
140863 + }
140864 + csch_config.cqcid = cpu_to_be16(channel->idx);
140865 + csch_config.dcpid = channel->dcp_idx;
140866 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140867 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140868 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140869 +
140870 + for (i = 0; i < 8; i++)
140871 + csch_config.w[i] = csch_query.w[i];
140872 + csch_config.erem = csch_query.erem;
140873 + if (group_b)
140874 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140875 + & ~GROUP_B_ELIGIBILITY_SET)
140876 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
140877 + else
140878 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140879 + & ~GROUP_A_ELIGIBILITY_SET)
140880 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
140881 +
140882 + csch_config.crem = cpu_to_be16(csch_config.crem);
140883 +
140884 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140885 + pr_err("Cannot config channel %d's scheduler with "
140886 + "group_%c's cr eligibility\n", channel->idx,
140887 + group_b ? 'b' : 'a');
140888 + return -EINVAL;
140889 + }
140890 +
140891 + return 0;
140892 +}
140893 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
140894 +
140895 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
140896 + *channel, int group_b, int ere)
140897 +{
140898 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140899 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140900 + int i;
140901 +
140902 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140903 + pr_err("Cannot get the channel %d scheduler setting.\n",
140904 + channel->idx);
140905 + return -EINVAL;
140906 + }
140907 + csch_config.cqcid = cpu_to_be16(channel->idx);
140908 + csch_config.dcpid = channel->dcp_idx;
140909 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140910 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140911 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140912 +
140913 + for (i = 0; i < 8; i++)
140914 + csch_config.w[i] = csch_query.w[i];
140915 + csch_config.crem = csch_query.crem;
140916 + if (group_b)
140917 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140918 + & ~GROUP_B_ELIGIBILITY_SET)
140919 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
140920 + else
140921 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140922 + & ~GROUP_A_ELIGIBILITY_SET)
140923 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
140924 +
140925 + csch_config.erem = cpu_to_be16(csch_config.erem);
140926 +
140927 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140928 + pr_err("Cannot config channel %d's scheduler with "
140929 + "group_%c's er eligibility\n", channel->idx,
140930 + group_b ? 'b' : 'a');
140931 + return -EINVAL;
140932 + }
140933 +
140934 + return 0;
140935 +}
140936 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
140937 +
140938 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
140939 + unsigned int idx, int cre)
140940 +{
140941 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140942 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140943 + int i;
140944 +
140945 + if (idx > 7) {
140946 + pr_err("CQ index is out of range\n");
140947 + return -EINVAL;
140948 + }
140949 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140950 + pr_err("Cannot get the channel %d scheduler setting.\n",
140951 + channel->idx);
140952 + return -EINVAL;
140953 + }
140954 + csch_config.cqcid = cpu_to_be16(channel->idx);
140955 + csch_config.dcpid = channel->dcp_idx;
140956 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140957 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140958 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140959 + for (i = 0; i < 8; i++)
140960 + csch_config.w[i] = csch_query.w[i];
140961 + csch_config.erem = csch_query.erem;
140962 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140963 + & ~CQ_ELIGIBILITY_SET(idx)) |
140964 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
140965 + csch_config.crem = cpu_to_be16(csch_config.crem);
140966 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140967 + pr_err("Cannot config channel scheduler to set "
140968 + "cr eligibility mask for CQ#%d\n", idx);
140969 + return -EINVAL;
140970 + }
140971 +
140972 + return 0;
140973 +}
140974 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
140975 +
140976 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
140977 + unsigned int idx, int ere)
140978 +{
140979 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140980 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140981 + int i;
140982 +
140983 + if (idx > 7) {
140984 + pr_err("CQ index is out of range\n");
140985 + return -EINVAL;
140986 + }
140987 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140988 + pr_err("Cannot get the channel %d scheduler setting.\n",
140989 + channel->idx);
140990 + return -EINVAL;
140991 + }
140992 + csch_config.cqcid = cpu_to_be16(channel->idx);
140993 + csch_config.dcpid = channel->dcp_idx;
140994 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140995 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140996 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140997 + for (i = 0; i < 8; i++)
140998 + csch_config.w[i] = csch_query.w[i];
140999 + csch_config.crem = csch_query.crem;
141000 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141001 + & ~CQ_ELIGIBILITY_SET(idx)) |
141002 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
141003 + csch_config.erem = cpu_to_be16(csch_config.erem);
141004 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141005 + pr_err("Cannot config channel scheduler to set "
141006 + "er eligibility mask for CQ#%d\n", idx);
141007 + return -EINVAL;
141008 + }
141009 + return 0;
141010 +}
141011 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
141012 +
141013 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
141014 + struct qm_ceetm_channel *channel, unsigned int idx,
141015 + struct qm_ceetm_ccg *ccg)
141016 +{
141017 + struct qm_ceetm_cq *p;
141018 + struct qm_mcc_ceetm_cq_config cq_config;
141019 +
141020 + if (idx > 7) {
141021 + pr_err("The independent class queue id is out of range\n");
141022 + return -EINVAL;
141023 + }
141024 +
141025 + list_for_each_entry(p, &channel->class_queues, node) {
141026 + if (p->idx == idx) {
141027 + pr_err("The CQ#%d has been claimed!\n", idx);
141028 + return -EINVAL;
141029 + }
141030 + }
141031 +
141032 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141033 + if (!p) {
141034 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141035 + return -ENOMEM;
141036 + }
141037 +
141038 + list_add_tail(&p->node, &channel->class_queues);
141039 + p->idx = idx;
141040 + p->is_claimed = 1;
141041 + p->parent = channel;
141042 + INIT_LIST_HEAD(&p->bound_lfqids);
141043 +
141044 + if (ccg) {
141045 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141046 + cq_config.dcpid = channel->dcp_idx;
141047 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141048 + if (qman_ceetm_configure_cq(&cq_config)) {
141049 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141050 + idx, ccg->idx);
141051 + list_del(&p->node);
141052 + kfree(p);
141053 + return -EINVAL;
141054 + }
141055 + }
141056 +
141057 + *cq = p;
141058 + return 0;
141059 +}
141060 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
141061 +
141062 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
141063 + struct qm_ceetm_channel *channel, unsigned int idx,
141064 + struct qm_ceetm_ccg *ccg)
141065 +{
141066 + struct qm_ceetm_cq *p;
141067 + struct qm_mcc_ceetm_cq_config cq_config;
141068 +
141069 + if ((idx < 8) || (idx > 15)) {
141070 + pr_err("This grouped class queue id is out of range\n");
141071 + return -EINVAL;
141072 + }
141073 +
141074 + list_for_each_entry(p, &channel->class_queues, node) {
141075 + if (p->idx == idx) {
141076 + pr_err("The CQ#%d has been claimed!\n", idx);
141077 + return -EINVAL;
141078 + }
141079 + }
141080 +
141081 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141082 + if (!p) {
141083 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141084 + return -ENOMEM;
141085 + }
141086 +
141087 + list_add_tail(&p->node, &channel->class_queues);
141088 + p->idx = idx;
141089 + p->is_claimed = 1;
141090 + p->parent = channel;
141091 + INIT_LIST_HEAD(&p->bound_lfqids);
141092 +
141093 + if (ccg) {
141094 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141095 + cq_config.dcpid = channel->dcp_idx;
141096 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141097 + if (qman_ceetm_configure_cq(&cq_config)) {
141098 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141099 + idx, ccg->idx);
141100 + list_del(&p->node);
141101 + kfree(p);
141102 + return -EINVAL;
141103 + }
141104 + }
141105 + *cq = p;
141106 + return 0;
141107 +}
141108 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
141109 +
141110 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
141111 + struct qm_ceetm_channel *channel, unsigned int idx,
141112 + struct qm_ceetm_ccg *ccg)
141113 +{
141114 + struct qm_ceetm_cq *p;
141115 + struct qm_mcc_ceetm_cq_config cq_config;
141116 +
141117 + if ((idx < 12) || (idx > 15)) {
141118 + pr_err("This grouped class queue id is out of range\n");
141119 + return -EINVAL;
141120 + }
141121 +
141122 + list_for_each_entry(p, &channel->class_queues, node) {
141123 + if (p->idx == idx) {
141124 + pr_err("The CQ#%d has been claimed!\n", idx);
141125 + return -EINVAL;
141126 + }
141127 + }
141128 +
141129 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141130 + if (!p) {
141131 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141132 + return -ENOMEM;
141133 + }
141134 +
141135 + list_add_tail(&p->node, &channel->class_queues);
141136 + p->idx = idx;
141137 + p->is_claimed = 1;
141138 + p->parent = channel;
141139 + INIT_LIST_HEAD(&p->bound_lfqids);
141140 +
141141 + if (ccg) {
141142 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141143 + cq_config.dcpid = channel->dcp_idx;
141144 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141145 + if (qman_ceetm_configure_cq(&cq_config)) {
141146 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141147 + idx, ccg->idx);
141148 + list_del(&p->node);
141149 + kfree(p);
141150 + return -EINVAL;
141151 + }
141152 + }
141153 + *cq = p;
141154 + return 0;
141155 +}
141156 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
141157 +
141158 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
141159 +{
141160 + if (!list_empty(&cq->bound_lfqids)) {
141161 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
141162 + return -EBUSY;
141163 + }
141164 + list_del(&cq->node);
141165 + qman_ceetm_drain_cq(cq);
141166 + kfree(cq);
141167 + return 0;
141168 +}
141169 +EXPORT_SYMBOL(qman_ceetm_cq_release);
141170 +
141171 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
141172 + struct qm_ceetm_weight_code *weight_code)
141173 +{
141174 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
141175 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141176 + int i;
141177 +
141178 + if (cq->idx < 8) {
141179 + pr_err("Can not set weight for ungrouped class queue\n");
141180 + return -EINVAL;
141181 + }
141182 +
141183 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
141184 + pr_err("Can't query channel#%d's scheduler!\n",
141185 + cq->parent->idx);
141186 + return -EINVAL;
141187 + }
141188 +
141189 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
141190 + config_opts.dcpid = cq->parent->dcp_idx;
141191 + config_opts.crem = query_result.crem;
141192 + config_opts.erem = query_result.erem;
141193 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
141194 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
141195 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
141196 +
141197 + for (i = 0; i < 8; i++)
141198 + config_opts.w[i] = query_result.w[i];
141199 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
141200 + (weight_code->x & 0x7));
141201 + return qman_ceetm_configure_class_scheduler(&config_opts);
141202 +}
141203 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
141204 +
141205 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
141206 + struct qm_ceetm_weight_code *weight_code)
141207 +{
141208 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141209 +
141210 + if (cq->idx < 8) {
141211 + pr_err("Can not get weight for ungrouped class queue\n");
141212 + return -EINVAL;
141213 + }
141214 +
141215 + if (qman_ceetm_query_class_scheduler(cq->parent,
141216 + &query_result)) {
141217 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
141218 + return -EINVAL;
141219 + }
141220 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
141221 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
141222 +
141223 + return 0;
141224 +}
141225 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
141226 +
141227 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
141228 + * effective weight = 2^x / (1 - (y/64))
141229 + * = 2^(x+6) / (64 - y)
141230 + */
141231 +static void reduce_fraction(u32 *n, u32 *d)
141232 +{
141233 + u32 factor = 2;
141234 + u32 lesser = (*n < *d) ? *n : *d;
141235 + /* If factor exceeds the square-root of the lesser of *n and *d,
141236 + * then there's no point continuing. Proof: if there was a factor
141237 + * bigger than the square root, that would imply there exists
141238 + * another factor smaller than the square-root with which it
141239 + * multiplies to give 'lesser' - but that's a contradiction
141240 + * because the other factor would have already been found and
141241 + * divided out.
141242 + */
141243 + while ((factor * factor) <= lesser) {
141244 + /* If 'factor' is a factor of *n and *d, divide them both
141245 + * by 'factor' as many times as possible.
141246 + */
141247 + while (!(*n % factor) && !(*d % factor)) {
141248 + *n /= factor;
141249 + *d /= factor;
141250 + lesser /= factor;
141251 + }
141252 + if (factor == 2)
141253 + factor = 3;
141254 + else
141255 + factor += 2;
141256 + }
141257 +}
141258 +
141259 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
141260 + u32 *numerator,
141261 + u32 *denominator)
141262 +{
141263 + *numerator = (u32) 1 << (weight_code->x + 6);
141264 + *denominator = 64 - weight_code->y;
141265 + reduce_fraction(numerator, denominator);
141266 + return 0;
141267 +}
141268 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
141269 +
141270 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
141271 + * So find 'x' by range, and then estimate 'y' using:
141272 + * 64 - y = 2^(x + 6) / weight
141273 + * = 2^(x + 6) / (n/d)
141274 + * = d * 2^(x+6) / n
141275 + * y = 64 - (d * 2^(x+6) / n)
141276 + */
141277 +int qman_ceetm_ratio2wbfs(u32 numerator,
141278 + u32 denominator,
141279 + struct qm_ceetm_weight_code *weight_code,
141280 + int rounding)
141281 +{
141282 + unsigned int y, x = 0;
141283 + /* search incrementing 'x' until:
141284 + * weight < 2^(x+1)
141285 + * n/d < 2^(x+1)
141286 + * n < d * 2^(x+1)
141287 + */
141288 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
141289 + x++;
141290 + if (x >= 8)
141291 + return -ERANGE;
141292 + /* because of the subtraction, use '-rounding' */
141293 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
141294 + if (y >= 32)
141295 + return -ERANGE;
141296 + weight_code->x = x;
141297 + weight_code->y = y;
141298 + return 0;
141299 +}
141300 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
141301 +
141302 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
141303 +{
141304 + struct qm_ceetm_weight_code weight_code;
141305 +
141306 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
141307 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
141308 + return -EINVAL;
141309 + }
141310 + return qman_ceetm_set_queue_weight(cq, &weight_code);
141311 +}
141312 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
141313 +
141314 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
141315 +{
141316 + struct qm_ceetm_weight_code weight_code;
141317 + u32 n, d;
141318 +
141319 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
141320 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
141321 + return -EINVAL;
141322 + }
141323 +
141324 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
141325 + pr_err("Cannot get the ratio with wbfs code\n");
141326 + return -EINVAL;
141327 + }
141328 +
141329 + *ratio = (n * 100) / d;
141330 + return 0;
141331 +}
141332 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
141333 +
141334 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
141335 + u64 *frame_count, u64 *byte_count)
141336 +{
141337 + struct qm_mcr_ceetm_statistics_query result;
141338 + u16 cid, command_type;
141339 + enum qm_dc_portal dcp_idx;
141340 + int ret;
141341 +
141342 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
141343 + dcp_idx = cq->parent->dcp_idx;
141344 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141345 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
141346 + else
141347 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
141348 +
141349 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141350 + if (ret) {
141351 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
141352 + return -EINVAL;
141353 + }
141354 +
141355 + *frame_count = be40_to_cpu(result.frm_cnt);
141356 + *byte_count = be48_to_cpu(result.byte_cnt);
141357 + return 0;
141358 +}
141359 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
141360 +
141361 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
141362 +{
141363 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
141364 + int ret;
141365 +
141366 + do {
141367 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
141368 + if (ret) {
141369 + pr_err("Failed to pop frame from CQ\n");
141370 + return -EINVAL;
141371 + }
141372 + } while (!(ppxr.stat & 0x2));
141373 +
141374 + return 0;
141375 +}
141376 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
141377 +
141378 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
141379 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
141380 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
141381 + struct qm_ceetm_cq *cq)
141382 +{
141383 + struct qm_ceetm_lfq *p;
141384 + u32 lfqid;
141385 + int ret = 0;
141386 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
141387 +
141388 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
141389 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
141390 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
141391 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
141392 + } else {
141393 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141394 + cq->parent->dcp_idx);
141395 + return -EINVAL;
141396 + }
141397 +
141398 + if (ret) {
141399 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
141400 + return -ENODEV;
141401 + }
141402 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141403 + if (!p)
141404 + return -ENOMEM;
141405 + p->idx = lfqid;
141406 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
141407 + p->parent = cq->parent;
141408 + list_add_tail(&p->node, &cq->bound_lfqids);
141409 +
141410 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
141411 + (cq->parent->dcp_idx << 16) |
141412 + (lfqid & CEETM_LFQMT_LFQID_LSB));
141413 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
141414 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
141415 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
141416 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
141417 + lfqid, cq->idx);
141418 + list_del(&p->node);
141419 + kfree(p);
141420 + return -EINVAL;
141421 + }
141422 + *lfq = p;
141423 + return 0;
141424 +}
141425 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
141426 +
141427 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
141428 +{
141429 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
141430 + qman_release_ceetm0_lfqid(lfq->idx);
141431 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
141432 + qman_release_ceetm1_lfqid(lfq->idx);
141433 + } else {
141434 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141435 + lfq->parent->dcp_idx);
141436 + return -EINVAL;
141437 + }
141438 + list_del(&lfq->node);
141439 + kfree(lfq);
141440 + return 0;
141441 +}
141442 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
141443 +
141444 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
141445 + u32 context_b)
141446 +{
141447 + struct qm_mcc_ceetm_dct_config dct_config;
141448 + lfq->context_a = context_a;
141449 + lfq->context_b = context_b;
141450 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
141451 + dct_config.dcpid = lfq->parent->dcp_idx;
141452 + dct_config.context_b = cpu_to_be32(context_b);
141453 + dct_config.context_a = cpu_to_be64(context_a);
141454 +
141455 + return qman_ceetm_configure_dct(&dct_config);
141456 +}
141457 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
141458 +
141459 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
141460 + u32 *context_b)
141461 +{
141462 + struct qm_mcc_ceetm_dct_query dct_query;
141463 + struct qm_mcr_ceetm_dct_query query_result;
141464 +
141465 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
141466 + dct_query.dcpid = lfq->parent->dcp_idx;
141467 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
141468 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
141469 + return -EINVAL;
141470 + }
141471 + *context_a = be64_to_cpu(query_result.context_a);
141472 + *context_b = be32_to_cpu(query_result.context_b);
141473 + return 0;
141474 +}
141475 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
141476 +
141477 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
141478 +{
141479 + spin_lock_init(&fq->fqlock);
141480 + fq->fqid = lfq->idx;
141481 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
141482 + if (lfq->ern)
141483 + fq->cb.ern = lfq->ern;
141484 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
141485 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
141486 + return -ENOMEM;
141487 +#endif
141488 + return 0;
141489 +}
141490 +EXPORT_SYMBOL(qman_ceetm_create_fq);
141491 +
141492 +#define MAX_CCG_IDX 0x000F
141493 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
141494 + struct qm_ceetm_channel *channel,
141495 + unsigned int idx,
141496 + void (*cscn)(struct qm_ceetm_ccg *,
141497 + void *cb_ctx,
141498 + int congested),
141499 + void *cb_ctx)
141500 +{
141501 + struct qm_ceetm_ccg *p;
141502 +
141503 + if (idx > MAX_CCG_IDX) {
141504 + pr_err("The given ccg index is out of range\n");
141505 + return -EINVAL;
141506 + }
141507 +
141508 + list_for_each_entry(p, &channel->ccgs, node) {
141509 + if (p->idx == idx) {
141510 + pr_err("The CCG#%d has been claimed\n", idx);
141511 + return -EINVAL;
141512 + }
141513 + }
141514 +
141515 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141516 + if (!p) {
141517 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
141518 + return -ENOMEM;
141519 + }
141520 +
141521 + list_add_tail(&p->node, &channel->ccgs);
141522 +
141523 + p->idx = idx;
141524 + p->parent = channel;
141525 + p->cb = cscn;
141526 + p->cb_ctx = cb_ctx;
141527 + INIT_LIST_HEAD(&p->cb_node);
141528 +
141529 + *ccg = p;
141530 + return 0;
141531 +}
141532 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
141533 +
141534 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
141535 +{
141536 + unsigned long irqflags __maybe_unused;
141537 + struct qm_mcc_ceetm_ccgr_config config_opts;
141538 + int ret = 0;
141539 + struct qman_portal *p = get_affine_portal();
141540 +
141541 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141542 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141543 + if (!list_empty(&ccg->cb_node))
141544 + list_del(&ccg->cb_node);
141545 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141546 + (ccg->parent->idx << 4) | ccg->idx);
141547 + config_opts.dcpid = ccg->parent->dcp_idx;
141548 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
141549 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
141550 + ret = qman_ceetm_configure_ccgr(&config_opts);
141551 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141552 + put_affine_portal();
141553 +
141554 + list_del(&ccg->node);
141555 + kfree(ccg);
141556 + return ret;
141557 +}
141558 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
141559 +
141560 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
141561 + const struct qm_ceetm_ccg_params *params)
141562 +{
141563 + struct qm_mcc_ceetm_ccgr_config config_opts;
141564 + unsigned long irqflags __maybe_unused;
141565 + int ret;
141566 + struct qman_portal *p;
141567 +
141568 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
141569 + return -EINVAL;
141570 +
141571 + p = get_affine_portal();
141572 +
141573 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141574 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141575 +
141576 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141577 + (ccg->parent->idx << 4) | ccg->idx);
141578 + config_opts.dcpid = ccg->parent->dcp_idx;
141579 + config_opts.we_mask = we_mask;
141580 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
141581 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
141582 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
141583 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
141584 + }
141585 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
141586 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141587 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141588 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141589 + config_opts.cm_config.ctl_td_en = params->td_en;
141590 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141591 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141592 + config_opts.cm_config.ctl_mode = params->mode;
141593 + config_opts.cm_config.oal = params->oal;
141594 + config_opts.cm_config.cs_thres.hword =
141595 + cpu_to_be16(params->cs_thres_in.hword);
141596 + config_opts.cm_config.cs_thres_x.hword =
141597 + cpu_to_be16(params->cs_thres_out.hword);
141598 + config_opts.cm_config.td_thres.hword =
141599 + cpu_to_be16(params->td_thres.hword);
141600 + config_opts.cm_config.wr_parm_g.word =
141601 + cpu_to_be32(params->wr_parm_g.word);
141602 + config_opts.cm_config.wr_parm_y.word =
141603 + cpu_to_be32(params->wr_parm_y.word);
141604 + config_opts.cm_config.wr_parm_r.word =
141605 + cpu_to_be32(params->wr_parm_r.word);
141606 + ret = qman_ceetm_configure_ccgr(&config_opts);
141607 + if (ret) {
141608 + pr_err("Configure CCGR CM failed!\n");
141609 + goto release_lock;
141610 + }
141611 +
141612 + if (we_mask & QM_CCGR_WE_CSCN_EN)
141613 + if (list_empty(&ccg->cb_node))
141614 + list_add(&ccg->cb_node,
141615 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
141616 +release_lock:
141617 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141618 + put_affine_portal();
141619 + return ret;
141620 +}
141621 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
141622 +
141623 +#define CEETM_CCGR_CTL_MASK 0x01
141624 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
141625 + struct qm_ceetm_ccg_params *params)
141626 +{
141627 + struct qm_mcc_ceetm_ccgr_query query_opts;
141628 + struct qm_mcr_ceetm_ccgr_query query_result;
141629 +
141630 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141631 + (ccg->parent->idx << 4) | ccg->idx);
141632 + query_opts.dcpid = ccg->parent->dcp_idx;
141633 +
141634 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141635 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141636 + return -EINVAL;
141637 + }
141638 +
141639 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
141640 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
141641 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
141642 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
141643 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
141644 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
141645 + params->oal = query_result.cm_query.oal;
141646 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
141647 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
141648 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
141649 + params->td_en = query_result.cm_query.ctl_td_en;
141650 + params->td_mode = query_result.cm_query.ctl_td_mode;
141651 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
141652 + params->mode = query_result.cm_query.ctl_mode;
141653 +
141654 + return 0;
141655 +}
141656 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
141657 +
141658 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
141659 + u64 *frame_count, u64 *byte_count)
141660 +{
141661 + struct qm_mcr_ceetm_statistics_query result;
141662 + u16 cid, command_type;
141663 + enum qm_dc_portal dcp_idx;
141664 + int ret;
141665 +
141666 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
141667 + dcp_idx = ccg->parent->dcp_idx;
141668 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141669 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
141670 + else
141671 + command_type = CEETM_QUERY_REJECT_STATISTICS;
141672 +
141673 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141674 + if (ret) {
141675 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
141676 + return -EINVAL;
141677 + }
141678 +
141679 + *frame_count = be40_to_cpu(result.frm_cnt);
141680 + *byte_count = be48_to_cpu(result.byte_cnt);
141681 + return 0;
141682 +}
141683 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
141684 +
141685 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
141686 + u16 swp_idx,
141687 + unsigned int *cscn_enabled)
141688 +{
141689 + struct qm_mcc_ceetm_ccgr_query query_opts;
141690 + struct qm_mcr_ceetm_ccgr_query query_result;
141691 + int i;
141692 +
141693 + DPA_ASSERT(swp_idx < 127);
141694 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141695 + (ccg->parent->idx << 4) | ccg->idx);
141696 + query_opts.dcpid = ccg->parent->dcp_idx;
141697 +
141698 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141699 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141700 + return -EINVAL;
141701 + }
141702 +
141703 + i = swp_idx / 32;
141704 + i = 3 - i;
141705 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
141706 + (31 - swp_idx % 32);
141707 +
141708 + return 0;
141709 +}
141710 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141711 +
141712 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141713 + u16 dcp_idx,
141714 + u8 vcgid,
141715 + unsigned int cscn_enabled,
141716 + u16 we_mask,
141717 + const struct qm_ceetm_ccg_params *params)
141718 +{
141719 + struct qm_mcc_ceetm_ccgr_config config_opts;
141720 + int ret;
141721 +
141722 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141723 + (ccg->parent->idx << 4) | ccg->idx);
141724 + config_opts.dcpid = ccg->parent->dcp_idx;
141725 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141726 + QM_CCGR_WE_CDV);
141727 + config_opts.cm_config.cdv = vcgid;
141728 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141729 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141730 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141731 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141732 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141733 + config_opts.cm_config.ctl_td_en = params->td_en;
141734 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141735 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141736 + config_opts.cm_config.ctl_mode = params->mode;
141737 + config_opts.cm_config.cs_thres.hword =
141738 + cpu_to_be16(params->cs_thres_in.hword);
141739 + config_opts.cm_config.cs_thres_x.hword =
141740 + cpu_to_be16(params->cs_thres_out.hword);
141741 + config_opts.cm_config.td_thres.hword =
141742 + cpu_to_be16(params->td_thres.hword);
141743 + config_opts.cm_config.wr_parm_g.word =
141744 + cpu_to_be32(params->wr_parm_g.word);
141745 + config_opts.cm_config.wr_parm_y.word =
141746 + cpu_to_be32(params->wr_parm_y.word);
141747 + config_opts.cm_config.wr_parm_r.word =
141748 + cpu_to_be32(params->wr_parm_r.word);
141749 +
141750 + ret = qman_ceetm_configure_ccgr(&config_opts);
141751 + if (ret) {
141752 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141753 + return -EINVAL;
141754 + }
141755 + return 0;
141756 +}
141757 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141758 +
141759 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141760 + u16 dcp_idx,
141761 + u8 *vcgid,
141762 + unsigned int *cscn_enabled)
141763 +{
141764 + struct qm_mcc_ceetm_ccgr_query query_opts;
141765 + struct qm_mcr_ceetm_ccgr_query query_result;
141766 +
141767 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141768 + (ccg->parent->idx << 4) | ccg->idx);
141769 + query_opts.dcpid = ccg->parent->dcp_idx;
141770 +
141771 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141772 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141773 + return -EINVAL;
141774 + }
141775 +
141776 + *vcgid = query_result.cm_query.cdv;
141777 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141778 + return 0;
141779 +}
141780 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141781 +
141782 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141783 + unsigned int dcp_idx)
141784 +{
141785 + struct qm_mc_command *mcc;
141786 + struct qm_mc_result *mcr;
141787 + struct qman_portal *p;
141788 + unsigned long irqflags __maybe_unused;
141789 + u8 res;
141790 + int i, j;
141791 +
141792 + p = get_affine_portal();
141793 + PORTAL_IRQ_LOCK(p, irqflags);
141794 +
141795 + mcc = qm_mc_start(&p->p);
141796 + for (i = 0; i < 2; i++) {
141797 + mcc->ccgr_query.ccgrid =
141798 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
141799 + mcc->ccgr_query.dcpid = dcp_idx;
141800 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141801 +
141802 + while (!(mcr = qm_mc_result(&p->p)))
141803 + cpu_relax();
141804 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141805 + QM_CEETM_VERB_CCGR_QUERY);
141806 + res = mcr->result;
141807 + if (res == QM_MCR_RESULT_OK) {
141808 + for (j = 0; j < 8; j++)
141809 + mcr->ccgr_query.congestion_state.state.
141810 + __state[j] = be32_to_cpu(mcr->ccgr_query.
141811 + congestion_state.state.__state[j]);
141812 + *(ccg_state + i) =
141813 + mcr->ccgr_query.congestion_state.state;
141814 + } else {
141815 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
141816 + PORTAL_IRQ_UNLOCK(p, irqflags);
141817 + return -EIO;
141818 + }
141819 + }
141820 + PORTAL_IRQ_UNLOCK(p, irqflags);
141821 + put_affine_portal();
141822 + return 0;
141823 +}
141824 +
141825 +int qman_set_wpm(int wpm_enable)
141826 +{
141827 + return qm_set_wpm(wpm_enable);
141828 +}
141829 +EXPORT_SYMBOL(qman_set_wpm);
141830 +
141831 +int qman_get_wpm(int *wpm_enable)
141832 +{
141833 + return qm_get_wpm(wpm_enable);
141834 +}
141835 +EXPORT_SYMBOL(qman_get_wpm);
141836 +
141837 +int qman_shutdown_fq(u32 fqid)
141838 +{
141839 + struct qman_portal *p;
141840 + unsigned long irqflags __maybe_unused;
141841 + int ret;
141842 + struct qm_portal *low_p;
141843 + p = get_affine_portal();
141844 + PORTAL_IRQ_LOCK(p, irqflags);
141845 + low_p = &p->p;
141846 + ret = qm_shutdown_fq(&low_p, 1, fqid);
141847 + PORTAL_IRQ_UNLOCK(p, irqflags);
141848 + put_affine_portal();
141849 + return ret;
141850 +}
141851 +
141852 +const struct qm_portal_config *qman_get_qm_portal_config(
141853 + struct qman_portal *portal)
141854 +{
141855 + return portal->sharing_redirect ? NULL : portal->config;
141856 +}
141857 diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h
141858 new file mode 100644
141859 index 00000000..547b5fa2
141860 --- /dev/null
141861 +++ b/drivers/staging/fsl_qbman/qman_low.h
141862 @@ -0,0 +1,1427 @@
141863 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
141864 + *
141865 + * Redistribution and use in source and binary forms, with or without
141866 + * modification, are permitted provided that the following conditions are met:
141867 + * * Redistributions of source code must retain the above copyright
141868 + * notice, this list of conditions and the following disclaimer.
141869 + * * Redistributions in binary form must reproduce the above copyright
141870 + * notice, this list of conditions and the following disclaimer in the
141871 + * documentation and/or other materials provided with the distribution.
141872 + * * Neither the name of Freescale Semiconductor nor the
141873 + * names of its contributors may be used to endorse or promote products
141874 + * derived from this software without specific prior written permission.
141875 + *
141876 + *
141877 + * ALTERNATIVELY, this software may be distributed under the terms of the
141878 + * GNU General Public License ("GPL") as published by the Free Software
141879 + * Foundation, either version 2 of that License or (at your option) any
141880 + * later version.
141881 + *
141882 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
141883 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
141884 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
141885 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
141886 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
141887 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141888 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
141889 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
141890 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141891 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141892 + */
141893 +
141894 +#include "qman_private.h"
141895 +
141896 +/***************************/
141897 +/* Portal register assists */
141898 +/***************************/
141899 +
141900 +/* Cache-inhibited register offsets */
141901 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141902 +
141903 +#define QM_REG_EQCR_PI_CINH 0x0000
141904 +#define QM_REG_EQCR_CI_CINH 0x0004
141905 +#define QM_REG_EQCR_ITR 0x0008
141906 +#define QM_REG_DQRR_PI_CINH 0x0040
141907 +#define QM_REG_DQRR_CI_CINH 0x0044
141908 +#define QM_REG_DQRR_ITR 0x0048
141909 +#define QM_REG_DQRR_DCAP 0x0050
141910 +#define QM_REG_DQRR_SDQCR 0x0054
141911 +#define QM_REG_DQRR_VDQCR 0x0058
141912 +#define QM_REG_DQRR_PDQCR 0x005c
141913 +#define QM_REG_MR_PI_CINH 0x0080
141914 +#define QM_REG_MR_CI_CINH 0x0084
141915 +#define QM_REG_MR_ITR 0x0088
141916 +#define QM_REG_CFG 0x0100
141917 +#define QM_REG_ISR 0x0e00
141918 +#define QM_REG_IIR 0x0e0c
141919 +#define QM_REG_ITPR 0x0e14
141920 +
141921 +/* Cache-enabled register offsets */
141922 +#define QM_CL_EQCR 0x0000
141923 +#define QM_CL_DQRR 0x1000
141924 +#define QM_CL_MR 0x2000
141925 +#define QM_CL_EQCR_PI_CENA 0x3000
141926 +#define QM_CL_EQCR_CI_CENA 0x3100
141927 +#define QM_CL_DQRR_PI_CENA 0x3200
141928 +#define QM_CL_DQRR_CI_CENA 0x3300
141929 +#define QM_CL_MR_PI_CENA 0x3400
141930 +#define QM_CL_MR_CI_CENA 0x3500
141931 +#define QM_CL_CR 0x3800
141932 +#define QM_CL_RR0 0x3900
141933 +#define QM_CL_RR1 0x3940
141934 +
141935 +#endif
141936 +
141937 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
141938 +
141939 +#define QM_REG_EQCR_PI_CINH 0x3000
141940 +#define QM_REG_EQCR_CI_CINH 0x3040
141941 +#define QM_REG_EQCR_ITR 0x3080
141942 +#define QM_REG_DQRR_PI_CINH 0x3100
141943 +#define QM_REG_DQRR_CI_CINH 0x3140
141944 +#define QM_REG_DQRR_ITR 0x3180
141945 +#define QM_REG_DQRR_DCAP 0x31C0
141946 +#define QM_REG_DQRR_SDQCR 0x3200
141947 +#define QM_REG_DQRR_VDQCR 0x3240
141948 +#define QM_REG_DQRR_PDQCR 0x3280
141949 +#define QM_REG_MR_PI_CINH 0x3300
141950 +#define QM_REG_MR_CI_CINH 0x3340
141951 +#define QM_REG_MR_ITR 0x3380
141952 +#define QM_REG_CFG 0x3500
141953 +#define QM_REG_ISR 0x3600
141954 +#define QM_REG_IIR 0x36C0
141955 +#define QM_REG_ITPR 0x3740
141956 +
141957 +/* Cache-enabled register offsets */
141958 +#define QM_CL_EQCR 0x0000
141959 +#define QM_CL_DQRR 0x1000
141960 +#define QM_CL_MR 0x2000
141961 +#define QM_CL_EQCR_PI_CENA 0x3000
141962 +#define QM_CL_EQCR_CI_CENA 0x3040
141963 +#define QM_CL_DQRR_PI_CENA 0x3100
141964 +#define QM_CL_DQRR_CI_CENA 0x3140
141965 +#define QM_CL_MR_PI_CENA 0x3300
141966 +#define QM_CL_MR_CI_CENA 0x3340
141967 +#define QM_CL_CR 0x3800
141968 +#define QM_CL_RR0 0x3900
141969 +#define QM_CL_RR1 0x3940
141970 +
141971 +#endif
141972 +
141973 +
141974 +/* BTW, the drivers (and h/w programming model) already obtain the required
141975 + * synchronisation for portal accesses via lwsync(), hwsync(), and
141976 + * data-dependencies. Use of barrier()s or other order-preserving primitives
141977 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
141978 + * simply ensure that the compiler treats the portal registers as volatile (ie.
141979 + * non-coherent). */
141980 +
141981 +/* Cache-inhibited register access. */
141982 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
141983 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
141984 + (qm)->addr_ci + (o));
141985 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
141986 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
141987 +
141988 +/* Cache-enabled (index) register access */
141989 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
141990 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
141991 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
141992 +#define __qm_cl_out(qm, o, val) \
141993 + do { \
141994 + u32 *__tmpclout = (qm)->addr_ce + (o); \
141995 + __raw_writel(cpu_to_be32(val), __tmpclout); \
141996 + dcbf(__tmpclout); \
141997 + } while (0)
141998 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
141999 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
142000 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
142001 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
142002 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
142003 +#define qm_cl_invalidate(reg)\
142004 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
142005 +
142006 +/* Cache-enabled ring access */
142007 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
142008 +
142009 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
142010 + * analysis, look at using the "extra" bit in the ring index registers to avoid
142011 + * cyclic issues. */
142012 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
142013 +{
142014 + /* 'first' is included, 'last' is excluded */
142015 + if (first <= last)
142016 + return last - first;
142017 + return ringsize + last - first;
142018 +}
142019 +
142020 +/* Portal modes.
142021 + * Enum types;
142022 + * pmode == production mode
142023 + * cmode == consumption mode,
142024 + * dmode == h/w dequeue mode.
142025 + * Enum values use 3 letter codes. First letter matches the portal mode,
142026 + * remaining two letters indicate;
142027 + * ci == cache-inhibited portal register
142028 + * ce == cache-enabled portal register
142029 + * vb == in-band valid-bit (cache-enabled)
142030 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
142031 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
142032 + */
142033 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
142034 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
142035 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
142036 + qm_eqcr_pvb = 2 /* valid-bit */
142037 +};
142038 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
142039 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
142040 + qm_dqrr_dpull = 1 /* PDQCR */
142041 +};
142042 +enum qm_dqrr_pmode { /* s/w-only */
142043 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
142044 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
142045 + qm_dqrr_pvb /* reads valid-bit */
142046 +};
142047 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
142048 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
142049 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
142050 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
142051 +};
142052 +enum qm_mr_pmode { /* s/w-only */
142053 + qm_mr_pci, /* reads MR_PI_CINH */
142054 + qm_mr_pce, /* reads MR_PI_CENA */
142055 + qm_mr_pvb /* reads valid-bit */
142056 +};
142057 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
142058 + qm_mr_cci = 0, /* CI index, cache-inhibited */
142059 + qm_mr_cce = 1 /* CI index, cache-enabled */
142060 +};
142061 +
142062 +
142063 +/* ------------------------- */
142064 +/* --- Portal structures --- */
142065 +
142066 +#define QM_EQCR_SIZE 8
142067 +#define QM_DQRR_SIZE 16
142068 +#define QM_MR_SIZE 8
142069 +
142070 +struct qm_eqcr {
142071 + struct qm_eqcr_entry *ring, *cursor;
142072 + u8 ci, available, ithresh, vbit;
142073 +#ifdef CONFIG_FSL_DPA_CHECKING
142074 + u32 busy;
142075 + enum qm_eqcr_pmode pmode;
142076 +#endif
142077 +};
142078 +
142079 +struct qm_dqrr {
142080 + const struct qm_dqrr_entry *ring, *cursor;
142081 + u8 pi, ci, fill, ithresh, vbit;
142082 +#ifdef CONFIG_FSL_DPA_CHECKING
142083 + enum qm_dqrr_dmode dmode;
142084 + enum qm_dqrr_pmode pmode;
142085 + enum qm_dqrr_cmode cmode;
142086 +#endif
142087 +};
142088 +
142089 +struct qm_mr {
142090 + const struct qm_mr_entry *ring, *cursor;
142091 + u8 pi, ci, fill, ithresh, vbit;
142092 +#ifdef CONFIG_FSL_DPA_CHECKING
142093 + enum qm_mr_pmode pmode;
142094 + enum qm_mr_cmode cmode;
142095 +#endif
142096 +};
142097 +
142098 +struct qm_mc {
142099 + struct qm_mc_command *cr;
142100 + struct qm_mc_result *rr;
142101 + u8 rridx, vbit;
142102 +#ifdef CONFIG_FSL_DPA_CHECKING
142103 + enum {
142104 + /* Can be _mc_start()ed */
142105 + qman_mc_idle,
142106 + /* Can be _mc_commit()ed or _mc_abort()ed */
142107 + qman_mc_user,
142108 + /* Can only be _mc_retry()ed */
142109 + qman_mc_hw
142110 + } state;
142111 +#endif
142112 +};
142113 +
142114 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
142115 +
142116 +struct qm_addr {
142117 + void __iomem *addr_ce; /* cache-enabled */
142118 + void __iomem *addr_ci; /* cache-inhibited */
142119 +};
142120 +
142121 +struct qm_portal {
142122 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
142123 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
142124 + * is setup-only, so isn't a cause for a concern. In other words, don't
142125 + * rearrange this structure on a whim, there be dragons ... */
142126 + struct qm_addr addr;
142127 + struct qm_eqcr eqcr;
142128 + struct qm_dqrr dqrr;
142129 + struct qm_mr mr;
142130 + struct qm_mc mc;
142131 +} QM_PORTAL_ALIGNMENT;
142132 +
142133 +
142134 +/* ---------------- */
142135 +/* --- EQCR API --- */
142136 +
142137 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
142138 +#define EQCR_CARRYCLEAR(p) \
142139 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
142140 +
142141 +/* Bit-wise logic to convert a ring pointer to a ring index */
142142 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
142143 +{
142144 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
142145 +}
142146 +
142147 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
142148 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
142149 +{
142150 + /* NB: this is odd-looking, but experiments show that it generates fast
142151 + * code with essentially no branching overheads. We increment to the
142152 + * next EQCR pointer and handle overflow and 'vbit'. */
142153 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
142154 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
142155 + if (partial != eqcr->cursor)
142156 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
142157 +}
142158 +
142159 +static inline int qm_eqcr_init(struct qm_portal *portal,
142160 + enum qm_eqcr_pmode pmode,
142161 + unsigned int eq_stash_thresh,
142162 + int eq_stash_prio)
142163 +{
142164 + /* This use of 'register', as well as all other occurrences, is because
142165 + * it has been observed to generate much faster code with gcc than is
142166 + * otherwise the case. */
142167 + register struct qm_eqcr *eqcr = &portal->eqcr;
142168 + u32 cfg;
142169 + u8 pi;
142170 +
142171 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
142172 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142173 + qm_cl_invalidate(EQCR_CI);
142174 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
142175 + eqcr->cursor = eqcr->ring + pi;
142176 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
142177 + QM_EQCR_VERB_VBIT : 0;
142178 + eqcr->available = QM_EQCR_SIZE - 1 -
142179 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
142180 + eqcr->ithresh = qm_in(EQCR_ITR);
142181 +#ifdef CONFIG_FSL_DPA_CHECKING
142182 + eqcr->busy = 0;
142183 + eqcr->pmode = pmode;
142184 +#endif
142185 + cfg = (qm_in(CFG) & 0x00ffffff) |
142186 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
142187 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
142188 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
142189 + qm_out(CFG, cfg);
142190 + return 0;
142191 +}
142192 +
142193 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
142194 +{
142195 + return (qm_in(CFG) >> 28) & 0x7;
142196 +}
142197 +
142198 +static inline void qm_eqcr_finish(struct qm_portal *portal)
142199 +{
142200 + register struct qm_eqcr *eqcr = &portal->eqcr;
142201 + u8 pi, ci;
142202 + u32 cfg;
142203 +
142204 + /*
142205 + * Disable EQCI stashing because the QMan only
142206 + * presents the value it previously stashed to
142207 + * maintain coherency. Setting the stash threshold
142208 + * to 1 then 0 ensures that QMan has resyncronized
142209 + * its internal copy so that the portal is clean
142210 + * when it is reinitialized in the future
142211 + */
142212 + cfg = (qm_in(CFG) & 0x0fffffff) |
142213 + (1 << 28); /* QCSP_CFG: EST */
142214 + qm_out(CFG, cfg);
142215 + cfg &= 0x0fffffff; /* stash threshold = 0 */
142216 + qm_out(CFG, cfg);
142217 +
142218 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
142219 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142220 +
142221 + /* Refresh EQCR CI cache value */
142222 + qm_cl_invalidate(EQCR_CI);
142223 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142224 +
142225 + DPA_ASSERT(!eqcr->busy);
142226 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
142227 + pr_crit("losing uncommited EQCR entries\n");
142228 + if (ci != eqcr->ci)
142229 + pr_crit("missing existing EQCR completions\n");
142230 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
142231 + pr_crit("EQCR destroyed unquiesced\n");
142232 +}
142233 +
142234 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
142235 + *portal)
142236 +{
142237 + register struct qm_eqcr *eqcr = &portal->eqcr;
142238 + DPA_ASSERT(!eqcr->busy);
142239 + if (!eqcr->available)
142240 + return NULL;
142241 +
142242 +
142243 +#ifdef CONFIG_FSL_DPA_CHECKING
142244 + eqcr->busy = 1;
142245 +#endif
142246 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142247 + dcbz_64(eqcr->cursor);
142248 +#endif
142249 + return eqcr->cursor;
142250 +}
142251 +
142252 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
142253 + *portal)
142254 +{
142255 + register struct qm_eqcr *eqcr = &portal->eqcr;
142256 + u8 diff, old_ci;
142257 +
142258 + DPA_ASSERT(!eqcr->busy);
142259 + if (!eqcr->available) {
142260 + old_ci = eqcr->ci;
142261 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142262 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142263 + eqcr->available += diff;
142264 + if (!diff)
142265 + return NULL;
142266 + }
142267 +#ifdef CONFIG_FSL_DPA_CHECKING
142268 + eqcr->busy = 1;
142269 +#endif
142270 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142271 + dcbz_64(eqcr->cursor);
142272 +#endif
142273 + return eqcr->cursor;
142274 +}
142275 +
142276 +static inline void qm_eqcr_abort(struct qm_portal *portal)
142277 +{
142278 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142279 + DPA_ASSERT(eqcr->busy);
142280 +#ifdef CONFIG_FSL_DPA_CHECKING
142281 + eqcr->busy = 0;
142282 +#endif
142283 +}
142284 +
142285 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
142286 + struct qm_portal *portal, u8 myverb)
142287 +{
142288 + register struct qm_eqcr *eqcr = &portal->eqcr;
142289 + DPA_ASSERT(eqcr->busy);
142290 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
142291 + if (eqcr->available == 1)
142292 + return NULL;
142293 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142294 + dcbf(eqcr->cursor);
142295 + EQCR_INC(eqcr);
142296 + eqcr->available--;
142297 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142298 + dcbz_64(eqcr->cursor);
142299 +#endif
142300 + return eqcr->cursor;
142301 +}
142302 +
142303 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
142304 +#define EQCR_COMMIT_CHECKS(eqcr) \
142305 +do { \
142306 + DPA_ASSERT(eqcr->busy); \
142307 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
142308 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
142309 +} while (0)
142310 +#else
142311 +#define EQCR_COMMIT_CHECKS(eqcr) \
142312 +do { \
142313 + DPA_ASSERT(eqcr->busy); \
142314 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
142315 + cpu_to_be32(0x00ffffff))); \
142316 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
142317 + cpu_to_be32(0x00ffffff))); \
142318 +} while (0)
142319 +#endif
142320 +
142321 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
142322 +{
142323 + register struct qm_eqcr *eqcr = &portal->eqcr;
142324 + EQCR_COMMIT_CHECKS(eqcr);
142325 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
142326 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142327 + EQCR_INC(eqcr);
142328 + eqcr->available--;
142329 + dcbf(eqcr->cursor);
142330 + hwsync();
142331 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
142332 +#ifdef CONFIG_FSL_DPA_CHECKING
142333 + eqcr->busy = 0;
142334 +#endif
142335 +}
142336 +
142337 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
142338 +{
142339 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142340 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142341 + qm_cl_invalidate(EQCR_PI);
142342 + qm_cl_touch_rw(EQCR_PI);
142343 +}
142344 +
142345 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
142346 +{
142347 + register struct qm_eqcr *eqcr = &portal->eqcr;
142348 + EQCR_COMMIT_CHECKS(eqcr);
142349 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142350 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142351 + EQCR_INC(eqcr);
142352 + eqcr->available--;
142353 + dcbf(eqcr->cursor);
142354 + lwsync();
142355 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
142356 +#ifdef CONFIG_FSL_DPA_CHECKING
142357 + eqcr->busy = 0;
142358 +#endif
142359 +}
142360 +
142361 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
142362 +{
142363 + register struct qm_eqcr *eqcr = &portal->eqcr;
142364 + struct qm_eqcr_entry *eqcursor;
142365 + EQCR_COMMIT_CHECKS(eqcr);
142366 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
142367 + lwsync();
142368 + eqcursor = eqcr->cursor;
142369 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142370 + dcbf(eqcursor);
142371 + EQCR_INC(eqcr);
142372 + eqcr->available--;
142373 +#ifdef CONFIG_FSL_DPA_CHECKING
142374 + eqcr->busy = 0;
142375 +#endif
142376 +}
142377 +
142378 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
142379 +{
142380 + register struct qm_eqcr *eqcr = &portal->eqcr;
142381 + u8 diff, old_ci = eqcr->ci;
142382 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142383 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142384 + eqcr->available += diff;
142385 + return diff;
142386 +}
142387 +
142388 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
142389 +{
142390 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142391 + qm_cl_touch_ro(EQCR_CI);
142392 +}
142393 +
142394 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
142395 +{
142396 + register struct qm_eqcr *eqcr = &portal->eqcr;
142397 + u8 diff, old_ci = eqcr->ci;
142398 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142399 + qm_cl_invalidate(EQCR_CI);
142400 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142401 + eqcr->available += diff;
142402 + return diff;
142403 +}
142404 +
142405 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
142406 +{
142407 + register struct qm_eqcr *eqcr = &portal->eqcr;
142408 + return eqcr->ithresh;
142409 +}
142410 +
142411 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142412 +{
142413 + register struct qm_eqcr *eqcr = &portal->eqcr;
142414 + eqcr->ithresh = ithresh;
142415 + qm_out(EQCR_ITR, ithresh);
142416 +}
142417 +
142418 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
142419 +{
142420 + register struct qm_eqcr *eqcr = &portal->eqcr;
142421 + return eqcr->available;
142422 +}
142423 +
142424 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
142425 +{
142426 + register struct qm_eqcr *eqcr = &portal->eqcr;
142427 + return QM_EQCR_SIZE - 1 - eqcr->available;
142428 +}
142429 +
142430 +
142431 +/* ---------------- */
142432 +/* --- DQRR API --- */
142433 +
142434 +/* FIXME: many possible improvements;
142435 + * - look at changing the API to use pointer rather than index parameters now
142436 + * that 'cursor' is a pointer,
142437 + * - consider moving other parameters to pointer if it could help (ci)
142438 + */
142439 +
142440 +#define DQRR_CARRYCLEAR(p) \
142441 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
142442 +
142443 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
142444 +{
142445 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
142446 +}
142447 +
142448 +static inline const struct qm_dqrr_entry *DQRR_INC(
142449 + const struct qm_dqrr_entry *e)
142450 +{
142451 + return DQRR_CARRYCLEAR(e + 1);
142452 +}
142453 +
142454 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
142455 +{
142456 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
142457 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
142458 +}
142459 +
142460 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
142461 +{
142462 + register struct qm_dqrr *dqrr = &portal->dqrr;
142463 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142464 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142465 + qm_out(DQRR_CI_CINH, dqrr->ci);
142466 +}
142467 +
142468 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
142469 +{
142470 + register struct qm_dqrr *dqrr = &portal->dqrr;
142471 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142472 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142473 + qm_cl_out(DQRR_CI, dqrr->ci);
142474 +}
142475 +
142476 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
142477 +{
142478 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142479 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142480 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
142481 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
142482 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142483 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142484 +}
142485 +
142486 +static inline int qm_dqrr_init(struct qm_portal *portal,
142487 + const struct qm_portal_config *config,
142488 + enum qm_dqrr_dmode dmode,
142489 + __maybe_unused enum qm_dqrr_pmode pmode,
142490 + enum qm_dqrr_cmode cmode, u8 max_fill)
142491 +{
142492 + register struct qm_dqrr *dqrr = &portal->dqrr;
142493 + u32 cfg;
142494 +
142495 + /* Make sure the DQRR will be idle when we enable */
142496 + qm_out(DQRR_SDQCR, 0);
142497 + qm_out(DQRR_VDQCR, 0);
142498 + qm_out(DQRR_PDQCR, 0);
142499 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
142500 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142501 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142502 + dqrr->cursor = dqrr->ring + dqrr->ci;
142503 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142504 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
142505 + QM_DQRR_VERB_VBIT : 0;
142506 + dqrr->ithresh = qm_in(DQRR_ITR);
142507 +
142508 + /* Free up pending DQRR entries if any as per current DCM */
142509 + if (dqrr->fill) {
142510 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
142511 +
142512 +#ifdef CONFIG_FSL_DPA_CHECKING
142513 + dqrr->cmode = dcm;
142514 +#endif
142515 + switch (dcm) {
142516 + case qm_dqrr_cci:
142517 + qm_dqrr_cci_consume(portal, dqrr->fill);
142518 + break;
142519 + case qm_dqrr_cce:
142520 + qm_dqrr_cce_consume(portal, dqrr->fill);
142521 + break;
142522 + case qm_dqrr_cdc:
142523 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
142524 + break;
142525 + default:
142526 + DPA_ASSERT(0);
142527 + }
142528 + }
142529 +
142530 +#ifdef CONFIG_FSL_DPA_CHECKING
142531 + dqrr->dmode = dmode;
142532 + dqrr->pmode = pmode;
142533 + dqrr->cmode = cmode;
142534 +#endif
142535 + /* Invalidate every ring entry before beginning */
142536 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
142537 + dcbi(qm_cl(dqrr->ring, cfg));
142538 + cfg = (qm_in(CFG) & 0xff000f00) |
142539 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
142540 + ((dmode & 1) << 18) | /* DP */
142541 + ((cmode & 3) << 16) | /* DCM */
142542 + 0xa0 | /* RE+SE */
142543 + (0 ? 0x40 : 0) | /* Ignore RP */
142544 + (0 ? 0x10 : 0); /* Ignore SP */
142545 + qm_out(CFG, cfg);
142546 + qm_dqrr_set_maxfill(portal, max_fill);
142547 + return 0;
142548 +}
142549 +
142550 +static inline void qm_dqrr_finish(struct qm_portal *portal)
142551 +{
142552 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142553 +#ifdef CONFIG_FSL_DPA_CHECKING
142554 + if ((dqrr->cmode != qm_dqrr_cdc) &&
142555 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
142556 + pr_crit("Ignoring completed DQRR entries\n");
142557 +#endif
142558 +}
142559 +
142560 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
142561 + struct qm_portal *portal)
142562 +{
142563 + register struct qm_dqrr *dqrr = &portal->dqrr;
142564 + if (!dqrr->fill)
142565 + return NULL;
142566 + return dqrr->cursor;
142567 +}
142568 +
142569 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
142570 +{
142571 + register struct qm_dqrr *dqrr = &portal->dqrr;
142572 + return DQRR_PTR2IDX(dqrr->cursor);
142573 +}
142574 +
142575 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
142576 +{
142577 + register struct qm_dqrr *dqrr = &portal->dqrr;
142578 + DPA_ASSERT(dqrr->fill);
142579 + dqrr->cursor = DQRR_INC(dqrr->cursor);
142580 + return --dqrr->fill;
142581 +}
142582 +
142583 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
142584 +{
142585 + register struct qm_dqrr *dqrr = &portal->dqrr;
142586 + u8 diff, old_pi = dqrr->pi;
142587 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
142588 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142589 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142590 + dqrr->fill += diff;
142591 + return diff;
142592 +}
142593 +
142594 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
142595 +{
142596 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142597 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142598 + qm_cl_invalidate(DQRR_PI);
142599 + qm_cl_touch_ro(DQRR_PI);
142600 +}
142601 +
142602 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
142603 +{
142604 + register struct qm_dqrr *dqrr = &portal->dqrr;
142605 + u8 diff, old_pi = dqrr->pi;
142606 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142607 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
142608 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142609 + dqrr->fill += diff;
142610 + return diff;
142611 +}
142612 +
142613 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
142614 +{
142615 + register struct qm_dqrr *dqrr = &portal->dqrr;
142616 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
142617 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
142618 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
142619 + /*
142620 + * On PowerPC platforms if PAMU is not available we need to
142621 + * manually invalidate the cache. When PAMU is available the
142622 + * cache is updated by stashing operations generated by QMan
142623 + */
142624 + dcbi(res);
142625 + dcbt_ro(res);
142626 +#endif
142627 +
142628 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142629 + * inlining doesn't try to optimise out "excess reads". */
142630 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
142631 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
142632 + if (!dqrr->pi)
142633 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
142634 + dqrr->fill++;
142635 + }
142636 +}
142637 +
142638 +
142639 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
142640 +{
142641 + register struct qm_dqrr *dqrr = &portal->dqrr;
142642 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142643 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142644 + qm_out(DQRR_CI_CINH, dqrr->ci);
142645 +}
142646 +
142647 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
142648 +{
142649 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142650 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142651 + qm_cl_invalidate(DQRR_CI);
142652 + qm_cl_touch_rw(DQRR_CI);
142653 +}
142654 +
142655 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
142656 +{
142657 + register struct qm_dqrr *dqrr = &portal->dqrr;
142658 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142659 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142660 + qm_cl_out(DQRR_CI, dqrr->ci);
142661 +}
142662 +
142663 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
142664 + int park)
142665 +{
142666 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142667 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142668 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142669 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142670 + ((park ? 1 : 0) << 6) | /* PK */
142671 + idx); /* DCAP_CI */
142672 +}
142673 +
142674 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
142675 + const struct qm_dqrr_entry *dq,
142676 + int park)
142677 +{
142678 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142679 + u8 idx = DQRR_PTR2IDX(dq);
142680 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142681 + DPA_ASSERT((dqrr->ring + idx) == dq);
142682 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142683 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
142684 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
142685 + idx); /* DQRR_DCAP::DCAP_CI */
142686 +}
142687 +
142688 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
142689 +{
142690 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142691 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142692 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142693 +}
142694 +
142695 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
142696 +{
142697 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142698 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142699 + qm_cl_invalidate(DQRR_CI);
142700 + qm_cl_touch_ro(DQRR_CI);
142701 +}
142702 +
142703 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
142704 +{
142705 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142706 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142707 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
142708 +}
142709 +
142710 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
142711 +{
142712 + register struct qm_dqrr *dqrr = &portal->dqrr;
142713 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142714 + return dqrr->ci;
142715 +}
142716 +
142717 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142718 +{
142719 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142720 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142721 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142722 + (1 << 6) | /* PK */
142723 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142724 +}
142725 +
142726 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142727 +{
142728 + register struct qm_dqrr *dqrr = &portal->dqrr;
142729 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142730 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142731 + (1 << 6) | /* PK */
142732 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142733 +}
142734 +
142735 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142736 +{
142737 + qm_out(DQRR_SDQCR, sdqcr);
142738 +}
142739 +
142740 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142741 +{
142742 + return qm_in(DQRR_SDQCR);
142743 +}
142744 +
142745 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142746 +{
142747 + qm_out(DQRR_VDQCR, vdqcr);
142748 +}
142749 +
142750 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142751 +{
142752 + return qm_in(DQRR_VDQCR);
142753 +}
142754 +
142755 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142756 +{
142757 + qm_out(DQRR_PDQCR, pdqcr);
142758 +}
142759 +
142760 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142761 +{
142762 + return qm_in(DQRR_PDQCR);
142763 +}
142764 +
142765 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142766 +{
142767 + register struct qm_dqrr *dqrr = &portal->dqrr;
142768 + return dqrr->ithresh;
142769 +}
142770 +
142771 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142772 +{
142773 + qm_out(DQRR_ITR, ithresh);
142774 +}
142775 +
142776 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142777 +{
142778 + return (qm_in(CFG) & 0x00f00000) >> 20;
142779 +}
142780 +
142781 +
142782 +/* -------------- */
142783 +/* --- MR API --- */
142784 +
142785 +#define MR_CARRYCLEAR(p) \
142786 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142787 +
142788 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142789 +{
142790 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142791 +}
142792 +
142793 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142794 +{
142795 + return MR_CARRYCLEAR(e + 1);
142796 +}
142797 +
142798 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
142799 + enum qm_mr_cmode cmode)
142800 +{
142801 + register struct qm_mr *mr = &portal->mr;
142802 + u32 cfg;
142803 +
142804 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
142805 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
142806 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
142807 + mr->cursor = mr->ring + mr->ci;
142808 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
142809 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
142810 + mr->ithresh = qm_in(MR_ITR);
142811 +#ifdef CONFIG_FSL_DPA_CHECKING
142812 + mr->pmode = pmode;
142813 + mr->cmode = cmode;
142814 +#endif
142815 + cfg = (qm_in(CFG) & 0xfffff0ff) |
142816 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
142817 + qm_out(CFG, cfg);
142818 + return 0;
142819 +}
142820 +
142821 +static inline void qm_mr_finish(struct qm_portal *portal)
142822 +{
142823 + register struct qm_mr *mr = &portal->mr;
142824 + if (mr->ci != MR_PTR2IDX(mr->cursor))
142825 + pr_crit("Ignoring completed MR entries\n");
142826 +}
142827 +
142828 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
142829 +{
142830 + register struct qm_mr *mr = &portal->mr;
142831 + if (!mr->fill)
142832 + return NULL;
142833 + return mr->cursor;
142834 +}
142835 +
142836 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
142837 +{
142838 + register struct qm_mr *mr = &portal->mr;
142839 + return MR_PTR2IDX(mr->cursor);
142840 +}
142841 +
142842 +static inline u8 qm_mr_next(struct qm_portal *portal)
142843 +{
142844 + register struct qm_mr *mr = &portal->mr;
142845 + DPA_ASSERT(mr->fill);
142846 + mr->cursor = MR_INC(mr->cursor);
142847 + return --mr->fill;
142848 +}
142849 +
142850 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
142851 +{
142852 + register struct qm_mr *mr = &portal->mr;
142853 + u8 diff, old_pi = mr->pi;
142854 + DPA_ASSERT(mr->pmode == qm_mr_pci);
142855 + mr->pi = qm_in(MR_PI_CINH);
142856 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142857 + mr->fill += diff;
142858 + return diff;
142859 +}
142860 +
142861 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
142862 +{
142863 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142864 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142865 + qm_cl_invalidate(MR_PI);
142866 + qm_cl_touch_ro(MR_PI);
142867 +}
142868 +
142869 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
142870 +{
142871 + register struct qm_mr *mr = &portal->mr;
142872 + u8 diff, old_pi = mr->pi;
142873 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142874 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
142875 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142876 + mr->fill += diff;
142877 + return diff;
142878 +}
142879 +
142880 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
142881 +{
142882 + register struct qm_mr *mr = &portal->mr;
142883 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
142884 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
142885 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142886 + * inlining doesn't try to optimise out "excess reads". */
142887 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
142888 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
142889 + if (!mr->pi)
142890 + mr->vbit ^= QM_MR_VERB_VBIT;
142891 + mr->fill++;
142892 + res = MR_INC(res);
142893 + }
142894 + dcbit_ro(res);
142895 +}
142896 +
142897 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
142898 +{
142899 + register struct qm_mr *mr = &portal->mr;
142900 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142901 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142902 + qm_out(MR_CI_CINH, mr->ci);
142903 +}
142904 +
142905 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
142906 +{
142907 + register struct qm_mr *mr = &portal->mr;
142908 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142909 + mr->ci = MR_PTR2IDX(mr->cursor);
142910 + qm_out(MR_CI_CINH, mr->ci);
142911 +}
142912 +
142913 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
142914 +{
142915 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142916 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142917 + qm_cl_invalidate(MR_CI);
142918 + qm_cl_touch_rw(MR_CI);
142919 +}
142920 +
142921 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
142922 +{
142923 + register struct qm_mr *mr = &portal->mr;
142924 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142925 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142926 + qm_cl_out(MR_CI, mr->ci);
142927 +}
142928 +
142929 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
142930 +{
142931 + register struct qm_mr *mr = &portal->mr;
142932 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142933 + mr->ci = MR_PTR2IDX(mr->cursor);
142934 + qm_cl_out(MR_CI, mr->ci);
142935 +}
142936 +
142937 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
142938 +{
142939 + register struct qm_mr *mr = &portal->mr;
142940 + return mr->ci;
142941 +}
142942 +
142943 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
142944 +{
142945 + register struct qm_mr *mr = &portal->mr;
142946 + return mr->ithresh;
142947 +}
142948 +
142949 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142950 +{
142951 + qm_out(MR_ITR, ithresh);
142952 +}
142953 +
142954 +
142955 +/* ------------------------------ */
142956 +/* --- Management command API --- */
142957 +
142958 +static inline int qm_mc_init(struct qm_portal *portal)
142959 +{
142960 + register struct qm_mc *mc = &portal->mc;
142961 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
142962 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
142963 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
142964 + QM_MCC_VERB_VBIT) ? 0 : 1;
142965 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
142966 +#ifdef CONFIG_FSL_DPA_CHECKING
142967 + mc->state = qman_mc_idle;
142968 +#endif
142969 + return 0;
142970 +}
142971 +
142972 +static inline void qm_mc_finish(struct qm_portal *portal)
142973 +{
142974 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142975 + DPA_ASSERT(mc->state == qman_mc_idle);
142976 +#ifdef CONFIG_FSL_DPA_CHECKING
142977 + if (mc->state != qman_mc_idle)
142978 + pr_crit("Losing incomplete MC command\n");
142979 +#endif
142980 +}
142981 +
142982 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
142983 +{
142984 + register struct qm_mc *mc = &portal->mc;
142985 + DPA_ASSERT(mc->state == qman_mc_idle);
142986 +#ifdef CONFIG_FSL_DPA_CHECKING
142987 + mc->state = qman_mc_user;
142988 +#endif
142989 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142990 + dcbz_64(mc->cr);
142991 +#endif
142992 + return mc->cr;
142993 +}
142994 +
142995 +static inline void qm_mc_abort(struct qm_portal *portal)
142996 +{
142997 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142998 + DPA_ASSERT(mc->state == qman_mc_user);
142999 +#ifdef CONFIG_FSL_DPA_CHECKING
143000 + mc->state = qman_mc_idle;
143001 +#endif
143002 +}
143003 +
143004 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
143005 +{
143006 + register struct qm_mc *mc = &portal->mc;
143007 + struct qm_mc_result *rr = mc->rr + mc->rridx;
143008 + DPA_ASSERT(mc->state == qman_mc_user);
143009 + lwsync();
143010 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
143011 + dcbf(mc->cr);
143012 + dcbit_ro(rr);
143013 +#ifdef CONFIG_FSL_DPA_CHECKING
143014 + mc->state = qman_mc_hw;
143015 +#endif
143016 +}
143017 +
143018 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
143019 +{
143020 + register struct qm_mc *mc = &portal->mc;
143021 + struct qm_mc_result *rr = mc->rr + mc->rridx;
143022 + DPA_ASSERT(mc->state == qman_mc_hw);
143023 + /* The inactive response register's verb byte always returns zero until
143024 + * its command is submitted and completed. This includes the valid-bit,
143025 + * in case you were wondering... */
143026 + if (!__raw_readb(&rr->verb)) {
143027 + dcbit_ro(rr);
143028 + return NULL;
143029 + }
143030 + mc->rridx ^= 1;
143031 + mc->vbit ^= QM_MCC_VERB_VBIT;
143032 +#ifdef CONFIG_FSL_DPA_CHECKING
143033 + mc->state = qman_mc_idle;
143034 +#endif
143035 + return rr;
143036 +}
143037 +
143038 +
143039 +/* ------------------------------------- */
143040 +/* --- Portal interrupt register API --- */
143041 +
143042 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
143043 +{
143044 + return 0;
143045 +}
143046 +
143047 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
143048 +{
143049 +}
143050 +
143051 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
143052 +{
143053 + qm_out(ITPR, iperiod);
143054 +}
143055 +
143056 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
143057 +{
143058 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
143059 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
143060 +#else
143061 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
143062 +#endif
143063 +}
143064 +
143065 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
143066 + u32 val)
143067 +{
143068 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
143069 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
143070 +#else
143071 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
143072 +#endif
143073 +}
143074 +
143075 +/* Cleanup FQs */
143076 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
143077 + u32 fqid)
143078 +{
143079 +
143080 + struct qm_mc_command *mcc;
143081 + struct qm_mc_result *mcr;
143082 + u8 state;
143083 + int orl_empty, fq_empty, i, drain = 0;
143084 + u32 result;
143085 + u32 channel, wq;
143086 + u16 dest_wq;
143087 +
143088 + /* Determine the state of the FQID */
143089 + mcc = qm_mc_start(portal[0]);
143090 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
143091 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
143092 + while (!(mcr = qm_mc_result(portal[0])))
143093 + cpu_relax();
143094 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
143095 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
143096 + if (state == QM_MCR_NP_STATE_OOS)
143097 + return 0; /* Already OOS, no need to do anymore checks */
143098 +
143099 + /* Query which channel the FQ is using */
143100 + mcc = qm_mc_start(portal[0]);
143101 + mcc->queryfq.fqid = cpu_to_be32(fqid);
143102 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
143103 + while (!(mcr = qm_mc_result(portal[0])))
143104 + cpu_relax();
143105 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
143106 +
143107 + /* Need to store these since the MCR gets reused */
143108 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
143109 + wq = dest_wq & 0x7;
143110 + channel = dest_wq>>3;
143111 +
143112 + switch (state) {
143113 + case QM_MCR_NP_STATE_TEN_SCHED:
143114 + case QM_MCR_NP_STATE_TRU_SCHED:
143115 + case QM_MCR_NP_STATE_ACTIVE:
143116 + case QM_MCR_NP_STATE_PARKED:
143117 + orl_empty = 0;
143118 + mcc = qm_mc_start(portal[0]);
143119 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143120 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
143121 + while (!(mcr = qm_mc_result(portal[0])))
143122 + cpu_relax();
143123 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143124 + QM_MCR_VERB_ALTER_RETIRE);
143125 + result = mcr->result; /* Make a copy as we reuse MCR below */
143126 +
143127 + if (result == QM_MCR_RESULT_PENDING) {
143128 + /* Need to wait for the FQRN in the message ring, which
143129 + will only occur once the FQ has been drained. In
143130 + order for the FQ to drain the portal needs to be set
143131 + to dequeue from the channel the FQ is scheduled on */
143132 + const struct qm_mr_entry *msg;
143133 + const struct qm_dqrr_entry *dqrr = NULL;
143134 + int found_fqrn = 0;
143135 + u16 dequeue_wq = 0;
143136 +
143137 + /* Flag that we need to drain FQ */
143138 + drain = 1;
143139 +
143140 + if (channel >= qm_channel_pool1 &&
143141 + channel < (qm_channel_pool1 + 15)) {
143142 + /* Pool channel, enable the bit in the portal */
143143 + dequeue_wq = (channel -
143144 + qm_channel_pool1 + 1)<<4 | wq;
143145 + } else if (channel < qm_channel_pool1) {
143146 + /* Dedicated channel */
143147 + dequeue_wq = wq;
143148 + } else {
143149 + pr_info("Cannot recover FQ 0x%x, it is "
143150 + "scheduled on channel 0x%x",
143151 + fqid, channel);
143152 + return -EBUSY;
143153 + }
143154 + /* Set the sdqcr to drain this channel */
143155 + if (channel < qm_channel_pool1)
143156 + for (i = 0; i < portal_count; i++)
143157 + qm_dqrr_sdqcr_set(portal[i],
143158 + QM_SDQCR_TYPE_ACTIVE |
143159 + QM_SDQCR_CHANNELS_DEDICATED);
143160 + else
143161 + for (i = 0; i < portal_count; i++)
143162 + qm_dqrr_sdqcr_set(
143163 + portal[i],
143164 + QM_SDQCR_TYPE_ACTIVE |
143165 + QM_SDQCR_CHANNELS_POOL_CONV
143166 + (channel));
143167 + while (!found_fqrn) {
143168 + /* Keep draining DQRR while checking the MR*/
143169 + for (i = 0; i < portal_count; i++) {
143170 + qm_dqrr_pvb_update(portal[i]);
143171 + dqrr = qm_dqrr_current(portal[i]);
143172 + while (dqrr) {
143173 + qm_dqrr_cdc_consume_1ptr(
143174 + portal[i], dqrr, 0);
143175 + qm_dqrr_pvb_update(portal[i]);
143176 + qm_dqrr_next(portal[i]);
143177 + dqrr = qm_dqrr_current(
143178 + portal[i]);
143179 + }
143180 + /* Process message ring too */
143181 + qm_mr_pvb_update(portal[i]);
143182 + msg = qm_mr_current(portal[i]);
143183 + while (msg) {
143184 + if ((msg->verb &
143185 + QM_MR_VERB_TYPE_MASK)
143186 + == QM_MR_VERB_FQRN)
143187 + found_fqrn = 1;
143188 + qm_mr_next(portal[i]);
143189 + qm_mr_cci_consume_to_current(
143190 + portal[i]);
143191 + qm_mr_pvb_update(portal[i]);
143192 + msg = qm_mr_current(portal[i]);
143193 + }
143194 + cpu_relax();
143195 + }
143196 + }
143197 + }
143198 + if (result != QM_MCR_RESULT_OK &&
143199 + result != QM_MCR_RESULT_PENDING) {
143200 + /* error */
143201 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
143202 + fqid, result);
143203 + return -1;
143204 + }
143205 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
143206 + /* ORL had no entries, no need to wait until the
143207 + ERNs come in */
143208 + orl_empty = 1;
143209 + }
143210 + /* Retirement succeeded, check to see if FQ needs
143211 + to be drained */
143212 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
143213 + /* FQ is Not Empty, drain using volatile DQ commands */
143214 + fq_empty = 0;
143215 + do {
143216 + const struct qm_dqrr_entry *dqrr = NULL;
143217 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
143218 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
143219 +
143220 + /* Wait for a dequeue to occur */
143221 + while (dqrr == NULL) {
143222 + qm_dqrr_pvb_update(portal[0]);
143223 + dqrr = qm_dqrr_current(portal[0]);
143224 + if (!dqrr)
143225 + cpu_relax();
143226 + }
143227 + /* Process the dequeues, making sure to
143228 + empty the ring completely */
143229 + while (dqrr) {
143230 + if (be32_to_cpu(dqrr->fqid) == fqid &&
143231 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
143232 + fq_empty = 1;
143233 + qm_dqrr_cdc_consume_1ptr(portal[0],
143234 + dqrr, 0);
143235 + qm_dqrr_pvb_update(portal[0]);
143236 + qm_dqrr_next(portal[0]);
143237 + dqrr = qm_dqrr_current(portal[0]);
143238 + }
143239 + } while (fq_empty == 0);
143240 + }
143241 + for (i = 0; i < portal_count; i++)
143242 + qm_dqrr_sdqcr_set(portal[i], 0);
143243 +
143244 + /* Wait for the ORL to have been completely drained */
143245 + while (orl_empty == 0) {
143246 + const struct qm_mr_entry *msg;
143247 + qm_mr_pvb_update(portal[0]);
143248 + msg = qm_mr_current(portal[0]);
143249 + while (msg) {
143250 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
143251 + QM_MR_VERB_FQRL)
143252 + orl_empty = 1;
143253 + qm_mr_next(portal[0]);
143254 + qm_mr_cci_consume_to_current(portal[0]);
143255 + qm_mr_pvb_update(portal[0]);
143256 + msg = qm_mr_current(portal[0]);
143257 + }
143258 + cpu_relax();
143259 + }
143260 + mcc = qm_mc_start(portal[0]);
143261 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143262 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143263 + while (!(mcr = qm_mc_result(portal[0])))
143264 + cpu_relax();
143265 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143266 + QM_MCR_VERB_ALTER_OOS);
143267 + if (mcr->result != QM_MCR_RESULT_OK) {
143268 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
143269 + fqid, mcr->result);
143270 + return -1;
143271 + }
143272 + return 0;
143273 + case QM_MCR_NP_STATE_RETIRED:
143274 + /* Send OOS Command */
143275 + mcc = qm_mc_start(portal[0]);
143276 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143277 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143278 + while (!(mcr = qm_mc_result(portal[0])))
143279 + cpu_relax();
143280 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143281 + QM_MCR_VERB_ALTER_OOS);
143282 + if (mcr->result) {
143283 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
143284 + return -1;
143285 + }
143286 + return 0;
143287 + }
143288 + return -1;
143289 +}
143290 diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h
143291 new file mode 100644
143292 index 00000000..ee025cff
143293 --- /dev/null
143294 +++ b/drivers/staging/fsl_qbman/qman_private.h
143295 @@ -0,0 +1,398 @@
143296 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
143297 + *
143298 + * Redistribution and use in source and binary forms, with or without
143299 + * modification, are permitted provided that the following conditions are met:
143300 + * * Redistributions of source code must retain the above copyright
143301 + * notice, this list of conditions and the following disclaimer.
143302 + * * Redistributions in binary form must reproduce the above copyright
143303 + * notice, this list of conditions and the following disclaimer in the
143304 + * documentation and/or other materials provided with the distribution.
143305 + * * Neither the name of Freescale Semiconductor nor the
143306 + * names of its contributors may be used to endorse or promote products
143307 + * derived from this software without specific prior written permission.
143308 + *
143309 + *
143310 + * ALTERNATIVELY, this software may be distributed under the terms of the
143311 + * GNU General Public License ("GPL") as published by the Free Software
143312 + * Foundation, either version 2 of that License or (at your option) any
143313 + * later version.
143314 + *
143315 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143316 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143317 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143318 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143319 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143320 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143321 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143322 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143323 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143324 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143325 + */
143326 +
143327 +#include "dpa_sys.h"
143328 +#include <linux/fsl_qman.h>
143329 +#include <linux/iommu.h>
143330 +
143331 +#if defined(CONFIG_FSL_PAMU)
143332 +#include <asm/fsl_pamu_stash.h>
143333 +#endif
143334 +
143335 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
143336 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
143337 +#endif
143338 +
143339 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
143340 + /* ----------------- */
143341 + /* Congestion Groups */
143342 + /* ----------------- */
143343 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
143344 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
143345 + * those that don't concern us. We harness the structure and accessor details
143346 + * already used in the management command to query congestion groups. */
143347 +struct qman_cgrs {
143348 + struct __qm_mcr_querycongestion q;
143349 +};
143350 +static inline void qman_cgrs_init(struct qman_cgrs *c)
143351 +{
143352 + memset(c, 0, sizeof(*c));
143353 +}
143354 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
143355 +{
143356 + memset(c, 0xff, sizeof(*c));
143357 +}
143358 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
143359 +{
143360 + return QM_MCR_QUERYCONGESTION(&c->q, num);
143361 +}
143362 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
143363 +{
143364 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
143365 +}
143366 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
143367 +{
143368 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
143369 +}
143370 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
143371 +{
143372 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
143373 + ;
143374 + return num;
143375 +}
143376 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
143377 + const struct qman_cgrs *src)
143378 +{
143379 + *dest = *src;
143380 +}
143381 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
143382 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143383 +{
143384 + int ret;
143385 + u32 *_d = dest->q.__state;
143386 + const u32 *_a = a->q.__state;
143387 + const u32 *_b = b->q.__state;
143388 + for (ret = 0; ret < 8; ret++)
143389 + *(_d++) = *(_a++) & *(_b++);
143390 +}
143391 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
143392 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143393 +{
143394 + int ret;
143395 + u32 *_d = dest->q.__state;
143396 + const u32 *_a = a->q.__state;
143397 + const u32 *_b = b->q.__state;
143398 + for (ret = 0; ret < 8; ret++)
143399 + *(_d++) = *(_a++) ^ *(_b++);
143400 +}
143401 +
143402 + /* ----------------------- */
143403 + /* CEETM Congestion Groups */
143404 + /* ----------------------- */
143405 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
143406 + * congestion groups.
143407 + */
143408 +struct qman_ccgrs {
143409 + struct __qm_mcr_querycongestion q[2];
143410 +};
143411 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
143412 +{
143413 + memset(c, 0, sizeof(*c));
143414 +}
143415 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
143416 +{
143417 + memset(c, 0xff, sizeof(*c));
143418 +}
143419 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
143420 +{
143421 + if (num < __CGR_NUM)
143422 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
143423 + else
143424 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
143425 +}
143426 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
143427 +{
143428 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
143429 + ;
143430 + return num;
143431 +}
143432 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
143433 + const struct qman_ccgrs *src)
143434 +{
143435 + *dest = *src;
143436 +}
143437 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
143438 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143439 +{
143440 + int ret, i;
143441 + u32 *_d;
143442 + const u32 *_a, *_b;
143443 + for (i = 0; i < 2; i++) {
143444 + _d = dest->q[i].__state;
143445 + _a = a->q[i].__state;
143446 + _b = b->q[i].__state;
143447 + for (ret = 0; ret < 8; ret++)
143448 + *(_d++) = *(_a++) & *(_b++);
143449 + }
143450 +}
143451 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
143452 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143453 +{
143454 + int ret, i;
143455 + u32 *_d;
143456 + const u32 *_a, *_b;
143457 + for (i = 0; i < 2; i++) {
143458 + _d = dest->q[i].__state;
143459 + _a = a->q[i].__state;
143460 + _b = b->q[i].__state;
143461 + for (ret = 0; ret < 8; ret++)
143462 + *(_d++) = *(_a++) ^ *(_b++);
143463 + }
143464 +}
143465 +
143466 +/* used by CCSR and portal interrupt code */
143467 +enum qm_isr_reg {
143468 + qm_isr_status = 0,
143469 + qm_isr_enable = 1,
143470 + qm_isr_disable = 2,
143471 + qm_isr_inhibit = 3
143472 +};
143473 +
143474 +struct qm_portal_config {
143475 + /* Corenet portal addresses;
143476 + * [0]==cache-enabled, [1]==cache-inhibited. */
143477 + __iomem void *addr_virt[2];
143478 + struct resource addr_phys[2];
143479 + struct device dev;
143480 + struct iommu_domain *iommu_domain;
143481 + /* Allow these to be joined in lists */
143482 + struct list_head list;
143483 + /* User-visible portal configuration settings */
143484 + struct qman_portal_config public_cfg;
143485 + /* power management saved data */
143486 + u32 saved_isdr;
143487 +};
143488 +
143489 +/* Revision info (for errata and feature handling) */
143490 +#define QMAN_REV11 0x0101
143491 +#define QMAN_REV12 0x0102
143492 +#define QMAN_REV20 0x0200
143493 +#define QMAN_REV30 0x0300
143494 +#define QMAN_REV31 0x0301
143495 +#define QMAN_REV32 0x0302
143496 +
143497 +/* QMan REV_2 register contains the Cfg option */
143498 +#define QMAN_REV_CFG_0 0x0
143499 +#define QMAN_REV_CFG_1 0x1
143500 +#define QMAN_REV_CFG_2 0x2
143501 +#define QMAN_REV_CFG_3 0x3
143502 +
143503 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
143504 +extern u8 qman_ip_cfg;
143505 +extern u32 qman_clk;
143506 +extern u16 qman_portal_max;
143507 +
143508 +#ifdef CONFIG_FSL_QMAN_CONFIG
143509 +/* Hooks from qman_driver.c to qman_config.c */
143510 +int qman_init_ccsr(struct device_node *node);
143511 +void qman_liodn_fixup(u16 channel);
143512 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
143513 +size_t get_qman_fqd_size(void);
143514 +#else
143515 +static inline size_t get_qman_fqd_size(void)
143516 +{
143517 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
143518 +}
143519 +#endif
143520 +
143521 +int qm_set_wpm(int wpm);
143522 +int qm_get_wpm(int *wpm);
143523 +
143524 +/* Hooks from qman_driver.c in to qman_high.c */
143525 +struct qman_portal *qman_create_portal(
143526 + struct qman_portal *portal,
143527 + const struct qm_portal_config *config,
143528 + const struct qman_cgrs *cgrs);
143529 +
143530 +struct qman_portal *qman_create_affine_portal(
143531 + const struct qm_portal_config *config,
143532 + const struct qman_cgrs *cgrs);
143533 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
143534 + int cpu);
143535 +const struct qm_portal_config *qman_destroy_affine_portal(void);
143536 +void qman_destroy_portal(struct qman_portal *qm);
143537 +
143538 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
143539 +struct qm_portal_config *qm_get_unused_portal(void);
143540 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
143541 +
143542 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
143543 +void qm_set_liodns(struct qm_portal_config *pcfg);
143544 +
143545 +/* This CGR feature is supported by h/w and required by unit-tests and the
143546 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
143547 + * corruption of h/w fields by s/w that are usually incorruptible (because the
143548 + * counters are usually maintained entirely within h/w). As such, we declare
143549 + * this API internally. */
143550 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
143551 + struct qm_mcr_cgrtestwrite *result);
143552 +
143553 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
143554 +/* If the fq object pointer is greater than the size of context_b field,
143555 + * than a lookup table is required. */
143556 +int qman_setup_fq_lookup_table(size_t num_entries);
143557 +#endif
143558 +
143559 +
143560 +/*************************************************/
143561 +/* QMan s/w corenet portal, low-level i/face */
143562 +/*************************************************/
143563 +
143564 +/* Note: most functions are only used by the high-level interface, so are
143565 + * inlined from qman_low.h. The stuff below is for use by other parts of the
143566 + * driver. */
143567 +
143568 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
143569 + * dequeue TYPE. Choose TOKEN (8-bit).
143570 + * If SOURCE == CHANNELS,
143571 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
143572 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143573 + * priority.
143574 + * If SOURCE == SPECIFICWQ,
143575 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143576 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143577 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143578 + * same value.
143579 + */
143580 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
143581 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
143582 +#define QM_SDQCR_COUNT_EXACT1 0x0
143583 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
143584 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
143585 +#define QM_SDQCR_TYPE_MASK 0x03000000
143586 +#define QM_SDQCR_TYPE_NULL 0x0
143587 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
143588 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
143589 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
143590 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
143591 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
143592 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
143593 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
143594 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
143595 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
143596 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143597 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
143598 +
143599 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
143600 +#define QM_VDQCR_FQID_MASK 0x00ffffff
143601 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
143602 +
143603 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
143604 + * If MODE==SCHEDULED
143605 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
143606 + * If CHANNELS,
143607 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
143608 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143609 + * priority.
143610 + * If SPECIFICWQ,
143611 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143612 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143613 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143614 + * same value.
143615 + * If MODE==UNSCHEDULED
143616 + * Choose FQID().
143617 + */
143618 +#define QM_PDQCR_MODE_SCHEDULED 0x0
143619 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
143620 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
143621 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
143622 +#define QM_PDQCR_COUNT_EXACT1 0x0
143623 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
143624 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
143625 +#define QM_PDQCR_TYPE_MASK 0x03000000
143626 +#define QM_PDQCR_TYPE_NULL 0x0
143627 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
143628 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
143629 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
143630 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
143631 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
143632 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
143633 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
143634 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143635 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
143636 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
143637 +
143638 +/* Used by all portal interrupt registers except 'inhibit'
143639 + * Channels with frame availability
143640 + */
143641 +#define QM_PIRQ_DQAVAIL 0x0000ffff
143642 +
143643 +/* The DQAVAIL interrupt fields break down into these bits; */
143644 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
143645 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
143646 +#define QM_DQAVAIL_MASK 0xffff
143647 +/* This mask contains all the "irqsource" bits visible to API users */
143648 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
143649 +
143650 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
143651 + * the disable register" rather than "disable the ability to write". */
143652 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
143653 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
143654 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
143655 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
143656 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
143657 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
143658 +/* TODO: unfortunate name-clash here, reword? */
143659 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
143660 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
143661 +
143662 +#ifdef CONFIG_FSL_QMAN_CONFIG
143663 +int qman_have_ccsr(void);
143664 +#else
143665 +#define qman_have_ccsr 0
143666 +#endif
143667 +
143668 +__init int qman_init(void);
143669 +__init int qman_resource_init(void);
143670 +
143671 +/* CEETM related */
143672 +#define QMAN_CEETM_MAX 2
143673 +extern u8 num_ceetms;
143674 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
143675 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143676 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143677 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
143678 +int qman_ceetm_get_prescaler(u16 *pres);
143679 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
143680 + struct qm_mcr_ceetm_cq_query *cq_query);
143681 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
143682 + struct qm_mcr_ceetm_ccgr_query *response);
143683 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
143684 +
143685 +extern void *affine_portals[NR_CPUS];
143686 +const struct qm_portal_config *qman_get_qm_portal_config(
143687 + struct qman_portal *portal);
143688 +
143689 +/* power management */
143690 +#ifdef CONFIG_SUSPEND
143691 +void suspend_unused_qportal(void);
143692 +void resume_unused_qportal(void);
143693 +#endif
143694 diff --git a/drivers/staging/fsl_qbman/qman_test.c b/drivers/staging/fsl_qbman/qman_test.c
143695 new file mode 100644
143696 index 00000000..7995dd8c
143697 --- /dev/null
143698 +++ b/drivers/staging/fsl_qbman/qman_test.c
143699 @@ -0,0 +1,57 @@
143700 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143701 + *
143702 + * Redistribution and use in source and binary forms, with or without
143703 + * modification, are permitted provided that the following conditions are met:
143704 + * * Redistributions of source code must retain the above copyright
143705 + * notice, this list of conditions and the following disclaimer.
143706 + * * Redistributions in binary form must reproduce the above copyright
143707 + * notice, this list of conditions and the following disclaimer in the
143708 + * documentation and/or other materials provided with the distribution.
143709 + * * Neither the name of Freescale Semiconductor nor the
143710 + * names of its contributors may be used to endorse or promote products
143711 + * derived from this software without specific prior written permission.
143712 + *
143713 + *
143714 + * ALTERNATIVELY, this software may be distributed under the terms of the
143715 + * GNU General Public License ("GPL") as published by the Free Software
143716 + * Foundation, either version 2 of that License or (at your option) any
143717 + * later version.
143718 + *
143719 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143720 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143721 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143722 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143723 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143724 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143725 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143726 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143727 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143728 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143729 + */
143730 +
143731 +#include "qman_test.h"
143732 +
143733 +MODULE_AUTHOR("Geoff Thorpe");
143734 +MODULE_LICENSE("Dual BSD/GPL");
143735 +MODULE_DESCRIPTION("Qman testing");
143736 +
143737 +static int test_init(void)
143738 +{
143739 + int loop = 1;
143740 + while (loop--) {
143741 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143742 + qman_test_hotpotato();
143743 +#endif
143744 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143745 + qman_test_high();
143746 +#endif
143747 + }
143748 + return 0;
143749 +}
143750 +
143751 +static void test_exit(void)
143752 +{
143753 +}
143754 +
143755 +module_init(test_init);
143756 +module_exit(test_exit);
143757 diff --git a/drivers/staging/fsl_qbman/qman_test.h b/drivers/staging/fsl_qbman/qman_test.h
143758 new file mode 100644
143759 index 00000000..8c4181c7
143760 --- /dev/null
143761 +++ b/drivers/staging/fsl_qbman/qman_test.h
143762 @@ -0,0 +1,45 @@
143763 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143764 + *
143765 + * Redistribution and use in source and binary forms, with or without
143766 + * modification, are permitted provided that the following conditions are met:
143767 + * * Redistributions of source code must retain the above copyright
143768 + * notice, this list of conditions and the following disclaimer.
143769 + * * Redistributions in binary form must reproduce the above copyright
143770 + * notice, this list of conditions and the following disclaimer in the
143771 + * documentation and/or other materials provided with the distribution.
143772 + * * Neither the name of Freescale Semiconductor nor the
143773 + * names of its contributors may be used to endorse or promote products
143774 + * derived from this software without specific prior written permission.
143775 + *
143776 + *
143777 + * ALTERNATIVELY, this software may be distributed under the terms of the
143778 + * GNU General Public License ("GPL") as published by the Free Software
143779 + * Foundation, either version 2 of that License or (at your option) any
143780 + * later version.
143781 + *
143782 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143783 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143784 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143785 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143786 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143787 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143788 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143789 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143790 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143791 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143792 + */
143793 +
143794 +#include <linux/kernel.h>
143795 +#include <linux/errno.h>
143796 +#include <linux/io.h>
143797 +#include <linux/slab.h>
143798 +#include <linux/module.h>
143799 +#include <linux/interrupt.h>
143800 +#include <linux/delay.h>
143801 +#include <linux/sched.h>
143802 +
143803 +#include <linux/fsl_qman.h>
143804 +
143805 +void qman_test_hotpotato(void);
143806 +void qman_test_high(void);
143807 +
143808 diff --git a/drivers/staging/fsl_qbman/qman_test_high.c b/drivers/staging/fsl_qbman/qman_test_high.c
143809 new file mode 100644
143810 index 00000000..65ee270e
143811 --- /dev/null
143812 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
143813 @@ -0,0 +1,216 @@
143814 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143815 + *
143816 + * Redistribution and use in source and binary forms, with or without
143817 + * modification, are permitted provided that the following conditions are met:
143818 + * * Redistributions of source code must retain the above copyright
143819 + * notice, this list of conditions and the following disclaimer.
143820 + * * Redistributions in binary form must reproduce the above copyright
143821 + * notice, this list of conditions and the following disclaimer in the
143822 + * documentation and/or other materials provided with the distribution.
143823 + * * Neither the name of Freescale Semiconductor nor the
143824 + * names of its contributors may be used to endorse or promote products
143825 + * derived from this software without specific prior written permission.
143826 + *
143827 + *
143828 + * ALTERNATIVELY, this software may be distributed under the terms of the
143829 + * GNU General Public License ("GPL") as published by the Free Software
143830 + * Foundation, either version 2 of that License or (at your option) any
143831 + * later version.
143832 + *
143833 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143834 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143835 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143836 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143837 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143838 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143839 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143840 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143841 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143842 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143843 + */
143844 +
143845 +#include "qman_test.h"
143846 +
143847 +/*************/
143848 +/* constants */
143849 +/*************/
143850 +
143851 +#define CGR_ID 27
143852 +#define POOL_ID 2
143853 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
143854 +#define NUM_ENQUEUES 10
143855 +#define NUM_PARTIAL 4
143856 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
143857 + QM_SDQCR_TYPE_PRIO_QOS | \
143858 + QM_SDQCR_TOKEN_SET(0x98) | \
143859 + QM_SDQCR_CHANNELS_DEDICATED | \
143860 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
143861 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
143862 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
143863 +
143864 +/*************************************/
143865 +/* Predeclarations (eg. for fq_base) */
143866 +/*************************************/
143867 +
143868 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
143869 + struct qman_fq *,
143870 + const struct qm_dqrr_entry *);
143871 +static void cb_ern(struct qman_portal *, struct qman_fq *,
143872 + const struct qm_mr_entry *);
143873 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
143874 + const struct qm_mr_entry *);
143875 +
143876 +/***************/
143877 +/* global vars */
143878 +/***************/
143879 +
143880 +static struct qm_fd fd, fd_dq;
143881 +static struct qman_fq fq_base = {
143882 + .cb.dqrr = cb_dqrr,
143883 + .cb.ern = cb_ern,
143884 + .cb.fqs = cb_fqs
143885 +};
143886 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
143887 +static int retire_complete, sdqcr_complete;
143888 +
143889 +/**********************/
143890 +/* internal functions */
143891 +/**********************/
143892 +
143893 +/* Helpers for initialising and "incrementing" a frame descriptor */
143894 +static void fd_init(struct qm_fd *__fd)
143895 +{
143896 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
143897 + __fd->format = qm_fd_contig_big;
143898 + __fd->length29 = 0x0000ffff;
143899 + __fd->cmd = 0xfeedf00d;
143900 +}
143901 +
143902 +static void fd_inc(struct qm_fd *__fd)
143903 +{
143904 + u64 t = qm_fd_addr_get64(__fd);
143905 + int z = t >> 40;
143906 + t <<= 1;
143907 + if (z)
143908 + t |= 1;
143909 + qm_fd_addr_set64(__fd, t);
143910 + __fd->length29--;
143911 + __fd->cmd++;
143912 +}
143913 +
143914 +/* The only part of the 'fd' we can't memcmp() is the ppid */
143915 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
143916 +{
143917 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
143918 + if (!r)
143919 + r = a->format - b->format;
143920 + if (!r)
143921 + r = a->opaque - b->opaque;
143922 + if (!r)
143923 + r = a->cmd - b->cmd;
143924 + return r;
143925 +}
143926 +
143927 +/********/
143928 +/* test */
143929 +/********/
143930 +
143931 +static void do_enqueues(struct qman_fq *fq)
143932 +{
143933 + unsigned int loop;
143934 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
143935 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
143936 + (((loop + 1) == NUM_ENQUEUES) ?
143937 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
143938 + panic("qman_enqueue() failed\n");
143939 + fd_inc(&fd);
143940 + }
143941 +}
143942 +
143943 +void qman_test_high(void)
143944 +{
143945 + unsigned int flags;
143946 + int res;
143947 + struct qman_fq *fq = &fq_base;
143948 +
143949 + pr_info("qman_test_high starting\n");
143950 + fd_init(&fd);
143951 + fd_init(&fd_dq);
143952 +
143953 + /* Initialise (parked) FQ */
143954 + if (qman_create_fq(0, FQ_FLAGS, fq))
143955 + panic("qman_create_fq() failed\n");
143956 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
143957 + panic("qman_init_fq() failed\n");
143958 +
143959 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
143960 + do_enqueues(fq);
143961 + pr_info("VDQCR (till-empty);\n");
143962 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143963 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
143964 + panic("qman_volatile_dequeue() failed\n");
143965 + do_enqueues(fq);
143966 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
143967 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143968 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
143969 + panic("qman_volatile_dequeue() failed\n");
143970 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
143971 + NUM_ENQUEUES);
143972 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143973 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
143974 + panic("qman_volatile_dequeue() failed\n");
143975 +
143976 + do_enqueues(fq);
143977 + pr_info("scheduled dequeue (till-empty)\n");
143978 + if (qman_schedule_fq(fq))
143979 + panic("qman_schedule_fq() failed\n");
143980 + wait_event(waitqueue, sdqcr_complete);
143981 +
143982 + /* Retire and OOS the FQ */
143983 + res = qman_retire_fq(fq, &flags);
143984 + if (res < 0)
143985 + panic("qman_retire_fq() failed\n");
143986 + wait_event(waitqueue, retire_complete);
143987 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
143988 + panic("leaking frames\n");
143989 + if (qman_oos_fq(fq))
143990 + panic("qman_oos_fq() failed\n");
143991 + qman_destroy_fq(fq, 0);
143992 + pr_info("qman_test_high finished\n");
143993 +}
143994 +
143995 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
143996 + struct qman_fq *fq,
143997 + const struct qm_dqrr_entry *dq)
143998 +{
143999 + if (fd_cmp(&fd_dq, &dq->fd)) {
144000 + pr_err("BADNESS: dequeued frame doesn't match;\n");
144001 + pr_err("Expected 0x%llx, got 0x%llx\n",
144002 + (unsigned long long)fd_dq.length29,
144003 + (unsigned long long)dq->fd.length29);
144004 + BUG();
144005 + }
144006 + fd_inc(&fd_dq);
144007 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
144008 + sdqcr_complete = 1;
144009 + wake_up(&waitqueue);
144010 + }
144011 + return qman_cb_dqrr_consume;
144012 +}
144013 +
144014 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
144015 + const struct qm_mr_entry *msg)
144016 +{
144017 + panic("cb_ern() unimplemented");
144018 +}
144019 +
144020 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
144021 + const struct qm_mr_entry *msg)
144022 +{
144023 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
144024 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
144025 + panic("unexpected FQS message");
144026 + pr_info("Retirement message received\n");
144027 + retire_complete = 1;
144028 + wake_up(&waitqueue);
144029 +}
144030 diff --git a/drivers/staging/fsl_qbman/qman_test_hotpotato.c b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
144031 new file mode 100644
144032 index 00000000..899d2aa9
144033 --- /dev/null
144034 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
144035 @@ -0,0 +1,502 @@
144036 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
144037 + *
144038 + * Redistribution and use in source and binary forms, with or without
144039 + * modification, are permitted provided that the following conditions are met:
144040 + * * Redistributions of source code must retain the above copyright
144041 + * notice, this list of conditions and the following disclaimer.
144042 + * * Redistributions in binary form must reproduce the above copyright
144043 + * notice, this list of conditions and the following disclaimer in the
144044 + * documentation and/or other materials provided with the distribution.
144045 + * * Neither the name of Freescale Semiconductor nor the
144046 + * names of its contributors may be used to endorse or promote products
144047 + * derived from this software without specific prior written permission.
144048 + *
144049 + *
144050 + * ALTERNATIVELY, this software may be distributed under the terms of the
144051 + * GNU General Public License ("GPL") as published by the Free Software
144052 + * Foundation, either version 2 of that License or (at your option) any
144053 + * later version.
144054 + *
144055 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144056 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144057 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144058 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144059 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144060 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144061 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144062 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144063 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144064 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144065 + */
144066 +
144067 +#include <linux/kthread.h>
144068 +#include <linux/platform_device.h>
144069 +#include <linux/dma-mapping.h>
144070 +#include "qman_test.h"
144071 +
144072 +/* Algorithm:
144073 + *
144074 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
144075 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
144076 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
144077 + * shuttle a "hot potato" frame around them such that every forwarding action
144078 + * moves it from one cpu to another. (The use of more than one handler per cpu
144079 + * is to allow enough handlers/FQs to truly test the significance of caching -
144080 + * ie. when cache-expiries are occurring.)
144081 + *
144082 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
144083 + * first and last words of the frame data will undergo a transformation step on
144084 + * each forwarding action. To achieve this, each handler will be assigned a
144085 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
144086 + * received by a handler, the mixer of the expected sender is XOR'd into all
144087 + * words of the entire frame, which is then validated against the original
144088 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
144089 + * the current handler. Apart from validating that the frame is taking the
144090 + * expected path, this also provides some quasi-realistic overheads to each
144091 + * forwarding action - dereferencing *all* the frame data, computation, and
144092 + * conditional branching. There is a "special" handler designated to act as the
144093 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
144094 + * to determine when the test has completed by counting HP_LOOPS iterations.
144095 + *
144096 + * Init phases:
144097 + *
144098 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
144099 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
144100 + * handlers and link-list them (but do no other handler setup).
144101 + *
144102 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
144103 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
144104 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
144105 + * and advance the iterator for the next loop. This includes a final fixup,
144106 + * which connects the last handler to the first (and which is why phase 2
144107 + * and 3 are separate).
144108 + *
144109 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
144110 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
144111 + * initialise FQ objects and advance the iterator for the next loop.
144112 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
144113 + * initialisation targets the correct cpu.
144114 + */
144115 +
144116 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
144117 + * the fn from irq context, which is too restrictive). */
144118 +struct bstrap {
144119 + void (*fn)(void);
144120 + atomic_t started;
144121 +};
144122 +static int bstrap_fn(void *__bstrap)
144123 +{
144124 + struct bstrap *bstrap = __bstrap;
144125 + atomic_inc(&bstrap->started);
144126 + bstrap->fn();
144127 + while (!kthread_should_stop())
144128 + msleep(1);
144129 + return 0;
144130 +}
144131 +static int on_all_cpus(void (*fn)(void))
144132 +{
144133 + int cpu;
144134 + for_each_cpu(cpu, cpu_online_mask) {
144135 + struct bstrap bstrap = {
144136 + .fn = fn,
144137 + .started = ATOMIC_INIT(0)
144138 + };
144139 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
144140 + "hotpotato%d", cpu);
144141 + int ret;
144142 + if (IS_ERR(k))
144143 + return -ENOMEM;
144144 + kthread_bind(k, cpu);
144145 + wake_up_process(k);
144146 + /* If we call kthread_stop() before the "wake up" has had an
144147 + * effect, then the thread may exit with -EINTR without ever
144148 + * running the function. So poll until it's started before
144149 + * requesting it to stop. */
144150 + while (!atomic_read(&bstrap.started))
144151 + msleep(10);
144152 + ret = kthread_stop(k);
144153 + if (ret)
144154 + return ret;
144155 + }
144156 + return 0;
144157 +}
144158 +
144159 +struct hp_handler {
144160 +
144161 + /* The following data is stashed when 'rx' is dequeued; */
144162 + /* -------------- */
144163 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
144164 + struct qman_fq rx;
144165 + /* The Tx FQ we should forward to */
144166 + struct qman_fq tx;
144167 + /* The value we XOR post-dequeue, prior to validating */
144168 + u32 rx_mixer;
144169 + /* The value we XOR pre-enqueue, after validating */
144170 + u32 tx_mixer;
144171 + /* what the hotpotato address should be on dequeue */
144172 + dma_addr_t addr;
144173 + u32 *frame_ptr;
144174 +
144175 + /* The following data isn't (necessarily) stashed on dequeue; */
144176 + /* -------------- */
144177 + u32 fqid_rx, fqid_tx;
144178 + /* list node for linking us into 'hp_cpu' */
144179 + struct list_head node;
144180 + /* Just to check ... */
144181 + unsigned int processor_id;
144182 +} ____cacheline_aligned;
144183 +
144184 +struct hp_cpu {
144185 + /* identify the cpu we run on; */
144186 + unsigned int processor_id;
144187 + /* root node for the per-cpu list of handlers */
144188 + struct list_head handlers;
144189 + /* list node for linking us into 'hp_cpu_list' */
144190 + struct list_head node;
144191 + /* when repeatedly scanning 'hp_list', each time linking the n'th
144192 + * handlers together, this is used as per-cpu iterator state */
144193 + struct hp_handler *iterator;
144194 +};
144195 +
144196 +/* Each cpu has one of these */
144197 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
144198 +
144199 +/* links together the hp_cpu structs, in first-come first-serve order. */
144200 +static LIST_HEAD(hp_cpu_list);
144201 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
144202 +
144203 +static unsigned int hp_cpu_list_length;
144204 +
144205 +/* the "special" handler, that starts and terminates the test. */
144206 +static struct hp_handler *special_handler;
144207 +static int loop_counter;
144208 +
144209 +/* handlers are allocated out of this, so they're properly aligned. */
144210 +static struct kmem_cache *hp_handler_slab;
144211 +
144212 +/* this is the frame data */
144213 +static void *__frame_ptr;
144214 +static u32 *frame_ptr;
144215 +static dma_addr_t frame_dma;
144216 +
144217 +/* the main function waits on this */
144218 +static DECLARE_WAIT_QUEUE_HEAD(queue);
144219 +
144220 +#define HP_PER_CPU 2
144221 +#define HP_LOOPS 8
144222 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
144223 +#define HP_NUM_WORDS 80
144224 +/* First word of the LFSR-based frame data */
144225 +#define HP_FIRST_WORD 0xabbaf00d
144226 +
144227 +static inline u32 do_lfsr(u32 prev)
144228 +{
144229 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
144230 +}
144231 +
144232 +static void allocate_frame_data(void)
144233 +{
144234 + u32 lfsr = HP_FIRST_WORD;
144235 + int loop;
144236 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
144237 + if (!pdev)
144238 + panic("platform_device_alloc() failed");
144239 + if (platform_device_add(pdev))
144240 + panic("platform_device_add() failed");
144241 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
144242 + if (!__frame_ptr)
144243 + panic("kmalloc() failed");
144244 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
144245 + ~(unsigned long)63);
144246 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
144247 + frame_ptr[loop] = lfsr;
144248 + lfsr = do_lfsr(lfsr);
144249 + }
144250 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
144251 + DMA_BIDIRECTIONAL);
144252 + platform_device_del(pdev);
144253 + platform_device_put(pdev);
144254 +}
144255 +
144256 +static void deallocate_frame_data(void)
144257 +{
144258 + kfree(__frame_ptr);
144259 +}
144260 +
144261 +static inline void process_frame_data(struct hp_handler *handler,
144262 + const struct qm_fd *fd)
144263 +{
144264 + u32 *p = handler->frame_ptr;
144265 + u32 lfsr = HP_FIRST_WORD;
144266 + int loop;
144267 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
144268 + pr_err("Got 0x%llx expected 0x%llx\n",
144269 + qm_fd_addr_get64(fd), handler->addr);
144270 + panic("bad frame address");
144271 + }
144272 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144273 + *p ^= handler->rx_mixer;
144274 + if (*p != lfsr)
144275 + panic("corrupt frame data");
144276 + *p ^= handler->tx_mixer;
144277 + lfsr = do_lfsr(lfsr);
144278 + }
144279 +}
144280 +
144281 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
144282 + struct qman_fq *fq,
144283 + const struct qm_dqrr_entry *dqrr)
144284 +{
144285 + struct hp_handler *handler = (struct hp_handler *)fq;
144286 +
144287 + process_frame_data(handler, &dqrr->fd);
144288 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144289 + panic("qman_enqueue() failed");
144290 + return qman_cb_dqrr_consume;
144291 +}
144292 +
144293 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
144294 + struct qman_fq *fq,
144295 + const struct qm_dqrr_entry *dqrr)
144296 +{
144297 + struct hp_handler *handler = (struct hp_handler *)fq;
144298 +
144299 + process_frame_data(handler, &dqrr->fd);
144300 + if (++loop_counter < HP_LOOPS) {
144301 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144302 + panic("qman_enqueue() failed");
144303 + } else {
144304 + pr_info("Received final (%dth) frame\n", loop_counter);
144305 + wake_up(&queue);
144306 + }
144307 + return qman_cb_dqrr_consume;
144308 +}
144309 +
144310 +static void create_per_cpu_handlers(void)
144311 +{
144312 + struct hp_handler *handler;
144313 + int loop;
144314 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144315 +
144316 + hp_cpu->processor_id = smp_processor_id();
144317 + spin_lock(&hp_lock);
144318 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
144319 + hp_cpu_list_length++;
144320 + spin_unlock(&hp_lock);
144321 + INIT_LIST_HEAD(&hp_cpu->handlers);
144322 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144323 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
144324 + if (!handler)
144325 + panic("kmem_cache_alloc() failed");
144326 + handler->processor_id = hp_cpu->processor_id;
144327 + handler->addr = frame_dma;
144328 + handler->frame_ptr = frame_ptr;
144329 + list_add_tail(&handler->node, &hp_cpu->handlers);
144330 + }
144331 + put_cpu_var(hp_cpus);
144332 +}
144333 +
144334 +static void destroy_per_cpu_handlers(void)
144335 +{
144336 + struct list_head *loop, *tmp;
144337 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144338 +
144339 + spin_lock(&hp_lock);
144340 + list_del(&hp_cpu->node);
144341 + spin_unlock(&hp_lock);
144342 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
144343 + u32 flags;
144344 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
144345 + node);
144346 + if (qman_retire_fq(&handler->rx, &flags))
144347 + panic("qman_retire_fq(rx) failed");
144348 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
144349 + if (qman_oos_fq(&handler->rx))
144350 + panic("qman_oos_fq(rx) failed");
144351 + qman_destroy_fq(&handler->rx, 0);
144352 + qman_destroy_fq(&handler->tx, 0);
144353 + qman_release_fqid(handler->fqid_rx);
144354 + list_del(&handler->node);
144355 + kmem_cache_free(hp_handler_slab, handler);
144356 + }
144357 + put_cpu_var(hp_cpus);
144358 +}
144359 +
144360 +static inline u8 num_cachelines(u32 offset)
144361 +{
144362 + u8 res = (offset + (L1_CACHE_BYTES - 1))
144363 + / (L1_CACHE_BYTES);
144364 + if (res > 3)
144365 + return 3;
144366 + return res;
144367 +}
144368 +#define STASH_DATA_CL \
144369 + num_cachelines(HP_NUM_WORDS * 4)
144370 +#define STASH_CTX_CL \
144371 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
144372 +
144373 +static void init_handler(void *__handler)
144374 +{
144375 + struct qm_mcc_initfq opts;
144376 + struct hp_handler *handler = __handler;
144377 + BUG_ON(handler->processor_id != smp_processor_id());
144378 + /* Set up rx */
144379 + memset(&handler->rx, 0, sizeof(handler->rx));
144380 + if (handler == special_handler)
144381 + handler->rx.cb.dqrr = special_dqrr;
144382 + else
144383 + handler->rx.cb.dqrr = normal_dqrr;
144384 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
144385 + panic("qman_create_fq(rx) failed");
144386 + memset(&opts, 0, sizeof(opts));
144387 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
144388 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
144389 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
144390 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
144391 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
144392 + QMAN_INITFQ_FLAG_LOCAL, &opts))
144393 + panic("qman_init_fq(rx) failed");
144394 + /* Set up tx */
144395 + memset(&handler->tx, 0, sizeof(handler->tx));
144396 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
144397 + &handler->tx))
144398 + panic("qman_create_fq(tx) failed");
144399 +}
144400 +
144401 +static void init_phase2(void)
144402 +{
144403 + int loop;
144404 + u32 fqid = 0;
144405 + u32 lfsr = 0xdeadbeef;
144406 + struct hp_cpu *hp_cpu;
144407 + struct hp_handler *handler;
144408 +
144409 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144410 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144411 + int ret;
144412 + if (!loop)
144413 + hp_cpu->iterator = list_first_entry(
144414 + &hp_cpu->handlers,
144415 + struct hp_handler, node);
144416 + else
144417 + hp_cpu->iterator = list_entry(
144418 + hp_cpu->iterator->node.next,
144419 + struct hp_handler, node);
144420 + /* Rx FQID is the previous handler's Tx FQID */
144421 + hp_cpu->iterator->fqid_rx = fqid;
144422 + /* Allocate new FQID for Tx */
144423 + ret = qman_alloc_fqid(&fqid);
144424 + if (ret)
144425 + panic("qman_alloc_fqid() failed");
144426 + hp_cpu->iterator->fqid_tx = fqid;
144427 + /* Rx mixer is the previous handler's Tx mixer */
144428 + hp_cpu->iterator->rx_mixer = lfsr;
144429 + /* Get new mixer for Tx */
144430 + lfsr = do_lfsr(lfsr);
144431 + hp_cpu->iterator->tx_mixer = lfsr;
144432 + }
144433 + }
144434 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
144435 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
144436 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
144437 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
144438 + handler->fqid_rx = fqid;
144439 + handler->rx_mixer = lfsr;
144440 + /* and tag it as our "special" handler */
144441 + special_handler = handler;
144442 +}
144443 +
144444 +static void init_phase3(void)
144445 +{
144446 + int loop;
144447 + struct hp_cpu *hp_cpu;
144448 +
144449 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144450 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144451 + if (!loop)
144452 + hp_cpu->iterator = list_first_entry(
144453 + &hp_cpu->handlers,
144454 + struct hp_handler, node);
144455 + else
144456 + hp_cpu->iterator = list_entry(
144457 + hp_cpu->iterator->node.next,
144458 + struct hp_handler, node);
144459 + preempt_disable();
144460 + if (hp_cpu->processor_id == smp_processor_id())
144461 + init_handler(hp_cpu->iterator);
144462 + else
144463 + smp_call_function_single(hp_cpu->processor_id,
144464 + init_handler, hp_cpu->iterator, 1);
144465 + preempt_enable();
144466 + }
144467 + }
144468 +}
144469 +
144470 +static void send_first_frame(void *ignore)
144471 +{
144472 + u32 *p = special_handler->frame_ptr;
144473 + u32 lfsr = HP_FIRST_WORD;
144474 + int loop;
144475 + struct qm_fd fd;
144476 +
144477 + BUG_ON(special_handler->processor_id != smp_processor_id());
144478 + memset(&fd, 0, sizeof(fd));
144479 + qm_fd_addr_set64(&fd, special_handler->addr);
144480 + fd.format = qm_fd_contig_big;
144481 + fd.length29 = HP_NUM_WORDS * 4;
144482 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144483 + if (*p != lfsr)
144484 + panic("corrupt frame data");
144485 + *p ^= special_handler->tx_mixer;
144486 + lfsr = do_lfsr(lfsr);
144487 + }
144488 + pr_info("Sending first frame\n");
144489 + if (qman_enqueue(&special_handler->tx, &fd, 0))
144490 + panic("qman_enqueue() failed");
144491 +}
144492 +
144493 +void qman_test_hotpotato(void)
144494 +{
144495 + if (cpumask_weight(cpu_online_mask) < 2) {
144496 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
144497 + return;
144498 + }
144499 +
144500 + pr_info("qman_test_hotpotato starting\n");
144501 +
144502 + hp_cpu_list_length = 0;
144503 + loop_counter = 0;
144504 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
144505 + sizeof(struct hp_handler), L1_CACHE_BYTES,
144506 + SLAB_HWCACHE_ALIGN, NULL);
144507 + if (!hp_handler_slab)
144508 + panic("kmem_cache_create() failed");
144509 +
144510 + allocate_frame_data();
144511 +
144512 + /* Init phase 1 */
144513 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
144514 + if (on_all_cpus(create_per_cpu_handlers))
144515 + panic("on_each_cpu() failed");
144516 + pr_info("Number of cpus: %d, total of %d handlers\n",
144517 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
144518 +
144519 + init_phase2();
144520 +
144521 + init_phase3();
144522 +
144523 + preempt_disable();
144524 + if (special_handler->processor_id == smp_processor_id())
144525 + send_first_frame(NULL);
144526 + else
144527 + smp_call_function_single(special_handler->processor_id,
144528 + send_first_frame, NULL, 1);
144529 + preempt_enable();
144530 +
144531 + wait_event(queue, loop_counter == HP_LOOPS);
144532 + deallocate_frame_data();
144533 + if (on_all_cpus(destroy_per_cpu_handlers))
144534 + panic("on_each_cpu() failed");
144535 + kmem_cache_destroy(hp_handler_slab);
144536 + pr_info("qman_test_hotpotato finished\n");
144537 +}
144538 diff --git a/drivers/staging/fsl_qbman/qman_utility.c b/drivers/staging/fsl_qbman/qman_utility.c
144539 new file mode 100644
144540 index 00000000..f1e39023
144541 --- /dev/null
144542 +++ b/drivers/staging/fsl_qbman/qman_utility.c
144543 @@ -0,0 +1,129 @@
144544 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144545 + *
144546 + * Redistribution and use in source and binary forms, with or without
144547 + * modification, are permitted provided that the following conditions are met:
144548 + * * Redistributions of source code must retain the above copyright
144549 + * notice, this list of conditions and the following disclaimer.
144550 + * * Redistributions in binary form must reproduce the above copyright
144551 + * notice, this list of conditions and the following disclaimer in the
144552 + * documentation and/or other materials provided with the distribution.
144553 + * * Neither the name of Freescale Semiconductor nor the
144554 + * names of its contributors may be used to endorse or promote products
144555 + * derived from this software without specific prior written permission.
144556 + *
144557 + *
144558 + * ALTERNATIVELY, this software may be distributed under the terms of the
144559 + * GNU General Public License ("GPL") as published by the Free Software
144560 + * Foundation, either version 2 of that License or (at your option) any
144561 + * later version.
144562 + *
144563 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144564 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144565 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144566 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144567 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144568 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144569 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144570 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144571 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144572 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144573 + */
144574 +
144575 +#include "qman_private.h"
144576 +
144577 +/* ----------------- */
144578 +/* --- FQID Pool --- */
144579 +
144580 +struct qman_fqid_pool {
144581 + /* Base and size of the FQID range */
144582 + u32 fqid_base;
144583 + u32 total;
144584 + /* Number of FQIDs currently "allocated" */
144585 + u32 used;
144586 + /* Allocation optimisation. When 'used<total', it is the index of an
144587 + * available FQID. Otherwise there are no available FQIDs, and this
144588 + * will be set when the next deallocation occurs. */
144589 + u32 next;
144590 + /* A bit-field representation of the FQID range. */
144591 + unsigned long *bits;
144592 +};
144593 +
144594 +#define QLONG_BYTES sizeof(unsigned long)
144595 +#define QLONG_BITS (QLONG_BYTES * 8)
144596 +/* Number of 'longs' required for the given number of bits */
144597 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
144598 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
144599 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
144600 +/* And in bits */
144601 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
144602 +
144603 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
144604 +{
144605 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
144606 + unsigned int i;
144607 +
144608 + BUG_ON(!num);
144609 + if (!pool)
144610 + return NULL;
144611 + pool->fqid_base = fqid_start;
144612 + pool->total = num;
144613 + pool->used = 0;
144614 + pool->next = 0;
144615 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
144616 + if (!pool->bits) {
144617 + kfree(pool);
144618 + return NULL;
144619 + }
144620 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
144621 + * byte-oriented searching) then we fill the trailing bits with 1, to
144622 + * make them look allocated (permanently). */
144623 + for (i = num + 1; i < QNUM_BITS(num); i++)
144624 + set_bit(i, pool->bits);
144625 + return pool;
144626 +}
144627 +EXPORT_SYMBOL(qman_fqid_pool_create);
144628 +
144629 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
144630 +{
144631 + int ret = pool->used;
144632 + kfree(pool->bits);
144633 + kfree(pool);
144634 + return ret;
144635 +}
144636 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
144637 +
144638 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
144639 +{
144640 + int ret;
144641 + if (pool->used == pool->total)
144642 + return -ENOMEM;
144643 + *fqid = pool->fqid_base + pool->next;
144644 + ret = test_and_set_bit(pool->next, pool->bits);
144645 + BUG_ON(ret);
144646 + if (++pool->used == pool->total)
144647 + return 0;
144648 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
144649 + if (pool->next >= pool->total)
144650 + pool->next = find_first_zero_bit(pool->bits, pool->total);
144651 + BUG_ON(pool->next >= pool->total);
144652 + return 0;
144653 +}
144654 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
144655 +
144656 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
144657 +{
144658 + int ret;
144659 +
144660 + fqid -= pool->fqid_base;
144661 + ret = test_and_clear_bit(fqid, pool->bits);
144662 + BUG_ON(!ret);
144663 + if (pool->used-- == pool->total)
144664 + pool->next = fqid;
144665 +}
144666 +EXPORT_SYMBOL(qman_fqid_pool_free);
144667 +
144668 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
144669 +{
144670 + return pool->used;
144671 +}
144672 +EXPORT_SYMBOL(qman_fqid_pool_used);
144673 diff --git a/include/linux/fsl_bman.h b/include/linux/fsl_bman.h
144674 new file mode 100644
144675 index 00000000..43942221
144676 --- /dev/null
144677 +++ b/include/linux/fsl_bman.h
144678 @@ -0,0 +1,532 @@
144679 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144680 + *
144681 + * Redistribution and use in source and binary forms, with or without
144682 + * modification, are permitted provided that the following conditions are met:
144683 + * * Redistributions of source code must retain the above copyright
144684 + * notice, this list of conditions and the following disclaimer.
144685 + * * Redistributions in binary form must reproduce the above copyright
144686 + * notice, this list of conditions and the following disclaimer in the
144687 + * documentation and/or other materials provided with the distribution.
144688 + * * Neither the name of Freescale Semiconductor nor the
144689 + * names of its contributors may be used to endorse or promote products
144690 + * derived from this software without specific prior written permission.
144691 + *
144692 + *
144693 + * ALTERNATIVELY, this software may be distributed under the terms of the
144694 + * GNU General Public License ("GPL") as published by the Free Software
144695 + * Foundation, either version 2 of that License or (at your option) any
144696 + * later version.
144697 + *
144698 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144699 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144700 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144701 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144702 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144703 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144704 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144705 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144706 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144707 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144708 + */
144709 +
144710 +#ifndef FSL_BMAN_H
144711 +#define FSL_BMAN_H
144712 +
144713 +#ifdef __cplusplus
144714 +extern "C" {
144715 +#endif
144716 +
144717 +/* Last updated for v00.79 of the BG */
144718 +
144719 +/* Portal processing (interrupt) sources */
144720 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
144721 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
144722 +
144723 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
144724 + * buffer pools. */
144725 +struct bman_depletion {
144726 + u32 __state[2];
144727 +};
144728 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
144729 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
144730 +#define __bmdep_word(x) ((x) >> 5)
144731 +#define __bmdep_shift(x) ((x) & 0x1f)
144732 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
144733 +static inline void bman_depletion_init(struct bman_depletion *c)
144734 +{
144735 + c->__state[0] = c->__state[1] = 0;
144736 +}
144737 +static inline void bman_depletion_fill(struct bman_depletion *c)
144738 +{
144739 + c->__state[0] = c->__state[1] = ~0;
144740 +}
144741 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144742 +{
144743 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144744 +}
144745 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144746 +{
144747 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144748 +}
144749 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144750 +{
144751 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144752 +}
144753 +
144754 +/* ------------------------------------------------------- */
144755 +/* --- Bman data structures (and associated constants) --- */
144756 +
144757 +/* Represents s/w corenet portal mapped data structures */
144758 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144759 +struct bm_mc_command; /* MC (Management Command) command */
144760 +struct bm_mc_result; /* MC result */
144761 +
144762 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144763 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144764 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144765 +struct bm_buffer {
144766 + union {
144767 + struct {
144768 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144769 + u8 __reserved1;
144770 + u8 bpid;
144771 + u16 hi; /* High 16-bits of 48-bit address */
144772 + u32 lo; /* Low 32-bits of 48-bit address */
144773 +#else
144774 + u32 lo;
144775 + u16 hi;
144776 + u8 bpid;
144777 + u8 __reserved;
144778 +#endif
144779 + };
144780 + struct {
144781 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144782 + u64 __notaddress:16;
144783 + u64 addr:48;
144784 +#else
144785 + u64 addr:48;
144786 + u64 __notaddress:16;
144787 +#endif
144788 + };
144789 + u64 opaque;
144790 + };
144791 +} __aligned(8);
144792 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144793 +{
144794 + return buf->addr;
144795 +}
144796 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
144797 +{
144798 + return (dma_addr_t)buf->addr;
144799 +}
144800 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144801 +#define bm_buffer_set64(buf, v) \
144802 + do { \
144803 + struct bm_buffer *__buf931 = (buf); \
144804 + __buf931->hi = upper_32_bits(v); \
144805 + __buf931->lo = lower_32_bits(v); \
144806 + } while (0)
144807 +
144808 +/* See 1.5.3.5.4: "Release Command" */
144809 +struct bm_rcr_entry {
144810 + union {
144811 + struct {
144812 + u8 __dont_write_directly__verb;
144813 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
144814 + u8 __reserved1[62];
144815 + };
144816 + struct bm_buffer bufs[8];
144817 + };
144818 +} __packed;
144819 +#define BM_RCR_VERB_VBIT 0x80
144820 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
144821 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
144822 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
144823 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
144824 +
144825 +/* See 1.5.3.1: "Acquire Command" */
144826 +/* See 1.5.3.2: "Query Command" */
144827 +struct bm_mcc_acquire {
144828 + u8 bpid;
144829 + u8 __reserved1[62];
144830 +} __packed;
144831 +struct bm_mcc_query {
144832 + u8 __reserved2[63];
144833 +} __packed;
144834 +struct bm_mc_command {
144835 + u8 __dont_write_directly__verb;
144836 + union {
144837 + struct bm_mcc_acquire acquire;
144838 + struct bm_mcc_query query;
144839 + };
144840 +} __packed;
144841 +#define BM_MCC_VERB_VBIT 0x80
144842 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
144843 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
144844 +#define BM_MCC_VERB_CMD_QUERY 0x40
144845 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
144846 +
144847 +/* See 1.5.3.3: "Acquire Response" */
144848 +/* See 1.5.3.4: "Query Response" */
144849 +struct bm_pool_state {
144850 + u8 __reserved1[32];
144851 + /* "availability state" and "depletion state" */
144852 + struct {
144853 + u8 __reserved1[8];
144854 + /* Access using bman_depletion_***() */
144855 + struct bman_depletion state;
144856 + } as, ds;
144857 +};
144858 +struct bm_mc_result {
144859 + union {
144860 + struct {
144861 + u8 verb;
144862 + u8 __reserved1[63];
144863 + };
144864 + union {
144865 + struct {
144866 + u8 __reserved1;
144867 + u8 bpid;
144868 + u8 __reserved2[62];
144869 + };
144870 + struct bm_buffer bufs[8];
144871 + } acquire;
144872 + struct bm_pool_state query;
144873 + };
144874 +} __packed;
144875 +#define BM_MCR_VERB_VBIT 0x80
144876 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
144877 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
144878 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
144879 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
144880 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
144881 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
144882 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
144883 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
144884 + bman_depletion_get(&r->query.as.state, p)
144885 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
144886 +#define BM_MCR_QUERY_DEPLETION(r, p) \
144887 + bman_depletion_get(&r->query.ds.state, p)
144888 +
144889 +/*******************************************************************/
144890 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
144891 +/*******************************************************************/
144892 +
144893 + /* Portal and Buffer Pools */
144894 + /* ----------------------- */
144895 +/* Represents a managed portal */
144896 +struct bman_portal;
144897 +
144898 +/* This object type represents Bman buffer pools. */
144899 +struct bman_pool;
144900 +
144901 +struct bman_portal_config {
144902 + /* This is used for any "core-affine" portals, ie. default portals
144903 + * associated to the corresponding cpu. -1 implies that there is no core
144904 + * affinity configured. */
144905 + int cpu;
144906 + /* portal interrupt line */
144907 + int irq;
144908 + /* the unique index of this portal */
144909 + u32 index;
144910 + /* Is this portal shared? (If so, it has coarser locking and demuxes
144911 + * processing on behalf of other CPUs.) */
144912 + int is_shared;
144913 + /* These are the buffer pool IDs that may be used via this portal. */
144914 + struct bman_depletion mask;
144915 +};
144916 +
144917 +/* This callback type is used when handling pool depletion entry/exit. The
144918 + * 'cb_ctx' value is the opaque value associated with the pool object in
144919 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
144920 + * depletion-exit. */
144921 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
144922 + struct bman_pool *pool, void *cb_ctx, int depleted);
144923 +
144924 +/* This struct specifies parameters for a bman_pool object. */
144925 +struct bman_pool_params {
144926 + /* index of the buffer pool to encapsulate (0-63), ignored if
144927 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
144928 + u32 bpid;
144929 + /* bit-mask of BMAN_POOL_FLAG_*** options */
144930 + u32 flags;
144931 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
144932 + bman_cb_depletion cb;
144933 + /* opaque user value passed as a parameter to 'cb' */
144934 + void *cb_ctx;
144935 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
144936 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
144937 + * when run in the control plane (which controls Bman CCSR). This array
144938 + * matches the definition of bm_pool_set(). */
144939 + u32 thresholds[4];
144940 +};
144941 +
144942 +/* Flags to bman_new_pool() */
144943 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
144944 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
144945 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
144946 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
144947 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
144948 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
144949 +
144950 +/* Flags to bman_release() */
144951 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
144952 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
144953 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
144954 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
144955 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
144956 +#endif
144957 +#endif
144958 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
144959 +
144960 +/* Flags to bman_acquire() */
144961 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
144962 +
144963 + /* Portal Management */
144964 + /* ----------------- */
144965 +/**
144966 + * bman_get_portal_config - get portal configuration settings
144967 + *
144968 + * This returns a read-only view of the current cpu's affine portal settings.
144969 + */
144970 +const struct bman_portal_config *bman_get_portal_config(void);
144971 +
144972 +/**
144973 + * bman_irqsource_get - return the portal work that is interrupt-driven
144974 + *
144975 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
144976 + * enabled for interrupt handling on the current cpu's affine portal. These
144977 + * sources will trigger the portal interrupt and the interrupt handler (or a
144978 + * tasklet/bottom-half it defers to) will perform the corresponding processing
144979 + * work. The bman_poll_***() functions will only process sources that are not in
144980 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
144981 + * this always returns zero.
144982 + */
144983 +u32 bman_irqsource_get(void);
144984 +
144985 +/**
144986 + * bman_irqsource_add - add processing sources to be interrupt-driven
144987 + * @bits: bitmask of BM_PIRQ_**I processing sources
144988 + *
144989 + * Adds processing sources that should be interrupt-driven (rather than
144990 + * processed via bman_poll_***() functions). Returns zero for success, or
144991 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144992 +int bman_irqsource_add(u32 bits);
144993 +
144994 +/**
144995 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
144996 + * @bits: bitmask of BM_PIRQ_**I processing sources
144997 + *
144998 + * Removes processing sources from being interrupt-driven, so that they will
144999 + * instead be processed via bman_poll_***() functions. Returns zero for success,
145000 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
145001 +int bman_irqsource_remove(u32 bits);
145002 +
145003 +/**
145004 + * bman_affine_cpus - return a mask of cpus that have affine portals
145005 + */
145006 +const cpumask_t *bman_affine_cpus(void);
145007 +
145008 +/**
145009 + * bman_poll_slow - process anything that isn't interrupt-driven.
145010 + *
145011 + * This function does any portal processing that isn't interrupt-driven. If the
145012 + * current CPU is sharing a portal hosted on another CPU, this function will
145013 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
145014 + * indicating what interrupt sources were actually processed by the call.
145015 + *
145016 + * NB, unlike the legacy wrapper bman_poll(), this function will
145017 + * deterministically check for the presence of portal processing work and do it,
145018 + * which implies some latency even if there's nothing to do. The bman_poll()
145019 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
145020 + * checking for (and doing) portal processing infrequently. Ie. such that
145021 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
145022 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
145023 + * processing.
145024 + */
145025 +u32 bman_poll_slow(void);
145026 +
145027 +/**
145028 + * bman_poll - process anything that isn't interrupt-driven.
145029 + *
145030 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
145031 + * affine portal. This function does whatever processing is not triggered by
145032 + * interrupts. This is a legacy wrapper that can be used in core-processing
145033 + * loops but mitigates the performance overhead of portal processing by
145034 + * adaptively bypassing true portal processing most of the time. (Processing is
145035 + * done once every 10 calls if the previous processing revealed that work needed
145036 + * to be done, or once very 1000 calls if the previous processing revealed no
145037 + * work needed doing.) If you wish to control this yourself, call
145038 + * bman_poll_slow() instead, which always checks for portal processing work.
145039 + */
145040 +void bman_poll(void);
145041 +
145042 +/**
145043 + * bman_rcr_is_empty - Determine if portal's RCR is empty
145044 + *
145045 + * For use in situations where a cpu-affine caller needs to determine when all
145046 + * releases for the local portal have been processed by Bman but can't use the
145047 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
145048 + * The function forces tracking of RCR consumption (which normally doesn't
145049 + * happen until release processing needs to find space to put new release
145050 + * commands), and returns zero if the ring still has unprocessed entries,
145051 + * non-zero if it is empty.
145052 + */
145053 +int bman_rcr_is_empty(void);
145054 +
145055 +/**
145056 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
145057 + * @result: is set by the API to the base BPID of the allocated range
145058 + * @count: the number of BPIDs required
145059 + * @align: required alignment of the allocated range
145060 + * @partial: non-zero if the API can return fewer than @count BPIDs
145061 + *
145062 + * Returns the number of buffer pools allocated, or a negative error code. If
145063 + * @partial is non zero, the allocation request may return a smaller range of
145064 + * BPs than requested (though alignment will be as requested). If @partial is
145065 + * zero, the return value will either be 'count' or negative.
145066 + */
145067 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
145068 +static inline int bman_alloc_bpid(u32 *result)
145069 +{
145070 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
145071 + return (ret > 0) ? 0 : ret;
145072 +}
145073 +
145074 +/**
145075 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
145076 + * @bpid: the base BPID of the range to deallocate
145077 + * @count: the number of BPIDs in the range
145078 + *
145079 + * This function can also be used to seed the allocator with ranges of BPIDs
145080 + * that it can subsequently allocate from.
145081 + */
145082 +void bman_release_bpid_range(u32 bpid, unsigned int count);
145083 +static inline void bman_release_bpid(u32 bpid)
145084 +{
145085 + bman_release_bpid_range(bpid, 1);
145086 +}
145087 +
145088 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
145089 +static inline int bman_reserve_bpid(u32 bpid)
145090 +{
145091 + return bman_reserve_bpid_range(bpid, 1);
145092 +}
145093 +
145094 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
145095 +
145096 +
145097 +int bman_shutdown_pool(u32 bpid);
145098 +
145099 + /* Pool management */
145100 + /* --------------- */
145101 +/**
145102 + * bman_new_pool - Allocates a Buffer Pool object
145103 + * @params: parameters specifying the buffer pool ID and behaviour
145104 + *
145105 + * Creates a pool object for the given @params. A portal and the depletion
145106 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
145107 + * is set. NB, the fields from @params are copied into the new pool object, so
145108 + * the structure provided by the caller can be released or reused after the
145109 + * function returns.
145110 + */
145111 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
145112 +
145113 +/**
145114 + * bman_free_pool - Deallocates a Buffer Pool object
145115 + * @pool: the pool object to release
145116 + *
145117 + */
145118 +void bman_free_pool(struct bman_pool *pool);
145119 +
145120 +/**
145121 + * bman_get_params - Returns a pool object's parameters.
145122 + * @pool: the pool object
145123 + *
145124 + * The returned pointer refers to state within the pool object so must not be
145125 + * modified and can no longer be read once the pool object is destroyed.
145126 + */
145127 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
145128 +
145129 +/**
145130 + * bman_release - Release buffer(s) to the buffer pool
145131 + * @pool: the buffer pool object to release to
145132 + * @bufs: an array of buffers to release
145133 + * @num: the number of buffers in @bufs (1-8)
145134 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
145135 + *
145136 + * Adds the given buffers to RCR entries. If the portal @p was created with the
145137 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
145138 + * utilisation of RCR. As such, these buffers may join an existing ring entry
145139 + * and/or it may not be issued right away so as to allow future releases to join
145140 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
145141 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
145142 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
145143 + * is selected, in which case it will sleep waiting for space to become
145144 + * available in RCR. If the function receives a signal before such time (and
145145 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
145146 + * it returns zero.
145147 + */
145148 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
145149 + u32 flags);
145150 +
145151 +/**
145152 + * bman_acquire - Acquire buffer(s) from a buffer pool
145153 + * @pool: the buffer pool object to acquire from
145154 + * @bufs: array for storing the acquired buffers
145155 + * @num: the number of buffers desired (@bufs is at least this big)
145156 + *
145157 + * Issues an "Acquire" command via the portal's management command interface.
145158 + * The return value will be the number of buffers obtained from the pool, or a
145159 + * negative error code if a h/w error or pool starvation was encountered. In
145160 + * the latter case, the content of @bufs is undefined.
145161 + */
145162 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
145163 + u32 flags);
145164 +
145165 +/**
145166 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
145167 + * @pool: the buffer pool object the stockpile belongs
145168 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
145169 + *
145170 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
145171 + * The return value will be a negative error code if a h/w error occurred.
145172 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
145173 + * -EAGAIN will be returned.
145174 + */
145175 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
145176 +
145177 +/**
145178 + * bman_query_pools - Query all buffer pool states
145179 + * @state: storage for the queried availability and depletion states
145180 + */
145181 +int bman_query_pools(struct bm_pool_state *state);
145182 +
145183 +#ifdef CONFIG_FSL_BMAN_CONFIG
145184 +/**
145185 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
145186 + * @pool: the buffer pool object to query
145187 + *
145188 + * Return the number of the free buffers
145189 + */
145190 +u32 bman_query_free_buffers(struct bman_pool *pool);
145191 +
145192 +/**
145193 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
145194 + * @pool: the buffer pool object to which the thresholds will be set
145195 + * @thresholds: the new thresholds
145196 + */
145197 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
145198 +#endif
145199 +
145200 +/**
145201 + * The below bman_p_***() variant might be called in a situation that the cpu
145202 + * which the portal affine to is not online yet.
145203 + * @bman_portal specifies which portal the API will use.
145204 +*/
145205 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
145206 +#ifdef __cplusplus
145207 +}
145208 +#endif
145209 +
145210 +#endif /* FSL_BMAN_H */
145211 diff --git a/include/linux/fsl_qman.h b/include/linux/fsl_qman.h
145212 new file mode 100644
145213 index 00000000..4e4b21d5
145214 --- /dev/null
145215 +++ b/include/linux/fsl_qman.h
145216 @@ -0,0 +1,3888 @@
145217 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
145218 + *
145219 + * Redistribution and use in source and binary forms, with or without
145220 + * modification, are permitted provided that the following conditions are met:
145221 + * * Redistributions of source code must retain the above copyright
145222 + * notice, this list of conditions and the following disclaimer.
145223 + * * Redistributions in binary form must reproduce the above copyright
145224 + * notice, this list of conditions and the following disclaimer in the
145225 + * documentation and/or other materials provided with the distribution.
145226 + * * Neither the name of Freescale Semiconductor nor the
145227 + * names of its contributors may be used to endorse or promote products
145228 + * derived from this software without specific prior written permission.
145229 + *
145230 + *
145231 + * ALTERNATIVELY, this software may be distributed under the terms of the
145232 + * GNU General Public License ("GPL") as published by the Free Software
145233 + * Foundation, either version 2 of that License or (at your option) any
145234 + * later version.
145235 + *
145236 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145237 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145238 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145239 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145240 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145241 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145242 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145243 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145244 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145245 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145246 + */
145247 +
145248 +#ifndef FSL_QMAN_H
145249 +#define FSL_QMAN_H
145250 +
145251 +#ifdef __cplusplus
145252 +extern "C" {
145253 +#endif
145254 +
145255 +/* Last updated for v00.800 of the BG */
145256 +
145257 +/* Hardware constants */
145258 +#define QM_CHANNEL_SWPORTAL0 0
145259 +#define QMAN_CHANNEL_POOL1 0x21
145260 +#define QMAN_CHANNEL_CAAM 0x80
145261 +#define QMAN_CHANNEL_PME 0xa0
145262 +#define QMAN_CHANNEL_POOL1_REV3 0x401
145263 +#define QMAN_CHANNEL_CAAM_REV3 0x840
145264 +#define QMAN_CHANNEL_PME_REV3 0x860
145265 +#define QMAN_CHANNEL_DCE 0x8a0
145266 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
145267 +extern u16 qm_channel_pool1;
145268 +extern u16 qm_channel_caam;
145269 +extern u16 qm_channel_pme;
145270 +extern u16 qm_channel_dce;
145271 +enum qm_dc_portal {
145272 + qm_dc_portal_fman0 = 0,
145273 + qm_dc_portal_fman1 = 1,
145274 + qm_dc_portal_caam = 2,
145275 + qm_dc_portal_pme = 3,
145276 + qm_dc_portal_rman = 4,
145277 + qm_dc_portal_dce = 5
145278 +};
145279 +
145280 +/* Portal processing (interrupt) sources */
145281 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
145282 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
145283 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
145284 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
145285 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
145286 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
145287 +/* This mask contains all the interrupt sources that need handling except DQRI,
145288 + * ie. that if present should trigger slow-path processing. */
145289 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
145290 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
145291 +
145292 +/* --- Clock speed --- */
145293 +/* A qman driver instance may or may not know the current qman clock speed.
145294 + * However, certain CEETM calculations may not be possible if this is not known.
145295 + * The 'set' function will only succeed (return zero) if the driver did not
145296 + * already know the clock speed. Likewise, the 'get' function will only succeed
145297 + * if the driver does know the clock speed (either because it knew when booting,
145298 + * or was told via 'set'). In cases where software is running on a driver
145299 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
145300 + * and the user can obtain the current qman clock speed by other means (eg. from
145301 + * a message sent from the control-plane), then the 'set' function can be used
145302 + * to enable rate-calculations in a driver where it would otherwise not be
145303 + * possible. */
145304 +int qm_get_clock(u64 *clock_hz);
145305 +int qm_set_clock(u64 clock_hz);
145306 +
145307 +/* For qman_static_dequeue_*** APIs */
145308 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
145309 +/* for n in [1,15] */
145310 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
145311 +/* for conversion from n of qm_channel */
145312 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
145313 +{
145314 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
145315 +}
145316 +
145317 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
145318 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
145319 + * FQID(n) to fill in the frame queue ID. */
145320 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
145321 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
145322 +#define QM_VDQCR_EXACT 0x40000000
145323 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
145324 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
145325 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
145326 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
145327 +
145328 +
145329 +/* ------------------------------------------------------- */
145330 +/* --- Qman data structures (and associated constants) --- */
145331 +
145332 +/* Represents s/w corenet portal mapped data structures */
145333 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
145334 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
145335 +struct qm_mr_entry; /* MR (Message Ring) entries */
145336 +struct qm_mc_command; /* MC (Management Command) command */
145337 +struct qm_mc_result; /* MC result */
145338 +
145339 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
145340 +#define QM_FD_FORMAT_SG 0x4
145341 +#define QM_FD_FORMAT_LONG 0x2
145342 +#define QM_FD_FORMAT_COMPOUND 0x1
145343 +enum qm_fd_format {
145344 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
145345 + * scatter-gather table. 'big' implies a 29-bit length with no offset
145346 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
145347 + * implies a s/g-like table, where each entry itself represents a frame
145348 + * (contiguous or scatter-gather) and the 29-bit "length" is
145349 + * interpreted purely for congestion calculations, ie. a "congestion
145350 + * weight". */
145351 + qm_fd_contig = 0,
145352 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
145353 + qm_fd_sg = QM_FD_FORMAT_SG,
145354 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
145355 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
145356 +};
145357 +
145358 +/* Capitalised versions are un-typed but can be used in static expressions */
145359 +#define QM_FD_CONTIG 0
145360 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
145361 +#define QM_FD_SG QM_FD_FORMAT_SG
145362 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
145363 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
145364 +
145365 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
145366 +struct qm_fd {
145367 + union {
145368 + struct {
145369 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145370 + u8 dd:2; /* dynamic debug */
145371 + u8 liodn_offset:6;
145372 + u8 bpid:8; /* Buffer Pool ID */
145373 + u8 eliodn_offset:4;
145374 + u8 __reserved:4;
145375 + u8 addr_hi; /* high 8-bits of 40-bit address */
145376 + u32 addr_lo; /* low 32-bits of 40-bit address */
145377 +#else
145378 + u32 addr_lo; /* low 32-bits of 40-bit address */
145379 + u8 addr_hi; /* high 8-bits of 40-bit address */
145380 + u8 __reserved:4;
145381 + u8 eliodn_offset:4;
145382 + u8 bpid:8; /* Buffer Pool ID */
145383 + u8 liodn_offset:6;
145384 + u8 dd:2; /* dynamic debug */
145385 +#endif
145386 + };
145387 + struct {
145388 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145389 + u64 __notaddress:24;
145390 + u64 addr:40;
145391 +#else
145392 + u64 addr:40;
145393 + u64 __notaddress:24;
145394 +#endif
145395 + };
145396 + u64 opaque_addr;
145397 + };
145398 + /* The 'format' field indicates the interpretation of the remaining 29
145399 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
145400 + * other union elements. Note, union'd structs are difficult to use with
145401 + * static initialisation under gcc, in which case use the "opaque" form
145402 + * with one of the macros. */
145403 + union {
145404 + /* For easier/faster copying of this part of the fd (eg. from a
145405 + * DQRR entry to an EQCR entry) copy 'opaque' */
145406 + u32 opaque;
145407 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
145408 + struct {
145409 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145410 + enum qm_fd_format format:3;
145411 + u16 offset:9;
145412 + u32 length20:20;
145413 +#else
145414 + u32 length20:20;
145415 + u16 offset:9;
145416 + enum qm_fd_format format:3;
145417 +#endif
145418 + };
145419 + /* If 'format' is _contig_big or _sg_big, 29b length */
145420 + struct {
145421 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145422 + enum qm_fd_format _format1:3;
145423 + u32 length29:29;
145424 +#else
145425 + u32 length29:29;
145426 + enum qm_fd_format _format1:3;
145427 +#endif
145428 + };
145429 + /* If 'format' is _compound, 29b "congestion weight" */
145430 + struct {
145431 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145432 + enum qm_fd_format _format2:3;
145433 + u32 cong_weight:29;
145434 +#else
145435 + u32 cong_weight:29;
145436 + enum qm_fd_format _format2:3;
145437 +#endif
145438 + };
145439 + };
145440 + union {
145441 + u32 cmd;
145442 + u32 status;
145443 + };
145444 +} __aligned(8);
145445 +#define QM_FD_DD_NULL 0x00
145446 +#define QM_FD_PID_MASK 0x3f
145447 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
145448 +{
145449 + return fd->addr;
145450 +}
145451 +
145452 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
145453 +{
145454 + return (dma_addr_t)fd->addr;
145455 +}
145456 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145457 +#define qm_fd_addr_set64(fd, v) \
145458 + do { \
145459 + struct qm_fd *__fd931 = (fd); \
145460 + __fd931->addr = v; \
145461 + } while (0)
145462 +
145463 +/* For static initialisation of FDs (which is complicated by the use of unions
145464 + * in "struct qm_fd"), use the following macros. Note that;
145465 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
145466 + * use-case),
145467 + * - use capitalised QM_FD_*** formats for static initialisation.
145468 + */
145469 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
145470 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145471 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
145472 + { cmd } }
145473 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
145474 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145475 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
145476 + { cmd } }
145477 +
145478 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
145479 +#define QM_SG_OFFSET_MASK 0x1FFF
145480 +struct qm_sg_entry {
145481 + union {
145482 + struct {
145483 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145484 + u8 __reserved1[3];
145485 + u8 addr_hi; /* high 8-bits of 40-bit address */
145486 + u32 addr_lo; /* low 32-bits of 40-bit address */
145487 +#else
145488 + u32 addr_lo; /* low 32-bits of 40-bit address */
145489 + u8 addr_hi; /* high 8-bits of 40-bit address */
145490 + u8 __reserved1[3];
145491 +#endif
145492 + };
145493 + struct {
145494 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145495 + u64 __notaddress:24;
145496 + u64 addr:40;
145497 +#else
145498 + u64 addr:40;
145499 + u64 __notaddress:24;
145500 +#endif
145501 + };
145502 + u64 opaque;
145503 + };
145504 + union {
145505 + struct {
145506 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145507 + u32 extension:1; /* Extension bit */
145508 + u32 final:1; /* Final bit */
145509 + u32 length:30;
145510 +#else
145511 + u32 length:30;
145512 + u32 final:1; /* Final bit */
145513 + u32 extension:1; /* Extension bit */
145514 +#endif
145515 + };
145516 + u32 sgt_efl;
145517 + };
145518 + u8 __reserved2;
145519 + u8 bpid;
145520 + union {
145521 + struct {
145522 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145523 + u16 __reserved3:3;
145524 + u16 offset:13;
145525 +#else
145526 + u16 offset:13;
145527 + u16 __reserved3:3;
145528 +#endif
145529 + };
145530 + u16 opaque_offset;
145531 + };
145532 +} __packed;
145533 +union qm_sg_efl {
145534 + struct {
145535 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145536 + u32 extension:1; /* Extension bit */
145537 + u32 final:1; /* Final bit */
145538 + u32 length:30;
145539 +#else
145540 + u32 length:30;
145541 + u32 final:1; /* Final bit */
145542 + u32 extension:1; /* Extension bit */
145543 +#endif
145544 + };
145545 + u32 efl;
145546 +};
145547 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
145548 +{
145549 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
145550 +}
145551 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
145552 +{
145553 + union qm_sg_efl u;
145554 +
145555 + u.efl = be32_to_cpu(sg->sgt_efl);
145556 + return u.extension;
145557 +}
145558 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
145559 +{
145560 + union qm_sg_efl u;
145561 +
145562 + u.efl = be32_to_cpu(sg->sgt_efl);
145563 + return u.final;
145564 +}
145565 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
145566 +{
145567 + union qm_sg_efl u;
145568 +
145569 + u.efl = be32_to_cpu(sg->sgt_efl);
145570 + return u.length;
145571 +}
145572 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
145573 +{
145574 + return sg->bpid;
145575 +}
145576 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
145577 +{
145578 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
145579 +
145580 + return opaque_offset & 0x1fff;
145581 +}
145582 +
145583 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145584 +#define qm_sg_entry_set64(sg, v) \
145585 + do { \
145586 + struct qm_sg_entry *__sg931 = (sg); \
145587 + __sg931->opaque = cpu_to_be64(v); \
145588 + } while (0)
145589 +#define qm_sg_entry_set_ext(sg, v) \
145590 + do { \
145591 + union qm_sg_efl __u932; \
145592 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
145593 + __u932.extension = v; \
145594 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
145595 + } while (0)
145596 +#define qm_sg_entry_set_final(sg, v) \
145597 + do { \
145598 + union qm_sg_efl __u933; \
145599 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
145600 + __u933.final = v; \
145601 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
145602 + } while (0)
145603 +#define qm_sg_entry_set_len(sg, v) \
145604 + do { \
145605 + union qm_sg_efl __u934; \
145606 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
145607 + __u934.length = v; \
145608 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
145609 + } while (0)
145610 +#define qm_sg_entry_set_bpid(sg, v) \
145611 + do { \
145612 + struct qm_sg_entry *__u935 = (sg); \
145613 + __u935->bpid = v; \
145614 + } while (0)
145615 +#define qm_sg_entry_set_offset(sg, v) \
145616 + do { \
145617 + struct qm_sg_entry *__u936 = (sg); \
145618 + __u936->opaque_offset = cpu_to_be16(v); \
145619 + } while (0)
145620 +
145621 +/* See 1.5.8.1: "Enqueue Command" */
145622 +struct qm_eqcr_entry {
145623 + u8 __dont_write_directly__verb;
145624 + u8 dca;
145625 + u16 seqnum;
145626 + u32 orp; /* 24-bit */
145627 + u32 fqid; /* 24-bit */
145628 + u32 tag;
145629 + struct qm_fd fd;
145630 + u8 __reserved3[32];
145631 +} __packed;
145632 +#define QM_EQCR_VERB_VBIT 0x80
145633 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
145634 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
145635 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
145636 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
145637 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
145638 +#define QM_EQCR_VERB_COLOUR_RED 0x10
145639 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
145640 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
145641 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
145642 +#define QM_EQCR_DCA_ENABLE 0x80
145643 +#define QM_EQCR_DCA_PARK 0x40
145644 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
145645 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
145646 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
145647 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
145648 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
145649 +
145650 +/* See 1.5.8.2: "Frame Dequeue Response" */
145651 +struct qm_dqrr_entry {
145652 + u8 verb;
145653 + u8 stat;
145654 + u16 seqnum; /* 15-bit */
145655 + u8 tok;
145656 + u8 __reserved2[3];
145657 + u32 fqid; /* 24-bit */
145658 + u32 contextB;
145659 + struct qm_fd fd;
145660 + u8 __reserved4[32];
145661 +};
145662 +#define QM_DQRR_VERB_VBIT 0x80
145663 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
145664 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
145665 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
145666 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
145667 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
145668 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
145669 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
145670 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
145671 +
145672 +/* See 1.5.8.3: "ERN Message Response" */
145673 +/* See 1.5.8.4: "FQ State Change Notification" */
145674 +struct qm_mr_entry {
145675 + u8 verb;
145676 + union {
145677 + struct {
145678 + u8 dca;
145679 + u16 seqnum;
145680 + u8 rc; /* Rejection Code */
145681 + u32 orp:24;
145682 + u32 fqid; /* 24-bit */
145683 + u32 tag;
145684 + struct qm_fd fd;
145685 + } __packed ern;
145686 + struct {
145687 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145688 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145689 + u8 __reserved1:3;
145690 + enum qm_dc_portal portal:3;
145691 +#else
145692 + enum qm_dc_portal portal:3;
145693 + u8 __reserved1:3;
145694 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145695 +#endif
145696 + u16 __reserved2;
145697 + u8 rc; /* Rejection Code */
145698 + u32 __reserved3:24;
145699 + u32 fqid; /* 24-bit */
145700 + u32 tag;
145701 + struct qm_fd fd;
145702 + } __packed dcern;
145703 + struct {
145704 + u8 fqs; /* Frame Queue Status */
145705 + u8 __reserved1[6];
145706 + u32 fqid; /* 24-bit */
145707 + u32 contextB;
145708 + u8 __reserved2[16];
145709 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
145710 + };
145711 + u8 __reserved2[32];
145712 +} __packed;
145713 +#define QM_MR_VERB_VBIT 0x80
145714 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
145715 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
145716 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
145717 + * the other MR types by noting if the 0x20 bit is unset. */
145718 +#define QM_MR_VERB_TYPE_MASK 0x27
145719 +#define QM_MR_VERB_DC_ERN 0x20
145720 +#define QM_MR_VERB_FQRN 0x21
145721 +#define QM_MR_VERB_FQRNI 0x22
145722 +#define QM_MR_VERB_FQRL 0x23
145723 +#define QM_MR_VERB_FQPN 0x24
145724 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
145725 +#define QM_MR_RC_CGR_TAILDROP 0x00
145726 +#define QM_MR_RC_WRED 0x10
145727 +#define QM_MR_RC_ERROR 0x20
145728 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
145729 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
145730 +#define QM_MR_RC_FQ_TAILDROP 0x50
145731 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
145732 +#define QM_MR_RC_ORP_ZERO 0x70
145733 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
145734 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
145735 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
145736 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
145737 +#define QM_MR_DCERN_COLOUR_RED 0x02
145738 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145739 +
145740 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145741 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145742 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145743 + * latter has two inlines to assist with converting to/from the mant+exp
145744 + * representation. */
145745 +struct qm_fqd_stashing {
145746 + /* See QM_STASHING_EXCL_<...> */
145747 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145748 + u8 exclusive;
145749 + u8 __reserved1:2;
145750 + /* Numbers of cachelines */
145751 + u8 annotation_cl:2;
145752 + u8 data_cl:2;
145753 + u8 context_cl:2;
145754 +#else
145755 + u8 context_cl:2;
145756 + u8 data_cl:2;
145757 + u8 annotation_cl:2;
145758 + u8 __reserved1:2;
145759 + u8 exclusive;
145760 +#endif
145761 +} __packed;
145762 +struct qm_fqd_taildrop {
145763 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145764 + u16 __reserved1:3;
145765 + u16 mant:8;
145766 + u16 exp:5;
145767 +#else
145768 + u16 exp:5;
145769 + u16 mant:8;
145770 + u16 __reserved1:3;
145771 +#endif
145772 +} __packed;
145773 +struct qm_fqd_oac {
145774 + /* See QM_OAC_<...> */
145775 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145776 + u8 oac:2; /* "Overhead Accounting Control" */
145777 + u8 __reserved1:6;
145778 +#else
145779 + u8 __reserved1:6;
145780 + u8 oac:2; /* "Overhead Accounting Control" */
145781 +#endif
145782 + /* Two's-complement value (-128 to +127) */
145783 + signed char oal; /* "Overhead Accounting Length" */
145784 +} __packed;
145785 +struct qm_fqd {
145786 + union {
145787 + u8 orpc;
145788 + struct {
145789 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145790 + u8 __reserved1:2;
145791 + u8 orprws:3;
145792 + u8 oa:1;
145793 + u8 olws:2;
145794 +#else
145795 + u8 olws:2;
145796 + u8 oa:1;
145797 + u8 orprws:3;
145798 + u8 __reserved1:2;
145799 +#endif
145800 + } __packed;
145801 + };
145802 + u8 cgid;
145803 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
145804 + union {
145805 + u16 dest_wq;
145806 + struct {
145807 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145808 + u16 channel:13; /* qm_channel */
145809 + u16 wq:3;
145810 +#else
145811 + u16 wq:3;
145812 + u16 channel:13; /* qm_channel */
145813 +#endif
145814 + } __packed dest;
145815 + };
145816 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145817 + u16 __reserved2:1;
145818 + u16 ics_cred:15;
145819 +#else
145820 + u16 __reserved2:1;
145821 + u16 ics_cred:15;
145822 +#endif
145823 + /* For "Initialize Frame Queue" commands, the write-enable mask
145824 + * determines whether 'td' or 'oac_init' is observed. For query
145825 + * commands, this field is always 'td', and 'oac_query' (below) reflects
145826 + * the Overhead ACcounting values. */
145827 + union {
145828 + struct qm_fqd_taildrop td;
145829 + struct qm_fqd_oac oac_init;
145830 + };
145831 + u32 context_b;
145832 + union {
145833 + /* Treat it as 64-bit opaque */
145834 + u64 opaque;
145835 + struct {
145836 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145837 + u32 hi;
145838 + u32 lo;
145839 +#else
145840 + u32 lo;
145841 + u32 hi;
145842 +#endif
145843 + };
145844 + /* Treat it as s/w portal stashing config */
145845 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145846 + struct {
145847 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145848 + struct qm_fqd_stashing stashing;
145849 + /* 48-bit address of FQ context to
145850 + * stash, must be cacheline-aligned */
145851 + u16 context_hi;
145852 + u32 context_lo;
145853 +#else
145854 + u32 context_lo;
145855 + u16 context_hi;
145856 + struct qm_fqd_stashing stashing;
145857 +#endif
145858 + } __packed;
145859 + } context_a;
145860 + struct qm_fqd_oac oac_query;
145861 +} __packed;
145862 +/* 64-bit converters for context_hi/lo */
145863 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
145864 +{
145865 + return ((u64)fqd->context_a.context_hi << 32) |
145866 + (u64)fqd->context_a.context_lo;
145867 +}
145868 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
145869 +{
145870 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
145871 +}
145872 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
145873 +{
145874 + return ((u64)fqd->context_a.hi << 32) |
145875 + (u64)fqd->context_a.lo;
145876 +}
145877 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
145878 +#define qm_fqd_stashing_set64(fqd, v) \
145879 + do { \
145880 + struct qm_fqd *__fqd931 = (fqd); \
145881 + __fqd931->context_a.context_hi = upper_32_bits(v); \
145882 + __fqd931->context_a.context_lo = lower_32_bits(v); \
145883 + } while (0)
145884 +#define qm_fqd_context_a_set64(fqd, v) \
145885 + do { \
145886 + struct qm_fqd *__fqd931 = (fqd); \
145887 + __fqd931->context_a.hi = upper_32_bits(v); \
145888 + __fqd931->context_a.lo = lower_32_bits(v); \
145889 + } while (0)
145890 +/* convert a threshold value into mant+exp representation */
145891 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
145892 + int roundup)
145893 +{
145894 + u32 e = 0;
145895 + int oddbit = 0;
145896 + if (val > 0xe0000000)
145897 + return -ERANGE;
145898 + while (val > 0xff) {
145899 + oddbit = val & 1;
145900 + val >>= 1;
145901 + e++;
145902 + if (roundup && oddbit)
145903 + val++;
145904 + }
145905 + td->exp = e;
145906 + td->mant = val;
145907 + return 0;
145908 +}
145909 +/* and the other direction */
145910 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
145911 +{
145912 + return (u32)td->mant << td->exp;
145913 +}
145914 +
145915 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
145916 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
145917 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
145918 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
145919 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
145920 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
145921 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
145922 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
145923 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
145924 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
145925 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
145926 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
145927 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
145928 +
145929 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145930 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
145931 +#define QM_STASHING_EXCL_ANNOTATION 0x04
145932 +#define QM_STASHING_EXCL_DATA 0x02
145933 +#define QM_STASHING_EXCL_CTX 0x01
145934 +
145935 +/* See 1.5.5.3: "Intra Class Scheduling" */
145936 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
145937 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
145938 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
145939 +
145940 +/* See 1.5.8.4: "FQ State Change Notification" */
145941 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
145942 + * and associated commands/responses. The WRED parameters are calculated from
145943 + * these fields as follows;
145944 + * MaxTH = MA * (2 ^ Mn)
145945 + * Slope = SA / (2 ^ Sn)
145946 + * MaxP = 4 * (Pn + 1)
145947 + */
145948 +struct qm_cgr_wr_parm {
145949 + union {
145950 + u32 word;
145951 + struct {
145952 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145953 + u32 MA:8;
145954 + u32 Mn:5;
145955 + u32 SA:7; /* must be between 64-127 */
145956 + u32 Sn:6;
145957 + u32 Pn:6;
145958 +#else
145959 + u32 Pn:6;
145960 + u32 Sn:6;
145961 + u32 SA:7; /* must be between 64-127 */
145962 + u32 Mn:5;
145963 + u32 MA:8;
145964 +#endif
145965 + } __packed;
145966 + };
145967 +} __packed;
145968 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
145969 + * management commands, this is padded to a 16-bit structure field, so that's
145970 + * how we represent it here. The congestion state threshold is calculated from
145971 + * these fields as follows;
145972 + * CS threshold = TA * (2 ^ Tn)
145973 + */
145974 +struct qm_cgr_cs_thres {
145975 + union {
145976 + u16 hword;
145977 + struct {
145978 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145979 + u16 __reserved:3;
145980 + u16 TA:8;
145981 + u16 Tn:5;
145982 +#else
145983 + u16 Tn:5;
145984 + u16 TA:8;
145985 + u16 __reserved:3;
145986 +#endif
145987 + } __packed;
145988 + };
145989 +} __packed;
145990 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
145991 + * commands and the "Query CGR" result. It's suctioned out here into its own
145992 + * struct. */
145993 +struct __qm_mc_cgr {
145994 + struct qm_cgr_wr_parm wr_parm_g;
145995 + struct qm_cgr_wr_parm wr_parm_y;
145996 + struct qm_cgr_wr_parm wr_parm_r;
145997 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
145998 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
145999 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
146000 + u8 cscn_en; /* boolean, use QM_CGR_EN */
146001 + union {
146002 + struct {
146003 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146004 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
146005 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
146006 +#else
146007 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
146008 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
146009 +#endif
146010 + };
146011 + u32 cscn_targ; /* use QM_CGR_TARG_* */
146012 + };
146013 + u8 cstd_en; /* boolean, use QM_CGR_EN */
146014 + u8 cs; /* boolean, only used in query response */
146015 + union {
146016 + /* use qm_cgr_cs_thres_set64() */
146017 + struct qm_cgr_cs_thres cs_thres;
146018 + u16 __cs_thres;
146019 + };
146020 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
146021 +} __packed;
146022 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
146023 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
146024 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
146025 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
146026 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
146027 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
146028 +/* Convert CGR thresholds to/from "cs_thres" format */
146029 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
146030 +{
146031 + return (u64)th->TA << th->Tn;
146032 +}
146033 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
146034 + int roundup)
146035 +{
146036 + u32 e = 0;
146037 + int oddbit = 0;
146038 + while (val > 0xff) {
146039 + oddbit = val & 1;
146040 + val >>= 1;
146041 + e++;
146042 + if (roundup && oddbit)
146043 + val++;
146044 + }
146045 + th->Tn = e;
146046 + th->TA = val;
146047 + return 0;
146048 +}
146049 +
146050 +/* See 1.5.8.5.1: "Initialize FQ" */
146051 +/* See 1.5.8.5.2: "Query FQ" */
146052 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146053 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146054 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146055 +/* See 1.5.8.6.2: "CGR Test Write" */
146056 +/* See 1.5.8.6.3: "Query CGR" */
146057 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146058 +struct qm_mcc_initfq {
146059 + u8 __reserved1;
146060 + u16 we_mask; /* Write Enable Mask */
146061 + u32 fqid; /* 24-bit */
146062 + u16 count; /* Initialises 'count+1' FQDs */
146063 + struct qm_fqd fqd; /* the FQD fields go here */
146064 + u8 __reserved3[30];
146065 +} __packed;
146066 +struct qm_mcc_queryfq {
146067 + u8 __reserved1[3];
146068 + u32 fqid; /* 24-bit */
146069 + u8 __reserved2[56];
146070 +} __packed;
146071 +struct qm_mcc_queryfq_np {
146072 + u8 __reserved1[3];
146073 + u32 fqid; /* 24-bit */
146074 + u8 __reserved2[56];
146075 +} __packed;
146076 +struct qm_mcc_alterfq {
146077 + u8 __reserved1[3];
146078 + u32 fqid; /* 24-bit */
146079 + u8 __reserved2;
146080 + u8 count; /* number of consecutive FQID */
146081 + u8 __reserved3[10];
146082 + u32 context_b; /* frame queue context b */
146083 + u8 __reserved4[40];
146084 +} __packed;
146085 +struct qm_mcc_initcgr {
146086 + u8 __reserved1;
146087 + u16 we_mask; /* Write Enable Mask */
146088 + struct __qm_mc_cgr cgr; /* CGR fields */
146089 + u8 __reserved2[2];
146090 + u8 cgid;
146091 + u8 __reserved4[32];
146092 +} __packed;
146093 +struct qm_mcc_cgrtestwrite {
146094 + u8 __reserved1[2];
146095 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146096 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146097 + u8 __reserved2[23];
146098 + u8 cgid;
146099 + u8 __reserved3[32];
146100 +} __packed;
146101 +struct qm_mcc_querycgr {
146102 + u8 __reserved1[30];
146103 + u8 cgid;
146104 + u8 __reserved2[32];
146105 +} __packed;
146106 +struct qm_mcc_querycongestion {
146107 + u8 __reserved[63];
146108 +} __packed;
146109 +struct qm_mcc_querywq {
146110 + u8 __reserved;
146111 + /* select channel if verb != QUERYWQ_DEDICATED */
146112 + union {
146113 + u16 channel_wq; /* ignores wq (3 lsbits) */
146114 + struct {
146115 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146116 + u16 id:13; /* qm_channel */
146117 + u16 __reserved1:3;
146118 +#else
146119 + u16 __reserved1:3;
146120 + u16 id:13; /* qm_channel */
146121 +#endif
146122 + } __packed channel;
146123 + };
146124 + u8 __reserved2[60];
146125 +} __packed;
146126 +
146127 +struct qm_mcc_ceetm_lfqmt_config {
146128 + u8 __reserved1[4];
146129 + u32 lfqid:24;
146130 + u8 __reserved2[2];
146131 + u16 cqid;
146132 + u8 __reserved3[2];
146133 + u16 dctidx;
146134 + u8 __reserved4[48];
146135 +} __packed;
146136 +
146137 +struct qm_mcc_ceetm_lfqmt_query {
146138 + u8 __reserved1[4];
146139 + u32 lfqid:24;
146140 + u8 __reserved2[56];
146141 +} __packed;
146142 +
146143 +struct qm_mcc_ceetm_cq_config {
146144 + u8 __reserved1;
146145 + u16 cqid;
146146 + u8 dcpid;
146147 + u8 __reserved2;
146148 + u16 ccgid;
146149 + u8 __reserved3[56];
146150 +} __packed;
146151 +
146152 +struct qm_mcc_ceetm_cq_query {
146153 + u8 __reserved1;
146154 + u16 cqid;
146155 + u8 dcpid;
146156 + u8 __reserved2[59];
146157 +} __packed;
146158 +
146159 +struct qm_mcc_ceetm_dct_config {
146160 + u8 __reserved1;
146161 + u16 dctidx;
146162 + u8 dcpid;
146163 + u8 __reserved2[15];
146164 + u32 context_b;
146165 + u64 context_a;
146166 + u8 __reserved3[32];
146167 +} __packed;
146168 +
146169 +struct qm_mcc_ceetm_dct_query {
146170 + u8 __reserved1;
146171 + u16 dctidx;
146172 + u8 dcpid;
146173 + u8 __reserved2[59];
146174 +} __packed;
146175 +
146176 +struct qm_mcc_ceetm_class_scheduler_config {
146177 + u8 __reserved1;
146178 + u16 cqcid;
146179 + u8 dcpid;
146180 + u8 __reserved2[6];
146181 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146182 + u8 gpc_reserved:1;
146183 + u8 gpc_combine_flag:1;
146184 + u8 gpc_prio_b:3;
146185 + u8 gpc_prio_a:3;
146186 +#else
146187 + u8 gpc_prio_a:3;
146188 + u8 gpc_prio_b:3;
146189 + u8 gpc_combine_flag:1;
146190 + u8 gpc_reserved:1;
146191 +#endif
146192 + u16 crem;
146193 + u16 erem;
146194 + u8 w[8];
146195 + u8 __reserved3[40];
146196 +} __packed;
146197 +
146198 +struct qm_mcc_ceetm_class_scheduler_query {
146199 + u8 __reserved1;
146200 + u16 cqcid;
146201 + u8 dcpid;
146202 + u8 __reserved2[59];
146203 +} __packed;
146204 +
146205 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
146206 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
146207 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
146208 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
146209 +#define CEETM_COMMAND_TCFC (4 << 12)
146210 +
146211 +#define CEETM_CCGRID_MASK 0x01FF
146212 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
146213 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
146214 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
146215 +#define CEETM_CCGR_CM_QUERY (0 << 14)
146216 +#define CEETM_CCGR_DN_QUERY (1 << 14)
146217 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
146218 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
146219 +
146220 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
146221 + u8 __reserved1;
146222 + u16 cid;
146223 + u8 dcpid;
146224 + union {
146225 + struct {
146226 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146227 + u8 map_shaped:1;
146228 + u8 map_reserved:4;
146229 + u8 map_lni_id:3;
146230 +#else
146231 + u8 map_lni_id:3;
146232 + u8 map_reserved:4;
146233 + u8 map_shaped:1;
146234 +#endif
146235 + u8 __reserved2[58];
146236 + } __packed channel_mapping;
146237 + struct {
146238 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146239 + u8 map_reserved:5;
146240 + u8 map_lni_id:3;
146241 +#else
146242 + u8 map_lni_id:3;
146243 + u8 map_reserved:5;
146244 +#endif
146245 + u8 __reserved2[58];
146246 + } __packed sp_mapping;
146247 + struct {
146248 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146249 + u8 cpl:1;
146250 + u8 cpl_reserved:2;
146251 + u8 oal:5;
146252 +#else
146253 + u8 oal:5;
146254 + u8 cpl_reserved:2;
146255 + u8 cpl:1;
146256 +#endif
146257 + u32 crtcr:24;
146258 + u32 ertcr:24;
146259 + u16 crtbl;
146260 + u16 ertbl;
146261 + u8 mps; /* This will be hardcoded by driver with 60 */
146262 + u8 __reserved2[47];
146263 + } __packed shaper_config;
146264 + struct {
146265 + u8 __reserved2[11];
146266 + u64 lnitcfcc;
146267 + u8 __reserved3[40];
146268 + } __packed tcfc_config;
146269 + };
146270 +} __packed;
146271 +
146272 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
146273 + u8 __reserved1;
146274 + u16 cid;
146275 + u8 dcpid;
146276 + u8 __reserved2[59];
146277 +} __packed;
146278 +
146279 +struct qm_mcc_ceetm_ccgr_config {
146280 + u8 __reserved1;
146281 + u16 ccgrid;
146282 + u8 dcpid;
146283 + u8 __reserved2;
146284 + u16 we_mask;
146285 + union {
146286 + struct {
146287 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146288 + u8 ctl_reserved:1;
146289 + u8 ctl_wr_en_g:1;
146290 + u8 ctl_wr_en_y:1;
146291 + u8 ctl_wr_en_r:1;
146292 + u8 ctl_td_en:1;
146293 + u8 ctl_td_mode:1;
146294 + u8 ctl_cscn_en:1;
146295 + u8 ctl_mode:1;
146296 +#else
146297 + u8 ctl_mode:1;
146298 + u8 ctl_cscn_en:1;
146299 + u8 ctl_td_mode:1;
146300 + u8 ctl_td_en:1;
146301 + u8 ctl_wr_en_r:1;
146302 + u8 ctl_wr_en_y:1;
146303 + u8 ctl_wr_en_g:1;
146304 + u8 ctl_reserved:1;
146305 +#endif
146306 + u8 cdv;
146307 + u16 cscn_tupd;
146308 + u8 oal;
146309 + u8 __reserved3;
146310 + struct qm_cgr_cs_thres cs_thres;
146311 + struct qm_cgr_cs_thres cs_thres_x;
146312 + struct qm_cgr_cs_thres td_thres;
146313 + struct qm_cgr_wr_parm wr_parm_g;
146314 + struct qm_cgr_wr_parm wr_parm_y;
146315 + struct qm_cgr_wr_parm wr_parm_r;
146316 + } __packed cm_config;
146317 + struct {
146318 + u8 dnc;
146319 + u8 dn0;
146320 + u8 dn1;
146321 + u64 dnba:40;
146322 + u8 __reserved3[2];
146323 + u16 dnth_0;
146324 + u8 __reserved4[2];
146325 + u16 dnth_1;
146326 + u8 __reserved5[8];
146327 + } __packed dn_config;
146328 + struct {
146329 + u8 __reserved3[3];
146330 + u64 i_cnt:40;
146331 + u8 __reserved4[16];
146332 + } __packed test_write;
146333 + };
146334 + u8 __reserved5[32];
146335 +} __packed;
146336 +
146337 +struct qm_mcc_ceetm_ccgr_query {
146338 + u8 __reserved1;
146339 + u16 ccgrid;
146340 + u8 dcpid;
146341 + u8 __reserved2[59];
146342 +} __packed;
146343 +
146344 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
146345 + u8 __reserved1;
146346 + u16 cqid;
146347 + u8 dcpid;
146348 + u8 ct;
146349 + u16 xsfdr;
146350 + u8 __reserved2[56];
146351 +} __packed;
146352 +
146353 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
146354 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
146355 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
146356 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
146357 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
146358 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
146359 +struct qm_mcc_ceetm_statistics_query_write {
146360 + u8 __reserved1;
146361 + u16 cid;
146362 + u8 dcpid;
146363 + u8 ct;
146364 + u8 __reserved2[13];
146365 + u64 frm_cnt:40;
146366 + u8 __reserved3[2];
146367 + u64 byte_cnt:48;
146368 + u8 __reserved[32];
146369 +} __packed;
146370 +
146371 +struct qm_mc_command {
146372 + u8 __dont_write_directly__verb;
146373 + union {
146374 + struct qm_mcc_initfq initfq;
146375 + struct qm_mcc_queryfq queryfq;
146376 + struct qm_mcc_queryfq_np queryfq_np;
146377 + struct qm_mcc_alterfq alterfq;
146378 + struct qm_mcc_initcgr initcgr;
146379 + struct qm_mcc_cgrtestwrite cgrtestwrite;
146380 + struct qm_mcc_querycgr querycgr;
146381 + struct qm_mcc_querycongestion querycongestion;
146382 + struct qm_mcc_querywq querywq;
146383 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
146384 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
146385 + struct qm_mcc_ceetm_cq_config cq_config;
146386 + struct qm_mcc_ceetm_cq_query cq_query;
146387 + struct qm_mcc_ceetm_dct_config dct_config;
146388 + struct qm_mcc_ceetm_dct_query dct_query;
146389 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
146390 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
146391 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
146392 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
146393 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
146394 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
146395 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146396 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
146397 + };
146398 +} __packed;
146399 +#define QM_MCC_VERB_VBIT 0x80
146400 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
146401 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
146402 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
146403 +#define QM_MCC_VERB_QUERYFQ 0x44
146404 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
146405 +#define QM_MCC_VERB_QUERYWQ 0x46
146406 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
146407 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
146408 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
146409 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
146410 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
146411 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
146412 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
146413 +#define QM_MCC_VERB_INITCGR 0x50
146414 +#define QM_MCC_VERB_MODIFYCGR 0x51
146415 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
146416 +#define QM_MCC_VERB_QUERYCGR 0x58
146417 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
146418 +/* INITFQ-specific flags */
146419 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
146420 +#define QM_INITFQ_WE_OAC 0x0100
146421 +#define QM_INITFQ_WE_ORPC 0x0080
146422 +#define QM_INITFQ_WE_CGID 0x0040
146423 +#define QM_INITFQ_WE_FQCTRL 0x0020
146424 +#define QM_INITFQ_WE_DESTWQ 0x0010
146425 +#define QM_INITFQ_WE_ICSCRED 0x0008
146426 +#define QM_INITFQ_WE_TDTHRESH 0x0004
146427 +#define QM_INITFQ_WE_CONTEXTB 0x0002
146428 +#define QM_INITFQ_WE_CONTEXTA 0x0001
146429 +/* INITCGR/MODIFYCGR-specific flags */
146430 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
146431 +#define QM_CGR_WE_WR_PARM_G 0x0400
146432 +#define QM_CGR_WE_WR_PARM_Y 0x0200
146433 +#define QM_CGR_WE_WR_PARM_R 0x0100
146434 +#define QM_CGR_WE_WR_EN_G 0x0080
146435 +#define QM_CGR_WE_WR_EN_Y 0x0040
146436 +#define QM_CGR_WE_WR_EN_R 0x0020
146437 +#define QM_CGR_WE_CSCN_EN 0x0010
146438 +#define QM_CGR_WE_CSCN_TARG 0x0008
146439 +#define QM_CGR_WE_CSTD_EN 0x0004
146440 +#define QM_CGR_WE_CS_THRES 0x0002
146441 +#define QM_CGR_WE_MODE 0x0001
146442 +
146443 +/* See 1.5.9.7 CEETM Management Commands */
146444 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
146445 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
146446 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
146447 +#define QM_CEETM_VERB_CQ_QUERY 0x73
146448 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
146449 +#define QM_CEETM_VERB_DCT_QUERY 0x75
146450 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
146451 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
146452 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
146453 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
146454 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
146455 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
146456 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
146457 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
146458 +
146459 +/* See 1.5.8.5.1: "Initialize FQ" */
146460 +/* See 1.5.8.5.2: "Query FQ" */
146461 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146462 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146463 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146464 +/* See 1.5.8.6.2: "CGR Test Write" */
146465 +/* See 1.5.8.6.3: "Query CGR" */
146466 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146467 +struct qm_mcr_initfq {
146468 + u8 __reserved1[62];
146469 +} __packed;
146470 +struct qm_mcr_queryfq {
146471 + u8 __reserved1[8];
146472 + struct qm_fqd fqd; /* the FQD fields are here */
146473 + u8 __reserved2[30];
146474 +} __packed;
146475 +struct qm_mcr_queryfq_np {
146476 + u8 __reserved1;
146477 + u8 state; /* QM_MCR_NP_STATE_*** */
146478 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146479 + u8 __reserved2;
146480 + u32 fqd_link:24;
146481 + u16 __reserved3:2;
146482 + u16 odp_seq:14;
146483 + u16 __reserved4:2;
146484 + u16 orp_nesn:14;
146485 + u16 __reserved5:1;
146486 + u16 orp_ea_hseq:15;
146487 + u16 __reserved6:1;
146488 + u16 orp_ea_tseq:15;
146489 + u8 __reserved7;
146490 + u32 orp_ea_hptr:24;
146491 + u8 __reserved8;
146492 + u32 orp_ea_tptr:24;
146493 + u8 __reserved9;
146494 + u32 pfdr_hptr:24;
146495 + u8 __reserved10;
146496 + u32 pfdr_tptr:24;
146497 + u8 __reserved11[5];
146498 + u8 __reserved12:7;
146499 + u8 is:1;
146500 + u16 ics_surp;
146501 + u32 byte_cnt;
146502 + u8 __reserved13;
146503 + u32 frm_cnt:24;
146504 + u32 __reserved14;
146505 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146506 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146507 + u16 __reserved15;
146508 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146509 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146510 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146511 +#else
146512 + u8 __reserved2;
146513 + u32 fqd_link:24;
146514 +
146515 + u16 odp_seq:14;
146516 + u16 __reserved3:2;
146517 +
146518 + u16 orp_nesn:14;
146519 + u16 __reserved4:2;
146520 +
146521 + u16 orp_ea_hseq:15;
146522 + u16 __reserved5:1;
146523 +
146524 + u16 orp_ea_tseq:15;
146525 + u16 __reserved6:1;
146526 +
146527 + u8 __reserved7;
146528 + u32 orp_ea_hptr:24;
146529 +
146530 + u8 __reserved8;
146531 + u32 orp_ea_tptr:24;
146532 +
146533 + u8 __reserved9;
146534 + u32 pfdr_hptr:24;
146535 +
146536 + u8 __reserved10;
146537 + u32 pfdr_tptr:24;
146538 +
146539 + u8 __reserved11[5];
146540 + u8 is:1;
146541 + u8 __reserved12:7;
146542 + u16 ics_surp;
146543 + u32 byte_cnt;
146544 + u8 __reserved13;
146545 + u32 frm_cnt:24;
146546 + u32 __reserved14;
146547 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146548 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146549 + u16 __reserved15;
146550 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146551 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146552 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146553 +#endif
146554 +} __packed;
146555 +
146556 +
146557 +struct qm_mcr_alterfq {
146558 + u8 fqs; /* Frame Queue Status */
146559 + u8 __reserved1[61];
146560 +} __packed;
146561 +struct qm_mcr_initcgr {
146562 + u8 __reserved1[62];
146563 +} __packed;
146564 +struct qm_mcr_cgrtestwrite {
146565 + u16 __reserved1;
146566 + struct __qm_mc_cgr cgr; /* CGR fields */
146567 + u8 __reserved2[3];
146568 + u32 __reserved3:24;
146569 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146570 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146571 + u32 __reserved4:24;
146572 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146573 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146574 + u16 lgt; /* Last Group Tick */
146575 + u16 wr_prob_g;
146576 + u16 wr_prob_y;
146577 + u16 wr_prob_r;
146578 + u8 __reserved5[8];
146579 +} __packed;
146580 +struct qm_mcr_querycgr {
146581 + u16 __reserved1;
146582 + struct __qm_mc_cgr cgr; /* CGR fields */
146583 + u8 __reserved2[3];
146584 + union {
146585 + struct {
146586 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146587 + u32 __reserved3:24;
146588 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146589 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146590 +#else
146591 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146592 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146593 + u32 __reserved3:24;
146594 +#endif
146595 + };
146596 + u64 i_bcnt;
146597 + };
146598 + union {
146599 + struct {
146600 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146601 + u32 __reserved4:24;
146602 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146603 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146604 +#else
146605 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146606 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146607 + u32 __reserved4:24;
146608 +#endif
146609 + };
146610 + u64 a_bcnt;
146611 + };
146612 + union {
146613 + u32 cscn_targ_swp[4];
146614 + u8 __reserved5[16];
146615 + };
146616 +} __packed;
146617 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
146618 +{
146619 + return be64_to_cpu(q->i_bcnt);
146620 +}
146621 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
146622 +{
146623 + return be64_to_cpu(q->a_bcnt);
146624 +}
146625 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
146626 + const struct qm_mcr_cgrtestwrite *q)
146627 +{
146628 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
146629 +}
146630 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
146631 + const struct qm_mcr_cgrtestwrite *q)
146632 +{
146633 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
146634 +}
146635 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146636 +#define qm_mcr_querycgr_i_set64(q, v) \
146637 + do { \
146638 + struct qm_mcr_querycgr *__q931 = (fd); \
146639 + __q931->i_bcnt_hi = upper_32_bits(v); \
146640 + __q931->i_bcnt_lo = lower_32_bits(v); \
146641 + } while (0)
146642 +#define qm_mcr_querycgr_a_set64(q, v) \
146643 + do { \
146644 + struct qm_mcr_querycgr *__q931 = (fd); \
146645 + __q931->a_bcnt_hi = upper_32_bits(v); \
146646 + __q931->a_bcnt_lo = lower_32_bits(v); \
146647 + } while (0)
146648 +struct __qm_mcr_querycongestion {
146649 + u32 __state[8];
146650 +};
146651 +struct qm_mcr_querycongestion {
146652 + u8 __reserved[30];
146653 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
146654 + struct __qm_mcr_querycongestion state;
146655 +} __packed;
146656 +struct qm_mcr_querywq {
146657 + union {
146658 + u16 channel_wq; /* ignores wq (3 lsbits) */
146659 + struct {
146660 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146661 + u16 id:13; /* qm_channel */
146662 + u16 __reserved:3;
146663 +#else
146664 + u16 __reserved:3;
146665 + u16 id:13; /* qm_channel */
146666 +#endif
146667 + } __packed channel;
146668 + };
146669 + u8 __reserved[28];
146670 + u32 wq_len[8];
146671 +} __packed;
146672 +
146673 +/* QMAN CEETM Management Command Response */
146674 +struct qm_mcr_ceetm_lfqmt_config {
146675 + u8 __reserved1[62];
146676 +} __packed;
146677 +struct qm_mcr_ceetm_lfqmt_query {
146678 + u8 __reserved1[8];
146679 + u16 cqid;
146680 + u8 __reserved2[2];
146681 + u16 dctidx;
146682 + u8 __reserved3[2];
146683 + u16 ccgid;
146684 + u8 __reserved4[44];
146685 +} __packed;
146686 +
146687 +struct qm_mcr_ceetm_cq_config {
146688 + u8 __reserved1[62];
146689 +} __packed;
146690 +
146691 +struct qm_mcr_ceetm_cq_query {
146692 + u8 __reserved1[4];
146693 + u16 ccgid;
146694 + u16 state;
146695 + u32 pfdr_hptr:24;
146696 + u32 pfdr_tptr:24;
146697 + u16 od1_xsfdr;
146698 + u16 od2_xsfdr;
146699 + u16 od3_xsfdr;
146700 + u16 od4_xsfdr;
146701 + u16 od5_xsfdr;
146702 + u16 od6_xsfdr;
146703 + u16 ra1_xsfdr;
146704 + u16 ra2_xsfdr;
146705 + u8 __reserved2;
146706 + u32 frm_cnt:24;
146707 + u8 __reserved333[28];
146708 +} __packed;
146709 +
146710 +struct qm_mcr_ceetm_dct_config {
146711 + u8 __reserved1[62];
146712 +} __packed;
146713 +
146714 +struct qm_mcr_ceetm_dct_query {
146715 + u8 __reserved1[18];
146716 + u32 context_b;
146717 + u64 context_a;
146718 + u8 __reserved2[32];
146719 +} __packed;
146720 +
146721 +struct qm_mcr_ceetm_class_scheduler_config {
146722 + u8 __reserved1[62];
146723 +} __packed;
146724 +
146725 +struct qm_mcr_ceetm_class_scheduler_query {
146726 + u8 __reserved1[9];
146727 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146728 + u8 gpc_reserved:1;
146729 + u8 gpc_combine_flag:1;
146730 + u8 gpc_prio_b:3;
146731 + u8 gpc_prio_a:3;
146732 +#else
146733 + u8 gpc_prio_a:3;
146734 + u8 gpc_prio_b:3;
146735 + u8 gpc_combine_flag:1;
146736 + u8 gpc_reserved:1;
146737 +#endif
146738 + u16 crem;
146739 + u16 erem;
146740 + u8 w[8];
146741 + u8 __reserved2[5];
146742 + u32 wbfslist:24;
146743 + u32 d8;
146744 + u32 d9;
146745 + u32 d10;
146746 + u32 d11;
146747 + u32 d12;
146748 + u32 d13;
146749 + u32 d14;
146750 + u32 d15;
146751 +} __packed;
146752 +
146753 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146754 + u16 cid;
146755 + u8 __reserved2[60];
146756 +} __packed;
146757 +
146758 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146759 + u16 cid;
146760 + u8 __reserved1;
146761 + union {
146762 + struct {
146763 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146764 + u8 map_shaped:1;
146765 + u8 map_reserved:4;
146766 + u8 map_lni_id:3;
146767 +#else
146768 + u8 map_lni_id:3;
146769 + u8 map_reserved:4;
146770 + u8 map_shaped:1;
146771 +#endif
146772 + u8 __reserved2[58];
146773 + } __packed channel_mapping_query;
146774 + struct {
146775 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146776 + u8 map_reserved:5;
146777 + u8 map_lni_id:3;
146778 +#else
146779 + u8 map_lni_id:3;
146780 + u8 map_reserved:5;
146781 +#endif
146782 + u8 __reserved2[58];
146783 + } __packed sp_mapping_query;
146784 + struct {
146785 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146786 + u8 cpl:1;
146787 + u8 cpl_reserved:2;
146788 + u8 oal:5;
146789 +#else
146790 + u8 oal:5;
146791 + u8 cpl_reserved:2;
146792 + u8 cpl:1;
146793 +#endif
146794 + u32 crtcr:24;
146795 + u32 ertcr:24;
146796 + u16 crtbl;
146797 + u16 ertbl;
146798 + u8 mps;
146799 + u8 __reserved2[15];
146800 + u32 crat;
146801 + u32 erat;
146802 + u8 __reserved3[24];
146803 + } __packed shaper_query;
146804 + struct {
146805 + u8 __reserved1[11];
146806 + u64 lnitcfcc;
146807 + u8 __reserved3[40];
146808 + } __packed tcfc_query;
146809 + };
146810 +} __packed;
146811 +
146812 +struct qm_mcr_ceetm_ccgr_config {
146813 + u8 __reserved1[46];
146814 + union {
146815 + u8 __reserved2[8];
146816 + struct {
146817 + u16 timestamp;
146818 + u16 wr_porb_g;
146819 + u16 wr_prob_y;
146820 + u16 wr_prob_r;
146821 + } __packed test_write;
146822 + };
146823 + u8 __reserved3[8];
146824 +} __packed;
146825 +
146826 +struct qm_mcr_ceetm_ccgr_query {
146827 + u8 __reserved1[6];
146828 + union {
146829 + struct {
146830 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146831 + u8 ctl_reserved:1;
146832 + u8 ctl_wr_en_g:1;
146833 + u8 ctl_wr_en_y:1;
146834 + u8 ctl_wr_en_r:1;
146835 + u8 ctl_td_en:1;
146836 + u8 ctl_td_mode:1;
146837 + u8 ctl_cscn_en:1;
146838 + u8 ctl_mode:1;
146839 +#else
146840 + u8 ctl_mode:1;
146841 + u8 ctl_cscn_en:1;
146842 + u8 ctl_td_mode:1;
146843 + u8 ctl_td_en:1;
146844 + u8 ctl_wr_en_r:1;
146845 + u8 ctl_wr_en_y:1;
146846 + u8 ctl_wr_en_g:1;
146847 + u8 ctl_reserved:1;
146848 +#endif
146849 + u8 cdv;
146850 + u8 __reserved2[2];
146851 + u8 oal;
146852 + u8 __reserved3;
146853 + struct qm_cgr_cs_thres cs_thres;
146854 + struct qm_cgr_cs_thres cs_thres_x;
146855 + struct qm_cgr_cs_thres td_thres;
146856 + struct qm_cgr_wr_parm wr_parm_g;
146857 + struct qm_cgr_wr_parm wr_parm_y;
146858 + struct qm_cgr_wr_parm wr_parm_r;
146859 + u16 cscn_targ_dcp;
146860 + u8 dcp_lsn;
146861 + u64 i_cnt:40;
146862 + u8 __reserved4[3];
146863 + u64 a_cnt:40;
146864 + u32 cscn_targ_swp[4];
146865 + } __packed cm_query;
146866 + struct {
146867 + u8 dnc;
146868 + u8 dn0;
146869 + u8 dn1;
146870 + u64 dnba:40;
146871 + u8 __reserved2[2];
146872 + u16 dnth_0;
146873 + u8 __reserved3[2];
146874 + u16 dnth_1;
146875 + u8 __reserved4[10];
146876 + u16 dnacc_0;
146877 + u8 __reserved5[2];
146878 + u16 dnacc_1;
146879 + u8 __reserved6[24];
146880 + } __packed dn_query;
146881 + struct {
146882 + u8 __reserved2[24];
146883 + struct __qm_mcr_querycongestion state;
146884 + } __packed congestion_state;
146885 +
146886 + };
146887 +} __packed;
146888 +
146889 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
146890 + u8 stat;
146891 + u8 __reserved1[11];
146892 + u16 dctidx;
146893 + struct qm_fd fd;
146894 + u8 __reserved2[32];
146895 +} __packed;
146896 +
146897 +struct qm_mcr_ceetm_statistics_query {
146898 + u8 __reserved1[17];
146899 + u64 frm_cnt:40;
146900 + u8 __reserved2[2];
146901 + u64 byte_cnt:48;
146902 + u8 __reserved3[32];
146903 +} __packed;
146904 +
146905 +struct qm_mc_result {
146906 + u8 verb;
146907 + u8 result;
146908 + union {
146909 + struct qm_mcr_initfq initfq;
146910 + struct qm_mcr_queryfq queryfq;
146911 + struct qm_mcr_queryfq_np queryfq_np;
146912 + struct qm_mcr_alterfq alterfq;
146913 + struct qm_mcr_initcgr initcgr;
146914 + struct qm_mcr_cgrtestwrite cgrtestwrite;
146915 + struct qm_mcr_querycgr querycgr;
146916 + struct qm_mcr_querycongestion querycongestion;
146917 + struct qm_mcr_querywq querywq;
146918 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
146919 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
146920 + struct qm_mcr_ceetm_cq_config cq_config;
146921 + struct qm_mcr_ceetm_cq_query cq_query;
146922 + struct qm_mcr_ceetm_dct_config dct_config;
146923 + struct qm_mcr_ceetm_dct_query dct_query;
146924 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
146925 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
146926 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
146927 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
146928 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
146929 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
146930 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146931 + struct qm_mcr_ceetm_statistics_query stats_query;
146932 + };
146933 +} __packed;
146934 +
146935 +#define QM_MCR_VERB_RRID 0x80
146936 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
146937 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
146938 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
146939 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
146940 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
146941 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
146942 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
146943 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
146944 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
146945 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
146946 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
146947 +#define QM_MCR_RESULT_NULL 0x00
146948 +#define QM_MCR_RESULT_OK 0xf0
146949 +#define QM_MCR_RESULT_ERR_FQID 0xf1
146950 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
146951 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
146952 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
146953 +#define QM_MCR_RESULT_PENDING 0xf8
146954 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
146955 +#define QM_MCR_NP_STATE_FE 0x10
146956 +#define QM_MCR_NP_STATE_R 0x08
146957 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
146958 +#define QM_MCR_NP_STATE_OOS 0x00
146959 +#define QM_MCR_NP_STATE_RETIRED 0x01
146960 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
146961 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
146962 +#define QM_MCR_NP_STATE_PARKED 0x04
146963 +#define QM_MCR_NP_STATE_ACTIVE 0x05
146964 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
146965 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
146966 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
146967 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
146968 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
146969 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146970 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146971 +/* This extracts the state for congestion group 'n' from a query response.
146972 + * Eg.
146973 + * u8 cgr = [...];
146974 + * struct qm_mc_result *res = [...];
146975 + * printf("congestion group %d congestion state: %d\n", cgr,
146976 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
146977 + */
146978 +#define __CGR_WORD(num) (num >> 5)
146979 +#define __CGR_SHIFT(num) (num & 0x1f)
146980 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
146981 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
146982 + u8 cgr)
146983 +{
146984 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
146985 +}
146986 +
146987 +
146988 +/*********************/
146989 +/* Utility interface */
146990 +/*********************/
146991 +
146992 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
146993 + * spinlock them yourself if needed. */
146994 +struct qman_fqid_pool;
146995 +
146996 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
146997 + * always succeeds, but returns non-zero if there were "leaked" FQID
146998 + * allocations. */
146999 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
147000 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
147001 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
147002 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
147003 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
147004 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
147005 +
147006 +/*******************************************************************/
147007 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
147008 +/*******************************************************************/
147009 +
147010 + /* Portal and Frame Queues */
147011 + /* ----------------------- */
147012 +/* Represents a managed portal */
147013 +struct qman_portal;
147014 +
147015 +/* This object type represents Qman frame queue descriptors (FQD), it is
147016 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
147017 + * defined further down. */
147018 +struct qman_fq;
147019 +
147020 +/* This object type represents a Qman congestion group, it is defined further
147021 + * down. */
147022 +struct qman_cgr;
147023 +
147024 +struct qman_portal_config {
147025 + /* If the caller enables DQRR stashing (and thus wishes to operate the
147026 + * portal from only one cpu), this is the logical CPU that the portal
147027 + * will stash to. Whether stashing is enabled or not, this setting is
147028 + * also used for any "core-affine" portals, ie. default portals
147029 + * associated to the corresponding cpu. -1 implies that there is no core
147030 + * affinity configured. */
147031 + int cpu;
147032 + /* portal interrupt line */
147033 + int irq;
147034 + /* the unique index of this portal */
147035 + u32 index;
147036 + /* Is this portal shared? (If so, it has coarser locking and demuxes
147037 + * processing on behalf of other CPUs.) */
147038 + int is_shared;
147039 + /* The portal's dedicated channel id, use this value for initialising
147040 + * frame queues to target this portal when scheduled. */
147041 + u16 channel;
147042 + /* A mask of which pool channels this portal has dequeue access to
147043 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
147044 + u32 pools;
147045 +};
147046 +
147047 +/* This enum, and the callback type that returns it, are used when handling
147048 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
147049 + * portal object (for handling dequeues that do not demux because contextB is
147050 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
147051 +enum qman_cb_dqrr_result {
147052 + /* DQRR entry can be consumed */
147053 + qman_cb_dqrr_consume,
147054 + /* Like _consume, but requests parking - FQ must be held-active */
147055 + qman_cb_dqrr_park,
147056 + /* Does not consume, for DCA mode only. This allows out-of-order
147057 + * consumes by explicit calls to qman_dca() and/or the use of implicit
147058 + * DCA via EQCR entries. */
147059 + qman_cb_dqrr_defer,
147060 + /* Stop processing without consuming this ring entry. Exits the current
147061 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
147062 + * interrupt handler, the callback would typically call
147063 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
147064 + * otherwise the interrupt will reassert immediately. */
147065 + qman_cb_dqrr_stop,
147066 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
147067 + qman_cb_dqrr_consume_stop
147068 +};
147069 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
147070 + struct qman_fq *fq,
147071 + const struct qm_dqrr_entry *dqrr);
147072 +
147073 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
147074 + * are always consumed after the callback returns. */
147075 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
147076 + const struct qm_mr_entry *msg);
147077 +
147078 +/* This callback type is used when handling DCP ERNs */
147079 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
147080 + const struct qm_mr_entry *msg);
147081 +
147082 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
147083 + * held-active + held-suspended are just "sched". Things like "retired" will not
147084 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
147085 + * then, to indicate it's completing and to gate attempts to retry the retire
147086 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
147087 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
147088 + * index rather than the FQ that ring entry corresponds to), so repeated park
147089 + * commands are allowed (if you're silly enough to try) but won't change FQ
147090 + * state, and the resulting park notifications move FQs from "sched" to
147091 + * "parked". */
147092 +enum qman_fq_state {
147093 + qman_fq_state_oos,
147094 + qman_fq_state_parked,
147095 + qman_fq_state_sched,
147096 + qman_fq_state_retired
147097 +};
147098 +
147099 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
147100 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
147101 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
147102 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
147103 + * they should;
147104 + *
147105 + * (a) extend the qman_fq structure with their state; eg.
147106 + *
147107 + * // myfq is allocated and driver_fq callbacks filled in;
147108 + * struct my_fq {
147109 + * struct qman_fq base;
147110 + * int an_extra_field;
147111 + * [ ... add other fields to be associated with each FQ ...]
147112 + * } *myfq = some_my_fq_allocator();
147113 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
147114 + *
147115 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
147116 + * struct my_fq *myfq = (struct my_fq *)fq;
147117 + * do_something_with(myfq->an_extra_field);
147118 + * [...]
147119 + *
147120 + * (b) when and if configuring the FQ for context stashing, specify how ever
147121 + * many cachelines are required to stash 'struct my_fq', to accelerate not
147122 + * only the Qman driver but the callback as well.
147123 + */
147124 +
147125 +struct qman_fq_cb {
147126 + qman_cb_dqrr dqrr; /* for dequeued frames */
147127 + qman_cb_mr ern; /* for s/w ERNs */
147128 + qman_cb_mr fqs; /* frame-queue state changes*/
147129 +};
147130 +
147131 +struct qman_fq {
147132 + /* Caller of qman_create_fq() provides these demux callbacks */
147133 + struct qman_fq_cb cb;
147134 + /* These are internal to the driver, don't touch. In particular, they
147135 + * may change, be removed, or extended (so you shouldn't rely on
147136 + * sizeof(qman_fq) being a constant). */
147137 + spinlock_t fqlock;
147138 + u32 fqid;
147139 + volatile unsigned long flags;
147140 + enum qman_fq_state state;
147141 + int cgr_groupid;
147142 + struct rb_node node;
147143 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
147144 + u32 key;
147145 +#endif
147146 +};
147147 +
147148 +/* This callback type is used when handling congestion group entry/exit.
147149 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
147150 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
147151 + struct qman_cgr *cgr, int congested);
147152 +
147153 +struct qman_cgr {
147154 + /* Set these prior to qman_create_cgr() */
147155 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
147156 + qman_cb_cgr cb;
147157 + /* These are private to the driver */
147158 + u16 chan; /* portal channel this object is created on */
147159 + struct list_head node;
147160 +};
147161 +
147162 +/* Flags to qman_create_fq() */
147163 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
147164 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
147165 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
147166 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
147167 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
147168 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
147169 +
147170 +/* Flags to qman_destroy_fq() */
147171 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
147172 +
147173 +/* Flags from qman_fq_state() */
147174 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
147175 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
147176 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
147177 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
147178 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
147179 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
147180 +
147181 +/* Flags to qman_init_fq() */
147182 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
147183 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
147184 +
147185 +/* Flags to qman_volatile_dequeue() */
147186 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
147187 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
147188 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
147189 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
147190 +#endif
147191 +
147192 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
147193 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
147194 + * any change here should be audited in PME.) */
147195 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
147196 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
147197 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
147198 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
147199 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
147200 +#endif
147201 +#endif
147202 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
147203 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
147204 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
147205 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
147206 + (((u32)(p) << 2) & 0x00000f00)
147207 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
147208 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
147209 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
147210 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
147211 +/* For the ORP-specific qman_enqueue_orp() variant;
147212 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
147213 + * of a frame. */
147214 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
147215 +/* - this flag performs no enqueue but fills in an ORP sequence number that
147216 + * would otherwise block it (eg. if a frame has been dropped). */
147217 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
147218 +/* - this flag performs no enqueue but advances NESN to the given sequence
147219 + * number. */
147220 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
147221 +
147222 +/* Flags to qman_modify_cgr() */
147223 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
147224 +#define QMAN_CGR_MODE_FRAME 0x00000001
147225 +
147226 + /* Portal Management */
147227 + /* ----------------- */
147228 +/**
147229 + * qman_get_portal_config - get portal configuration settings
147230 + *
147231 + * This returns a read-only view of the current cpu's affine portal settings.
147232 + */
147233 +const struct qman_portal_config *qman_get_portal_config(void);
147234 +
147235 +/**
147236 + * qman_irqsource_get - return the portal work that is interrupt-driven
147237 + *
147238 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
147239 + * enabled for interrupt handling on the current cpu's affine portal. These
147240 + * sources will trigger the portal interrupt and the interrupt handler (or a
147241 + * tasklet/bottom-half it defers to) will perform the corresponding processing
147242 + * work. The qman_poll_***() functions will only process sources that are not in
147243 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
147244 + * this always returns zero.
147245 + */
147246 +u32 qman_irqsource_get(void);
147247 +
147248 +/**
147249 + * qman_irqsource_add - add processing sources to be interrupt-driven
147250 + * @bits: bitmask of QM_PIRQ_**I processing sources
147251 + *
147252 + * Adds processing sources that should be interrupt-driven (rather than
147253 + * processed via qman_poll_***() functions). Returns zero for success, or
147254 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147255 + */
147256 +int qman_irqsource_add(u32 bits);
147257 +
147258 +/**
147259 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
147260 + * @bits: bitmask of QM_PIRQ_**I processing sources
147261 + *
147262 + * Removes processing sources from being interrupt-driven, so that they will
147263 + * instead be processed via qman_poll_***() functions. Returns zero for success,
147264 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147265 + */
147266 +int qman_irqsource_remove(u32 bits);
147267 +
147268 +/**
147269 + * qman_affine_cpus - return a mask of cpus that have affine portals
147270 + */
147271 +const cpumask_t *qman_affine_cpus(void);
147272 +
147273 +/**
147274 + * qman_affine_channel - return the channel ID of an portal
147275 + * @cpu: the cpu whose affine portal is the subject of the query
147276 + *
147277 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
147278 + * bug to call this function for any value of @cpu (other than -1) that is not a
147279 + * member of the mask returned from qman_affine_cpus().
147280 + */
147281 +u16 qman_affine_channel(int cpu);
147282 +
147283 +/**
147284 + * qman_get_affine_portal - return the portal pointer affine to cpu
147285 + * @cpu: the cpu whose affine portal is the subject of the query
147286 + *
147287 + */
147288 +void *qman_get_affine_portal(int cpu);
147289 +
147290 +/**
147291 + * qman_poll_dqrr - process DQRR (fast-path) entries
147292 + * @limit: the maximum number of DQRR entries to process
147293 + *
147294 + * Use of this function requires that DQRR processing not be interrupt-driven.
147295 + * Ie. the value returned by qman_irqsource_get() should not include
147296 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
147297 + * this function will return -EINVAL, otherwise the return value is >=0 and
147298 + * represents the number of DQRR entries processed.
147299 + */
147300 +int qman_poll_dqrr(unsigned int limit);
147301 +
147302 +/**
147303 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
147304 + *
147305 + * This function does any portal processing that isn't interrupt-driven. If the
147306 + * current CPU is sharing a portal hosted on another CPU, this function will
147307 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
147308 + * indicating what interrupt sources were actually processed by the call.
147309 + */
147310 +u32 qman_poll_slow(void);
147311 +
147312 +/**
147313 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
147314 + *
147315 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
147316 + * affine portal. There are two classes of portal processing in question;
147317 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
147318 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
147319 + * thresholds, congestion state changes, etc). This function does whatever
147320 + * processing is not triggered by interrupts.
147321 + *
147322 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
147323 + * interrupt-driven) then this function uses a heuristic to determine how often
147324 + * to run slow-path processing - as slow-path processing introduces at least a
147325 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
147326 + * close to zero-cost if there is no work to be done. Applications can tune this
147327 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
147328 + * rather than going via this wrapper.
147329 + */
147330 +void qman_poll(void);
147331 +
147332 +/**
147333 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
147334 + *
147335 + * Disables DQRR processing of the portal. This is reference-counted, so
147336 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147337 + * truly re-enable dequeuing.
147338 + */
147339 +void qman_stop_dequeues(void);
147340 +
147341 +/**
147342 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
147343 + *
147344 + * Enables DQRR processing of the portal. This is reference-counted, so
147345 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147346 + * truly re-enable dequeuing.
147347 + */
147348 +void qman_start_dequeues(void);
147349 +
147350 +/**
147351 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
147352 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147353 + *
147354 + * Adds a set of pool channels to the portal's static dequeue command register
147355 + * (SDQCR). The requested pools are limited to those the portal has dequeue
147356 + * access to.
147357 + */
147358 +void qman_static_dequeue_add(u32 pools);
147359 +
147360 +/**
147361 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
147362 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147363 + *
147364 + * Removes a set of pool channels from the portal's static dequeue command
147365 + * register (SDQCR). The requested pools are limited to those the portal has
147366 + * dequeue access to.
147367 + */
147368 +void qman_static_dequeue_del(u32 pools);
147369 +
147370 +/**
147371 + * qman_static_dequeue_get - return the portal's current SDQCR
147372 + *
147373 + * Returns the portal's current static dequeue command register (SDQCR). The
147374 + * entire register is returned, so if only the currently-enabled pool channels
147375 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
147376 + */
147377 +u32 qman_static_dequeue_get(void);
147378 +
147379 +/**
147380 + * qman_dca - Perform a Discrete Consumption Acknowledgement
147381 + * @dq: the DQRR entry to be consumed
147382 + * @park_request: indicates whether the held-active @fq should be parked
147383 + *
147384 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
147385 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
147386 + * does not take a 'portal' argument but implies the core affine portal from the
147387 + * cpu that is currently executing the function. For reasons of locking, this
147388 + * function must be called from the same CPU as that which processed the DQRR
147389 + * entry in the first place.
147390 + */
147391 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
147392 +
147393 +/**
147394 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
147395 + *
147396 + * For use in situations where a cpu-affine caller needs to determine when all
147397 + * enqueues for the local portal have been processed by Qman but can't use the
147398 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
147399 + * The function forces tracking of EQCR consumption (which normally doesn't
147400 + * happen until enqueue processing needs to find space to put new enqueue
147401 + * commands), and returns zero if the ring still has unprocessed entries,
147402 + * non-zero if it is empty.
147403 + */
147404 +int qman_eqcr_is_empty(void);
147405 +
147406 +/**
147407 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
147408 + * @handler: callback for processing DCP ERNs
147409 + * @affine: whether this handler is specific to the locally affine portal
147410 + *
147411 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
147412 + * DCP) is configured not to receive enqueue rejections, then any enqueues
147413 + * through that DCP that are rejected will be sent to a given software portal.
147414 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
147415 + * received on the portal affine to the current CPU. If multiple CPUs share a
147416 + * portal and they all call this function, they will be setting the handler for
147417 + * the same portal! If @affine is zero, then this handler will be global to all
147418 + * portals handled by this instance of the driver. Only those portals that do
147419 + * not have their own affine handler will use the global handler.
147420 + */
147421 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
147422 +
147423 + /* FQ management */
147424 + /* ------------- */
147425 +/**
147426 + * qman_create_fq - Allocates a FQ
147427 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
147428 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
147429 + * @fq: memory for storing the 'fq', with callbacks filled in
147430 + *
147431 + * Creates a frame queue object for the given @fqid, unless the
147432 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
147433 + * dynamically allocated (or the function fails if none are available). Once
147434 + * created, the caller should not touch the memory at 'fq' except as extended to
147435 + * adjacent memory for user-defined fields (see the definition of "struct
147436 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
147437 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
147438 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
147439 + * causes the driver to honour any contextB modifications requested in the
147440 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
147441 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
147442 + * software portals, the contextB field is controlled by the driver and can't be
147443 + * modified by the caller. If the AS_IS flag is specified, management commands
147444 + * will be used on portal @p to query state for frame queue @fqid and construct
147445 + * a frame queue object based on that, rather than assuming/requiring that it be
147446 + * Out of Service.
147447 + */
147448 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
147449 +
147450 +/**
147451 + * qman_destroy_fq - Deallocates a FQ
147452 + * @fq: the frame queue object to release
147453 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
147454 + *
147455 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
147456 + * not deallocated but the caller regains ownership, to do with as desired. The
147457 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
147458 + * is specified, in which case it may also be in the 'parked' state.
147459 + */
147460 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
147461 +
147462 +/**
147463 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
147464 + * @fq: the frame queue object to query
147465 + */
147466 +u32 qman_fq_fqid(struct qman_fq *fq);
147467 +
147468 +/**
147469 + * qman_fq_state - Queries the state of a FQ object
147470 + * @fq: the frame queue object to query
147471 + * @state: pointer to state enum to return the FQ scheduling state
147472 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
147473 + *
147474 + * Queries the state of the FQ object, without performing any h/w commands.
147475 + * This captures the state, as seen by the driver, at the time the function
147476 + * executes.
147477 + */
147478 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
147479 +
147480 +/**
147481 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
147482 + * @fq: the frame queue object to modify, must be 'parked' or new.
147483 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
147484 + * @opts: the FQ-modification settings, as defined in the low-level API
147485 + *
147486 + * The @opts parameter comes from the low-level portal API. Select
147487 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
147488 + * rather than parked. NB, @opts can be NULL.
147489 + *
147490 + * Note that some fields and options within @opts may be ignored or overwritten
147491 + * by the driver;
147492 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
147493 + * affects one frame queue: @fq).
147494 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
147495 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
147496 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
147497 + * initialised to a value used by the driver for demux.
147498 + * - if context_b is initialised for demux, so is context_a in case stashing
147499 + * is requested (see item 4).
147500 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
147501 + * objects.)
147502 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
147503 + * 'dest::channel' field will be overwritten to match the portal used to issue
147504 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
147505 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
147506 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
147507 + * isn't set, the destination channel/workqueue fields and the write-enable bit
147508 + * are left as-is.
147509 + * 4. if the driver overwrites context_a/b for demux, then if
147510 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
147511 + * context_a.address fields and will leave the stashing fields provided by the
147512 + * user alone, otherwise it will zero out the context_a.stashing fields.
147513 + */
147514 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
147515 +
147516 +/**
147517 + * qman_schedule_fq - Schedules a FQ
147518 + * @fq: the frame queue object to schedule, must be 'parked'
147519 + *
147520 + * Schedules the frame queue, which must be Parked, which takes it to
147521 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
147522 + */
147523 +int qman_schedule_fq(struct qman_fq *fq);
147524 +
147525 +/**
147526 + * qman_retire_fq - Retires a FQ
147527 + * @fq: the frame queue object to retire
147528 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
147529 + *
147530 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
147531 + * the retirement was started asynchronously, otherwise it returns negative for
147532 + * failure. When this function returns zero, @flags is set to indicate whether
147533 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
147534 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
147535 + * FQRN message shows up on the portal's message ring.
147536 + *
147537 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
147538 + * Active state), the completion will be via the message ring as a FQRN - but
147539 + * the corresponding callback may occur before this function returns!! Ie. the
147540 + * caller should be prepared to accept the callback as the function is called,
147541 + * not only once it has returned.
147542 + */
147543 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
147544 +
147545 +/**
147546 + * qman_oos_fq - Puts a FQ "out of service"
147547 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
147548 + *
147549 + * The frame queue must be retired and empty, and if any order restoration list
147550 + * was released as ERNs at the time of retirement, they must all be consumed.
147551 + */
147552 +int qman_oos_fq(struct qman_fq *fq);
147553 +
147554 +/**
147555 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
147556 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
147557 + * or 'retired' or 'parked' state
147558 + * @xon: boolean to set fq in XON or XOFF state
147559 + *
147560 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
147561 + * otherwise the IFSI interrupt will be asserted.
147562 + */
147563 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
147564 +
147565 +/**
147566 + * qman_query_fq - Queries FQD fields (via h/w query command)
147567 + * @fq: the frame queue object to be queried
147568 + * @fqd: storage for the queried FQD fields
147569 + */
147570 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
147571 +
147572 +/**
147573 + * qman_query_fq_np - Queries non-programmable FQD fields
147574 + * @fq: the frame queue object to be queried
147575 + * @np: storage for the queried FQD fields
147576 + */
147577 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
147578 +
147579 +/**
147580 + * qman_query_wq - Queries work queue lengths
147581 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
147582 + * to this software portal. Otherwise, query length of WQs in a
147583 + * channel specified in wq.
147584 + * @wq: storage for the queried WQs lengths. Also specified the channel to
147585 + * to query if query_dedicated is zero.
147586 + */
147587 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
147588 +
147589 +/**
147590 + * qman_volatile_dequeue - Issue a volatile dequeue command
147591 + * @fq: the frame queue object to dequeue from
147592 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
147593 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
147594 + *
147595 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
147596 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
147597 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
147598 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
147599 + * the VDQCR command has finished executing (ie. once the callback for the last
147600 + * DQRR entry resulting from the VDQCR command has been called). If not using
147601 + * the FINISH flag, completion can be determined either by detecting the
147602 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
147603 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
147604 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
147605 + * "flags" retrieved from qman_fq_state().
147606 + */
147607 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
147608 +
147609 +/**
147610 + * qman_enqueue - Enqueue a frame to a frame queue
147611 + * @fq: the frame queue object to enqueue to
147612 + * @fd: a descriptor of the frame to be enqueued
147613 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147614 + *
147615 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
147616 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
147617 + * field is ignored. The return value is non-zero on error, such as ring full
147618 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
147619 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
147620 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
147621 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
147622 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
147623 + * perform an implied "discrete consumption acknowledgement" on the dequeue
147624 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
147625 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
147626 + * this implicit DCA can delay the release of a "held active" frame queue
147627 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
147628 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
147629 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
147630 + * acknowledgement should "park request" the "held active" frame queue. Ie.
147631 + * when the portal eventually releases that frame queue, it will be left in the
147632 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
147633 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
147634 + * is requested, and the FQ is a member of a congestion group, then this
147635 + * function returns -EAGAIN if the congestion group is currently congested.
147636 + * Note, this does not eliminate ERNs, as the async interface means we can be
147637 + * sending enqueue commands to an un-congested FQ that becomes congested before
147638 + * the enqueue commands are processed, but it does minimise needless thrashing
147639 + * of an already busy hardware resource by throttling many of the to-be-dropped
147640 + * enqueues "at the source".
147641 + */
147642 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
147643 +
147644 +typedef int (*qman_cb_precommit) (void *arg);
147645 +/**
147646 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
147647 + * @fq: the frame queue object to enqueue to
147648 + * @fd: a descriptor of the frame to be enqueued
147649 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147650 + * @cb: user supplied callback function to invoke before writing commit verb.
147651 + * @cb_arg: callback function argument
147652 + *
147653 + * This is similar to qman_enqueue except that it will invoke a user supplied
147654 + * callback function just before writng the commit verb. This is useful
147655 + * when the user want to do something *just before* enqueuing the request and
147656 + * the enqueue can't fail.
147657 + */
147658 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
147659 + u32 flags, qman_cb_precommit cb, void *cb_arg);
147660 +
147661 +/**
147662 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
147663 + * @fq: the frame queue object to enqueue to
147664 + * @fd: a descriptor of the frame to be enqueued
147665 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147666 + * @orp: the frame queue object used as an order restoration point.
147667 + * @orp_seqnum: the sequence number of this frame in the order restoration path
147668 + *
147669 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
147670 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
147671 + * enqueue operation to employ order restoration. Each frame queue object acts
147672 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
147673 + * with an incrementing sequence number, this value is generally ignored unless
147674 + * that sequence of dequeued frames will need order restoration later. Each
147675 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
147676 + * is a re-assembly context for re-ordering frames relative to their sequence
147677 + * numbers as they are enqueued. The ORP does not have to be within the frame
147678 + * queue that receives the enqueued frame, in fact it is usually the frame
147679 + * queue from which the frames were originally dequeued. For the purposes of
147680 + * order restoration, multiple frames (or "fragments") can be enqueued for a
147681 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
147682 + * enqueues except the final fragment of a given sequence number. Ordering
147683 + * between sequence numbers is guaranteed, even if fragments of different
147684 + * sequence numbers are interlaced with one another. Fragments of the same
147685 + * sequence number will retain the order in which they are enqueued. If no
147686 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
147687 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
147688 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
147689 + * sequence number should become the ORP's "Next Expected Sequence Number".
147690 + *
147691 + * Side note: a frame queue object can be used purely as an ORP, without
147692 + * carrying any frames at all. Care should be taken not to deallocate a frame
147693 + * queue object that is being actively used as an ORP, as a future allocation
147694 + * of the frame queue object may start using the internal ORP before the
147695 + * previous use has finished.
147696 + */
147697 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
147698 + struct qman_fq *orp, u16 orp_seqnum);
147699 +
147700 +/**
147701 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
147702 + * @result: is set by the API to the base FQID of the allocated range
147703 + * @count: the number of FQIDs required
147704 + * @align: required alignment of the allocated range
147705 + * @partial: non-zero if the API can return fewer than @count FQIDs
147706 + *
147707 + * Returns the number of frame queues allocated, or a negative error code. If
147708 + * @partial is non zero, the allocation request may return a smaller range of
147709 + * FQs than requested (though alignment will be as requested). If @partial is
147710 + * zero, the return value will either be 'count' or negative.
147711 + */
147712 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
147713 +static inline int qman_alloc_fqid(u32 *result)
147714 +{
147715 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
147716 + return (ret > 0) ? 0 : ret;
147717 +}
147718 +
147719 +/**
147720 + * qman_release_fqid_range - Release the specified range of frame queue IDs
147721 + * @fqid: the base FQID of the range to deallocate
147722 + * @count: the number of FQIDs in the range
147723 + *
147724 + * This function can also be used to seed the allocator with ranges of FQIDs
147725 + * that it can subsequently allocate from.
147726 + */
147727 +void qman_release_fqid_range(u32 fqid, unsigned int count);
147728 +static inline void qman_release_fqid(u32 fqid)
147729 +{
147730 + qman_release_fqid_range(fqid, 1);
147731 +}
147732 +
147733 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
147734 +
147735 +
147736 +int qman_shutdown_fq(u32 fqid);
147737 +
147738 +/**
147739 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147740 + * @fqid: the base FQID of the range to deallocate
147741 + * @count: the number of FQIDs in the range
147742 + */
147743 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147744 +static inline int qman_reserve_fqid(u32 fqid)
147745 +{
147746 + return qman_reserve_fqid_range(fqid, 1);
147747 +}
147748 +
147749 + /* Pool-channel management */
147750 + /* ----------------------- */
147751 +/**
147752 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147753 + * @result: is set by the API to the base pool-channel ID of the allocated range
147754 + * @count: the number of pool-channel IDs required
147755 + * @align: required alignment of the allocated range
147756 + * @partial: non-zero if the API can return fewer than @count
147757 + *
147758 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147759 + * If @partial is non zero, the allocation request may return a smaller range of
147760 + * than requested (though alignment will be as requested). If @partial is zero,
147761 + * the return value will either be 'count' or negative.
147762 + */
147763 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147764 +static inline int qman_alloc_pool(u32 *result)
147765 +{
147766 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147767 + return (ret > 0) ? 0 : ret;
147768 +}
147769 +
147770 +/**
147771 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147772 + * @id: the base pool-channel ID of the range to deallocate
147773 + * @count: the number of pool-channel IDs in the range
147774 + */
147775 +void qman_release_pool_range(u32 id, unsigned int count);
147776 +static inline void qman_release_pool(u32 id)
147777 +{
147778 + qman_release_pool_range(id, 1);
147779 +}
147780 +
147781 +/**
147782 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147783 + * @id: the base pool-channel ID of the range to reserve
147784 + * @count: the number of pool-channel IDs in the range
147785 + */
147786 +int qman_reserve_pool_range(u32 id, unsigned int count);
147787 +static inline int qman_reserve_pool(u32 id)
147788 +{
147789 + return qman_reserve_pool_range(id, 1);
147790 +}
147791 +
147792 +void qman_seed_pool_range(u32 id, unsigned int count);
147793 +
147794 + /* CGR management */
147795 + /* -------------- */
147796 +/**
147797 + * qman_create_cgr - Register a congestion group object
147798 + * @cgr: the 'cgr' object, with fields filled in
147799 + * @flags: QMAN_CGR_FLAG_* values
147800 + * @opts: optional state of CGR settings
147801 + *
147802 + * Registers this object to receiving congestion entry/exit callbacks on the
147803 + * portal affine to the cpu portal on which this API is executed. If opts is
147804 + * NULL then only the callback (cgr->cb) function is registered. If @flags
147805 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
147806 + * any unspecified parameters) will be used rather than a modify hw hardware
147807 + * (which only modifies the specified parameters).
147808 + */
147809 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
147810 + struct qm_mcc_initcgr *opts);
147811 +
147812 +/**
147813 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
147814 + * @cgr: the 'cgr' object, with fields filled in
147815 + * @flags: QMAN_CGR_FLAG_* values
147816 + * @dcp_portal: the DCP portal to which the cgr object is registered.
147817 + * @opts: optional state of CGR settings
147818 + *
147819 + */
147820 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
147821 + struct qm_mcc_initcgr *opts);
147822 +
147823 +/**
147824 + * qman_delete_cgr - Deregisters a congestion group object
147825 + * @cgr: the 'cgr' object to deregister
147826 + *
147827 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
147828 + * is executed. This must be excuted on the same affine portal on which it was
147829 + * created.
147830 + */
147831 +int qman_delete_cgr(struct qman_cgr *cgr);
147832 +
147833 +/**
147834 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
147835 + * @cgr: the 'cgr' object to deregister
147836 + *
147837 + * This will select the proper CPU and run there qman_delete_cgr().
147838 + */
147839 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
147840 +
147841 +/**
147842 + * qman_modify_cgr - Modify CGR fields
147843 + * @cgr: the 'cgr' object to modify
147844 + * @flags: QMAN_CGR_FLAG_* values
147845 + * @opts: the CGR-modification settings
147846 + *
147847 + * The @opts parameter comes from the low-level portal API, and can be NULL.
147848 + * Note that some fields and options within @opts may be ignored or overwritten
147849 + * by the driver, in particular the 'cgrid' field is ignored (this operation
147850 + * only affects the given CGR object). If @flags contains
147851 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
147852 + * unspecified parameters) will be used rather than a modify hw hardware (which
147853 + * only modifies the specified parameters).
147854 + */
147855 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
147856 + struct qm_mcc_initcgr *opts);
147857 +
147858 +/**
147859 +* qman_query_cgr - Queries CGR fields
147860 +* @cgr: the 'cgr' object to query
147861 +* @result: storage for the queried congestion group record
147862 +*/
147863 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
147864 +
147865 +/**
147866 + * qman_query_congestion - Queries the state of all congestion groups
147867 + * @congestion: storage for the queried state of all congestion groups
147868 + */
147869 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
147870 +
147871 +/**
147872 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
147873 + * @result: is set by the API to the base CGR ID of the allocated range
147874 + * @count: the number of CGR IDs required
147875 + * @align: required alignment of the allocated range
147876 + * @partial: non-zero if the API can return fewer than @count
147877 + *
147878 + * Returns the number of CGR IDs allocated, or a negative error code.
147879 + * If @partial is non zero, the allocation request may return a smaller range of
147880 + * than requested (though alignment will be as requested). If @partial is zero,
147881 + * the return value will either be 'count' or negative.
147882 + */
147883 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
147884 +static inline int qman_alloc_cgrid(u32 *result)
147885 +{
147886 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
147887 + return (ret > 0) ? 0 : ret;
147888 +}
147889 +
147890 +/**
147891 + * qman_release_cgrid_range - Release the specified range of CGR IDs
147892 + * @id: the base CGR ID of the range to deallocate
147893 + * @count: the number of CGR IDs in the range
147894 + */
147895 +void qman_release_cgrid_range(u32 id, unsigned int count);
147896 +static inline void qman_release_cgrid(u32 id)
147897 +{
147898 + qman_release_cgrid_range(id, 1);
147899 +}
147900 +
147901 +/**
147902 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
147903 + * @id: the base CGR ID of the range to reserve
147904 + * @count: the number of CGR IDs in the range
147905 + */
147906 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
147907 +static inline int qman_reserve_cgrid(u32 id)
147908 +{
147909 + return qman_reserve_cgrid_range(id, 1);
147910 +}
147911 +
147912 +void qman_seed_cgrid_range(u32 id, unsigned int count);
147913 +
147914 +
147915 + /* Helpers */
147916 + /* ------- */
147917 +/**
147918 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
147919 + * @fqid: the FQID that will be initialised by other s/w
147920 + *
147921 + * In many situations, a FQID is provided for communication between s/w
147922 + * entities, and whilst the consumer is responsible for initialising and
147923 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
147924 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
147925 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
147926 + * However, data can not be enqueued to the FQ until it is initialised out of
147927 + * the OOS state - this function polls for that condition. It is particularly
147928 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
147929 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
147930 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
147931 + * synchronise. The function returns zero for success, +1 if the FQ is still in
147932 + * the OOS state, or negative if there was an error.
147933 + */
147934 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
147935 +{
147936 + struct qm_mcr_queryfq_np np;
147937 + int err;
147938 + err = qman_query_fq_np(fq, &np);
147939 + if (err)
147940 + return err;
147941 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
147942 + return 1;
147943 + return 0;
147944 +}
147945 +
147946 + /* -------------- */
147947 + /* CEETM :: types */
147948 + /* -------------- */
147949 +/**
147950 + * Token Rate Structure
147951 + * Shaping rates are based on a "credit" system and a pre-configured h/w
147952 + * internal timer. The following type represents a shaper "rate" parameter as a
147953 + * fractional number of "tokens". Here's how it works. This (fractional) number
147954 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
147955 + * (up to a limit which is set by another shaper parameter). Every time a frame
147956 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
147957 + * bytes of data in the enqueued frame. A shaper will not allow itself to
147958 + * enqueue any frames if its token count is negative. As such;
147959 + *
147960 + * The rate at which data is enqueued is limited by the
147961 + * rate at which tokens are added.
147962 + *
147963 + * Therefore if the user knows the period between these h/w timer updates in
147964 + * seconds, they can calculate the maximum traffic rate of the shaper (in
147965 + * bytes-per-second) from the token rate. And vice versa, they can calculate
147966 + * the token rate to use in order to achieve a given traffic rate.
147967 + */
147968 +struct qm_ceetm_rate {
147969 + /* The token rate is; whole + (fraction/8192) */
147970 + u32 whole:11; /* 0..2047 */
147971 + u32 fraction:13; /* 0..8191 */
147972 +};
147973 +
147974 +struct qm_ceetm_weight_code {
147975 + /* The weight code is; 5 msbits + 3 lsbits */
147976 + u8 y:5;
147977 + u8 x:3;
147978 +};
147979 +
147980 +struct qm_ceetm {
147981 + unsigned int idx;
147982 + struct list_head sub_portals;
147983 + struct list_head lnis;
147984 + unsigned int sp_range[2];
147985 + unsigned int lni_range[2];
147986 +};
147987 +
147988 +struct qm_ceetm_sp {
147989 + struct list_head node;
147990 + unsigned int idx;
147991 + unsigned int dcp_idx;
147992 + int is_claimed;
147993 + struct qm_ceetm_lni *lni;
147994 +};
147995 +
147996 +/* Logical Network Interface */
147997 +struct qm_ceetm_lni {
147998 + struct list_head node;
147999 + unsigned int idx;
148000 + unsigned int dcp_idx;
148001 + int is_claimed;
148002 + struct qm_ceetm_sp *sp;
148003 + struct list_head channels;
148004 + int shaper_enable;
148005 + int shaper_couple;
148006 + int oal;
148007 + struct qm_ceetm_rate cr_token_rate;
148008 + struct qm_ceetm_rate er_token_rate;
148009 + u16 cr_token_bucket_limit;
148010 + u16 er_token_bucket_limit;
148011 +};
148012 +
148013 +/* Class Queue Channel */
148014 +struct qm_ceetm_channel {
148015 + struct list_head node;
148016 + unsigned int idx;
148017 + unsigned int lni_idx;
148018 + unsigned int dcp_idx;
148019 + struct list_head class_queues;
148020 + struct list_head ccgs;
148021 + u8 shaper_enable;
148022 + u8 shaper_couple;
148023 + struct qm_ceetm_rate cr_token_rate;
148024 + struct qm_ceetm_rate er_token_rate;
148025 + u16 cr_token_bucket_limit;
148026 + u16 er_token_bucket_limit;
148027 +};
148028 +
148029 +struct qm_ceetm_ccg;
148030 +
148031 +/* This callback type is used when handling congestion entry/exit. The
148032 + * 'cb_ctx' value is the opaque value associated with ccg object.
148033 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
148034 + */
148035 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
148036 + int congested);
148037 +
148038 +/* Class Congestion Group */
148039 +struct qm_ceetm_ccg {
148040 + struct qm_ceetm_channel *parent;
148041 + struct list_head node;
148042 + struct list_head cb_node;
148043 + qman_cb_ccgr cb;
148044 + void *cb_ctx;
148045 + unsigned int idx;
148046 +};
148047 +
148048 +/* Class Queue */
148049 +struct qm_ceetm_cq {
148050 + struct qm_ceetm_channel *parent;
148051 + struct qm_ceetm_ccg *ccg;
148052 + struct list_head node;
148053 + unsigned int idx;
148054 + int is_claimed;
148055 + struct list_head bound_lfqids;
148056 + struct list_head binding_node;
148057 +};
148058 +
148059 +/* Logical Frame Queue */
148060 +struct qm_ceetm_lfq {
148061 + struct qm_ceetm_channel *parent;
148062 + struct list_head node;
148063 + unsigned int idx;
148064 + unsigned int dctidx;
148065 + u64 context_a;
148066 + u32 context_b;
148067 + qman_cb_mr ern;
148068 +};
148069 +
148070 +/**
148071 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
148072 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
148073 + * approximates that rate.
148074 + * @bps: the desired shaper rate in bps.
148075 + * @token_rate: the output token rate computed with the given kbps.
148076 + * @rounding: dictates how to round if an exact conversion is not possible; if
148077 + * it is negative then 'token_rate' will round down to the highest value that
148078 + * does not exceed the desired rate, if it is positive then 'token_rate' will
148079 + * round up to the lowest value that is greater than or equal to the desired
148080 + * rate, and if it is zero then it will round to the nearest approximation,
148081 + * whether that be up or down.
148082 + *
148083 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
148084 + */
148085 +int qman_ceetm_bps2tokenrate(u64 bps,
148086 + struct qm_ceetm_rate *token_rate,
148087 + int rounding);
148088 +
148089 +/**
148090 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
148091 + * corresponding number of 'bps'.
148092 + * @token_rate: the input desired token_rate fraction.
148093 + * @bps: the output shaper rate in bps computed with the give token rate.
148094 + * @rounding: has the same semantics as the previous function.
148095 + *
148096 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
148097 + */
148098 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
148099 + u64 *bps,
148100 + int rounding);
148101 +
148102 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
148103 + int partial);
148104 +static inline int qman_alloc_ceetm0_channel(u32 *result)
148105 +{
148106 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
148107 + return (ret > 0) ? 0 : ret;
148108 +}
148109 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
148110 +static inline void qman_release_ceetm0_channelid(u32 channelid)
148111 +{
148112 + qman_release_ceetm0_channel_range(channelid, 1);
148113 +}
148114 +
148115 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
148116 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
148117 +{
148118 + return qman_reserve_ceetm0_channel_range(channelid, 1);
148119 +}
148120 +
148121 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
148122 +
148123 +
148124 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
148125 + int partial);
148126 +static inline int qman_alloc_ceetm1_channel(u32 *result)
148127 +{
148128 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
148129 + return (ret > 0) ? 0 : ret;
148130 +}
148131 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
148132 +static inline void qman_release_ceetm1_channelid(u32 channelid)
148133 +{
148134 + qman_release_ceetm1_channel_range(channelid, 1);
148135 +}
148136 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
148137 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
148138 +{
148139 + return qman_reserve_ceetm1_channel_range(channelid, 1);
148140 +}
148141 +
148142 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
148143 +
148144 +
148145 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
148146 + int partial);
148147 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
148148 +{
148149 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
148150 + return (ret > 0) ? 0 : ret;
148151 +}
148152 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
148153 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
148154 +{
148155 + qman_release_ceetm0_lfqid_range(lfqid, 1);
148156 +}
148157 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
148158 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
148159 +{
148160 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
148161 +}
148162 +
148163 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
148164 +
148165 +
148166 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
148167 + int partial);
148168 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
148169 +{
148170 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
148171 + return (ret > 0) ? 0 : ret;
148172 +}
148173 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
148174 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
148175 +{
148176 + qman_release_ceetm1_lfqid_range(lfqid, 1);
148177 +}
148178 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
148179 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
148180 +{
148181 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
148182 +}
148183 +
148184 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
148185 +
148186 +
148187 + /* ----------------------------- */
148188 + /* CEETM :: sub-portals */
148189 + /* ----------------------------- */
148190 +
148191 +/**
148192 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
148193 + * to us and configured for traffic-management.
148194 + * @sp: the returned sub-portal object, if successful.
148195 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
148196 + * instance),
148197 + * @sp_idx" is the desired sub-portal index from 0 to 15.
148198 + *
148199 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
148200 + * if the sp_idx is out of range.
148201 + *
148202 + * Note that if there are multiple driver domains (eg. a linux kernel versus
148203 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
148204 + * then a sub-portal may be accessible by more than one instance of a qman
148205 + * driver and so it may be claimed multiple times. If this is the case, it is
148206 + * up to the system architect to prevent conflicting configuration actions
148207 + * coming from the different driver domains. The qman drivers do not have any
148208 + * behind-the-scenes coordination to prevent this from happening.
148209 + */
148210 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
148211 + enum qm_dc_portal dcp_idx,
148212 + unsigned int sp_idx);
148213 +
148214 +/**
148215 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
148216 + * @sp: the sub-portal to be released.
148217 + *
148218 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
148219 + * released.
148220 + */
148221 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
148222 +
148223 + /* ----------------------------------- */
148224 + /* CEETM :: logical network interfaces */
148225 + /* ----------------------------------- */
148226 +
148227 +/**
148228 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
148229 + * @lni: the returned LNI object, if successful.
148230 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
148231 + * instance)
148232 + * @lni_idx: is the desired LNI index.
148233 + *
148234 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
148235 + * is not available or has already been claimed (and not yet successfully
148236 + * released), or lni_dix is out of range.
148237 + *
148238 + * Note that there may be multiple driver domains (or instances) that need to
148239 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
148240 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
148241 + * qman_ceetm_sp_get_lni() for more information.
148242 + */
148243 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
148244 + enum qm_dc_portal dcp_id,
148245 + unsigned int lni_idx);
148246 +
148247 +/**
148248 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
148249 + * @lni: the lni needs to be released.
148250 + *
148251 + * This will only succeed if all dependent objects have been released.
148252 + * Returns zero for success, or -EBUSY if the dependencies are not released.
148253 + */
148254 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
148255 +
148256 +/**
148257 + * qman_ceetm_sp_set_lni
148258 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
148259 + * mapped to.
148260 + * @sp: the given sub-portal.
148261 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
148262 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
148263 + *
148264 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
148265 + * mapping has been set, or configure mapping command returns error, and
148266 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
148267 + * mapping command returns error.
148268 + *
148269 + * This may be useful in situations where multiple driver domains have access
148270 + * to the same sub-portals in order to all be able to transmit out the same
148271 + * physical interface (perhaps they're on different IP addresses or VPNs, so
148272 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
148273 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
148274 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
148275 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
148276 + * in order to determine the LNI that the control-plane had assigned. This is
148277 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
148278 + * LNI object.
148279 + */
148280 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
148281 + struct qm_ceetm_lni *lni);
148282 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
148283 + unsigned int *lni_idx);
148284 +
148285 +/**
148286 + * qman_ceetm_lni_enable_shaper
148287 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
148288 + * @lni: the given LNI.
148289 + * @coupled: indicates whether CR and ER are coupled.
148290 + * @oal: the overhead accounting length which is added to the actual length of
148291 + * each frame when performing shaper calculations.
148292 + *
148293 + * When the number of (unused) committed-rate tokens reach the committed-rate
148294 + * token limit, 'coupled' indicates whether surplus tokens should be added to
148295 + * the excess-rate token count (up to the excess-rate token limit).
148296 + * When LNI is claimed, the shaper is disabled by default. The enable function
148297 + * will turn on this shaper for this lni.
148298 + * Whenever a claimed LNI is first enabled for shaping, its committed and
148299 + * excess token rates and limits are zero, so will need to be changed to do
148300 + * anything useful. The shaper can subsequently be enabled/disabled without
148301 + * resetting the shaping parameters, but the shaping parameters will be reset
148302 + * when the LNI is released.
148303 + *
148304 + * Returns zero for success, or errno for "enable" function in the cases as:
148305 + * a) -EINVAL if the shaper is already enabled,
148306 + * b) -EIO if the configure shaper command returns error.
148307 + * For "disable" function, returns:
148308 + * a) -EINVAL if the shaper is has already disabled.
148309 + * b) -EIO if calling configure shaper command returns error.
148310 + */
148311 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
148312 + int oal);
148313 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
148314 +
148315 +/**
148316 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
148317 + * @lni: the give LNI
148318 + */
148319 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
148320 +
148321 +/**
148322 + * qman_ceetm_lni_set_commit_rate
148323 + * qman_ceetm_lni_get_commit_rate
148324 + * qman_ceetm_lni_set_excess_rate
148325 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
148326 + * token limit for the given LNI.
148327 + * @lni: the given LNI.
148328 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
148329 + * the LNI queried by "get" function.
148330 + * @token_limit: the desired token bucket limit for "set" function, or the token
148331 + * limit of the given LNI queried by "get" function.
148332 + *
148333 + * Returns zero for success. The "set" function returns -EINVAL if the given
148334 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148335 + * The "get" function returns -EINVAL if the token rate or the token limit is
148336 + * not set or the query command returns error.
148337 + */
148338 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
148339 + const struct qm_ceetm_rate *token_rate,
148340 + u16 token_limit);
148341 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
148342 + struct qm_ceetm_rate *token_rate,
148343 + u16 *token_limit);
148344 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
148345 + const struct qm_ceetm_rate *token_rate,
148346 + u16 token_limit);
148347 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
148348 + struct qm_ceetm_rate *token_rate,
148349 + u16 *token_limit);
148350 +/**
148351 + * qman_ceetm_lni_set_commit_rate_bps
148352 + * qman_ceetm_lni_get_commit_rate_bps
148353 + * qman_ceetm_lni_set_excess_rate_bps
148354 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
148355 + * and token limit for the given LNI.
148356 + * @lni: the given LNI.
148357 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
148358 + * of the LNI queried by "get" function.
148359 + * @token_limit: the desired token bucket limit for "set" function, or the token
148360 + * limit of the given LNI queried by "get" function.
148361 + *
148362 + * Returns zero for success. The "set" function returns -EINVAL if the given
148363 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148364 + * The "get" function returns -EINVAL if the token rate or the token limit is
148365 + * not set or the query command returns error.
148366 + */
148367 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
148368 + u64 bps,
148369 + u16 token_limit);
148370 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
148371 + u64 *bps, u16 *token_limit);
148372 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
148373 + u64 bps,
148374 + u16 token_limit);
148375 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
148376 + u64 *bps, u16 *token_limit);
148377 +
148378 +/**
148379 + * qman_ceetm_lni_set_tcfcc
148380 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
148381 + * @lni: the given LNI.
148382 + * @cq_level: is between 0 and 15, representing individual class queue levels
148383 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
148384 + * for every channel).
148385 + * @traffic_class: is between 0 and 7 when associating a given class queue level
148386 + * to a traffic class, or -1 when disabling traffic class flow control for this
148387 + * class queue level.
148388 + *
148389 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
148390 + * of range as indicated above, or -EIO if the configure/query tcfcc command
148391 + * returns error.
148392 + *
148393 + * Refer to the section of QMan CEETM traffic class flow control in the
148394 + * Reference Manual.
148395 + */
148396 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
148397 + unsigned int cq_level,
148398 + int traffic_class);
148399 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
148400 + unsigned int cq_level,
148401 + int *traffic_class);
148402 +
148403 + /* ----------------------------- */
148404 + /* CEETM :: class queue channels */
148405 + /* ----------------------------- */
148406 +
148407 +/**
148408 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
148409 + * the given LNI.
148410 + * @channel: the returned class queue channel object, if successful.
148411 + * @lni: the LNI that the channel belongs to.
148412 + *
148413 + * Channels are always initially "unshaped".
148414 + *
148415 + * Return zero for success, or -ENODEV if there is no channel available(all 32
148416 + * channels are claimed) or -EINVAL if the channel mapping command returns
148417 + * error.
148418 + */
148419 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
148420 + struct qm_ceetm_lni *lni);
148421 +
148422 +/**
148423 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
148424 + * @channel: the channel needs to be released.
148425 + *
148426 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
148427 + *
148428 + * Note any shaping of the channel will be cleared to leave it in an unshaped
148429 + * state.
148430 + */
148431 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
148432 +
148433 +/**
148434 + * qman_ceetm_channel_enable_shaper
148435 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
148436 + * @channel: the given channel.
148437 + * @coupled: indicates whether surplus CR tokens should be added to the
148438 + * excess-rate token count (up to the excess-rate token limit) when the number
148439 + * of (unused) committed-rate tokens reach the committed_rate token limit.
148440 + *
148441 + * Whenever a claimed channel is first enabled for shaping, its committed and
148442 + * excess token rates and limits are zero, so will need to be changed to do
148443 + * anything useful. The shaper can subsequently be enabled/disabled without
148444 + * resetting the shaping parameters, but the shaping parameters will be reset
148445 + * when the channel is released.
148446 + *
148447 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
148448 + * shaper has been enabled/disabled or the management command returns error.
148449 + */
148450 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
148451 + int coupled);
148452 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
148453 +
148454 +/**
148455 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
148456 + * @channel: the give channel.
148457 + */
148458 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
148459 +
148460 +/**
148461 + * qman_ceetm_channel_set_commit_rate
148462 + * qman_ceetm_channel_get_commit_rate
148463 + * qman_ceetm_channel_set_excess_rate
148464 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
148465 + * @channel: the given channel.
148466 + * @token_rate: the desired token rate for "set" function, or the queried token
148467 + * rate for "get" function.
148468 + * @token_limit: the desired token limit for "set" function, or the queried
148469 + * token limit for "get" function.
148470 + *
148471 + * Return zero for success. The "set" function returns -EINVAL if the channel
148472 + * is unshaped, or -EIO if the configure shapper command returns error. The
148473 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148474 + * the query shaper command returns error.
148475 + */
148476 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
148477 + const struct qm_ceetm_rate *token_rate,
148478 + u16 token_limit);
148479 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
148480 + struct qm_ceetm_rate *token_rate,
148481 + u16 *token_limit);
148482 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
148483 + const struct qm_ceetm_rate *token_rate,
148484 + u16 token_limit);
148485 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
148486 + struct qm_ceetm_rate *token_rate,
148487 + u16 *token_limit);
148488 +/**
148489 + * qman_ceetm_channel_set_commit_rate_bps
148490 + * qman_ceetm_channel_get_commit_rate_bps
148491 + * qman_ceetm_channel_set_excess_rate_bps
148492 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
148493 + * parameters.
148494 + * @channel: the given channel.
148495 + * @token_rate: the desired shaper rate in bps for "set" function, or the
148496 + * shaper rate in bps for "get" function.
148497 + * @token_limit: the desired token limit for "set" function, or the queried
148498 + * token limit for "get" function.
148499 + *
148500 + * Return zero for success. The "set" function returns -EINVAL if the channel
148501 + * is unshaped, or -EIO if the configure shapper command returns error. The
148502 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148503 + * the query shaper command returns error.
148504 + */
148505 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
148506 + u64 bps, u16 token_limit);
148507 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
148508 + u64 *bps, u16 *token_limit);
148509 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
148510 + u64 bps, u16 token_limit);
148511 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
148512 + u64 *bps, u16 *token_limit);
148513 +
148514 +/**
148515 + * qman_ceetm_channel_set_weight
148516 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
148517 + * @channel: the given channel.
148518 + * @token_limit: the desired token limit as the weight of the unshaped channel
148519 + * for "set" function, or the queried token limit for "get" function.
148520 + *
148521 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
148522 + * It allows the unshaped channels to be included in the CR time eligible list,
148523 + * and thus use the configured CR token limit value as their fair queuing
148524 + * weight.
148525 + *
148526 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
148527 + * the management command returns error.
148528 + */
148529 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
148530 + u16 token_limit);
148531 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
148532 + u16 *token_limit);
148533 +
148534 +/**
148535 + * qman_ceetm_channel_set_group
148536 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
148537 + * @channel: the given channel.
148538 + * @group_b: indicates whether there is group B in this channel.
148539 + * @prio_a: the priority of group A.
148540 + * @prio_b: the priority of group B.
148541 + *
148542 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
148543 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
148544 + * group A, otherwise they are split into group A (CQ8-11) and group B
148545 + * (CQ12-C15). The individual class queues and the group(s) are in strict
148546 + * priority order relative to each other. Within the group(s), the scheduling
148547 + * is not strict priority order, but the result of scheduling within a group
148548 + * is in strict priority order relative to the other class queues in the
148549 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
148550 + * relative to the individual class queues, and take values from 0-7. Eg. if
148551 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
148552 + * priority order would be;
148553 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
148554 + *
148555 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
148556 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
148557 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
148558 + * the configure scheduler command returns error. For "get" function, return
148559 + * -EINVAL if the query scheduler command returns error.
148560 + */
148561 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
148562 + int group_b,
148563 + unsigned int prio_a,
148564 + unsigned int prio_b);
148565 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
148566 + int *group_b,
148567 + unsigned int *prio_a,
148568 + unsigned int *prio_b);
148569 +
148570 +/**
148571 + * qman_ceetm_channel_set_group_cr_eligibility
148572 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
148573 + * @channel: the given channel object
148574 + * @group_b: indicates whether there is group B in this channel.
148575 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148576 + *
148577 + * Return zero for success, or -EINVAL if eligibility setting fails.
148578 +*/
148579 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
148580 + *channel, int group_b, int cre);
148581 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
148582 + *channel, int group_b, int ere);
148583 +
148584 +/**
148585 + * qman_ceetm_channel_set_cq_cr_eligibility
148586 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
148587 + * @channel: the given channel object
148588 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148589 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148590 + *
148591 + * Return zero for success, or -EINVAL if eligibility setting fails.
148592 +*/
148593 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
148594 + unsigned int idx, int cre);
148595 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
148596 + unsigned int idx, int ere);
148597 +
148598 + /* --------------------- */
148599 + /* CEETM :: class queues */
148600 + /* --------------------- */
148601 +
148602 +/**
148603 + * qman_ceetm_cq_claim - Claims an individual class queue.
148604 + * @cq: the returned class queue object, if successful.
148605 + * @channel: the class queue channel.
148606 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148607 + * @ccg: represents the class congestion group that this class queue should be
148608 + * subscribed to, or NULL if no congestion group membership is desired.
148609 + *
148610 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
148611 + * if this class queue has been claimed, or configure class queue command
148612 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
148613 + */
148614 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
148615 + struct qm_ceetm_channel *channel,
148616 + unsigned int idx,
148617 + struct qm_ceetm_ccg *ccg);
148618 +
148619 +/**
148620 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
148621 + * @cq: the returned class queue object, if successful.
148622 + * @channel: the class queue channel.
148623 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
148624 + * @ccg: represents the class congestion group that this class queue should be
148625 + * subscribed to, or NULL if no congestion group membership is desired.
148626 + *
148627 + * Return zero for success, or -EINVAL if @idx is out the range or if
148628 + * this class queue has been claimed or configure class queue command returns
148629 + * error, or returns -ENOMEM if allocating CQ memory fails.
148630 + */
148631 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
148632 + struct qm_ceetm_channel *channel,
148633 + unsigned int idx,
148634 + struct qm_ceetm_ccg *ccg);
148635 +
148636 +/**
148637 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
148638 + * @cq: the returned class queue object, if successful.
148639 + * @channel: the class queue channel.
148640 + * @idx: is from 0 to 3 (CQ12 to CQ15).
148641 + * @ccg: represents the class congestion group that this class queue should be
148642 + * subscribed to, or NULL if no congestion group membership is desired.
148643 + *
148644 + * Return zero for success, or -EINVAL if @idx is out the range or if
148645 + * this class queue has been claimed or configure class queue command returns
148646 + * error, or returns -ENOMEM if allocating CQ memory fails.
148647 + */
148648 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
148649 + struct qm_ceetm_channel *channel,
148650 + unsigned int idx,
148651 + struct qm_ceetm_ccg *ccg);
148652 +
148653 +/**
148654 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
148655 + * @cq: The class queue to be released.
148656 + *
148657 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
148658 + * FQIDs) have not been released.
148659 + */
148660 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
148661 +
148662 +/**
148663 + * qman_ceetm_set_queue_weight
148664 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
148665 + * queue.
148666 + * @cq: the given class queue.
148667 + * @weight_code: the desired weight code to set for the given class queue for
148668 + * "set" function or the queired weight code for "get" function.
148669 + *
148670 + * Grouped class queues have a default weight code of zero, which corresponds to
148671 + * a scheduler weighting of 1. This function can be used to modify a grouped
148672 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
148673 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
148674 + * and the corresponding sharing weight.)
148675 + *
148676 + * Returns zero for success, or -EIO if the configure weight command returns
148677 + * error for "set" function, or -EINVAL if the query command returns
148678 + * error for "get" function.
148679 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
148680 + * Manual for weight and weight code.
148681 + */
148682 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
148683 + struct qm_ceetm_weight_code *weight_code);
148684 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
148685 + struct qm_ceetm_weight_code *weight_code);
148686 +
148687 +/**
148688 + * qman_ceetm_set_queue_weight_in_ratio
148689 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
148690 + * grouped class queue.
148691 + * @cq: the given class queue.
148692 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
148693 + * by 100 to get rid of fraction.
148694 + *
148695 + * Returns zero for success, or -EIO if the configure weight command returns
148696 + * error for "set" function, or -EINVAL if the query command returns
148697 + * error for "get" function.
148698 + */
148699 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
148700 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
148701 +
148702 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
148703 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
148704 + * corresponding to intermediate weight codes are calculated using linear
148705 + * interpolation on the inverted values. Or put another way, the inverse weights
148706 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
148707 + * between these are divided linearly into 32 intermediate values, the inverses
148708 + * of which form the remaining weight codes.
148709 + *
148710 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
148711 + * scheduling within a group of class queues (group A or B). Weights are used to
148712 + * normalise the class queues to an underlying BFS algorithm where all class
148713 + * queues are assumed to require "equal bandwidth". So the weights referred to
148714 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
148715 + * one class queue in a group is assigned a weight of 2 whilst the other class
148716 + * queues in the group keep the default weight of 1, then the WBFS scheduler
148717 + * will effectively treat all frames enqueued on the weight-2 class queue as
148718 + * having half the number of bytes they really have. Ie. if all other things are
148719 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
148720 + * the others. So weights should be chosen to provide bandwidth ratios between
148721 + * members of the same class queue group. These weights have no bearing on
148722 + * behaviour outside that group's WBFS mechanism though.
148723 + */
148724 +
148725 +/**
148726 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
148727 + * representation of the corresponding weight is given (in order to not lose
148728 + * any precision).
148729 + * @weight_code: The given weight code in WBFS.
148730 + * @numerator: the numerator part of the weight computed by the weight code.
148731 + * @denominator: the denominator part of the weight computed by the weight code
148732 + *
148733 + * Returns zero for success or -EINVAL if the given weight code is illegal.
148734 + */
148735 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
148736 + u32 *numerator,
148737 + u32 *denominator);
148738 +/**
148739 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148740 + * If the user needs to know how close this is, convert the resulting weight
148741 + * code back to a weight and compare.
148742 + * @numerator: numerator part of the given weight.
148743 + * @denominator: denominator part of the given weight.
148744 + * @weight_code: the weight code computed from the given weight.
148745 + *
148746 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148747 + * the range of weights.
148748 + */
148749 +int qman_ceetm_ratio2wbfs(u32 numerator,
148750 + u32 denominator,
148751 + struct qm_ceetm_weight_code *weight_code,
148752 + int rounding);
148753 +
148754 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148755 +/**
148756 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148757 + * CQ counters.
148758 + * @cq: the given CQ object.
148759 + * @flags: indicates whether the statistics counter will be cleared after query.
148760 + * @frame_count: The number of the frames that have been counted since the
148761 + * counter was cleared last time.
148762 + * @byte_count: the number of bytes in all frames that have been counted.
148763 + *
148764 + * Return zero for success or -EINVAL if query statistics command returns error.
148765 + *
148766 + */
148767 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148768 + u64 *frame_count, u64 *byte_count);
148769 +
148770 +/**
148771 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148772 + * @cq: the give CQ object.
148773 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148774 + */
148775 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148776 +
148777 + /* ---------------------- */
148778 + /* CEETM :: logical FQIDs */
148779 + /* ---------------------- */
148780 +/**
148781 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148782 + * the given class queue.
148783 + * @lfq: the returned lfq object, if successful.
148784 + * @cq: the class queue which needs to claim a LFQID.
148785 + *
148786 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148787 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148788 + */
148789 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148790 + struct qm_ceetm_cq *cq);
148791 +
148792 +/**
148793 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148794 + * @lfq: the lfq to be released.
148795 + *
148796 + * Return zero for success.
148797 + */
148798 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
148799 +
148800 +/**
148801 + * qman_ceetm_lfq_set_context
148802 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
148803 + * "dequeue context table" associated with the logical FQID.
148804 + * @lfq: the given logical FQ object.
148805 + * @context_a: contextA of the dequeue context.
148806 + * @context_b: contextB of the dequeue context.
148807 + *
148808 + * Returns zero for success, or -EINVAL if there is error to set/get the
148809 + * context pair.
148810 + */
148811 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
148812 + u64 context_a,
148813 + u32 context_b);
148814 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
148815 + u64 *context_a,
148816 + u32 *context_b);
148817 +
148818 +/**
148819 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
148820 + * @lfq: the given logic fq.
148821 + * @fq: the fq object created for the given logic fq.
148822 + *
148823 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
148824 + * target a logical FQID (and the class queue it is associated with).
148825 + * Note that this FQ object can only be used for enqueues, and
148826 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
148827 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
148828 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
148829 + * responsibility to ensure that the underlying 'lfq' is not released until any
148830 + * enqueues to this FQ object have completed. The only field the user needs to
148831 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
148832 + * could conceivably be called on this FQ object. This API can be called
148833 + * multiple times to create multiple FQ objects referring to the same logical
148834 + * FQID, and any enqueue rejections will respect the callback of the object that
148835 + * issued the enqueue (and will identify the object via the parameter passed to
148836 + * the callback too). There is no 'flags' parameter to this API as there is for
148837 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
148838 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
148839 + *
148840 + * Returns 0 for success.
148841 + */
148842 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
148843 +
148844 + /* -------------------------------- */
148845 + /* CEETM :: class congestion groups */
148846 + /* -------------------------------- */
148847 +
148848 +/**
148849 + * qman_ceetm_ccg_claim - Claims an unused CCG.
148850 + * @ccg: the returned CCG object, if successful.
148851 + * @channel: the given class queue channel
148852 + * @cscn: the callback function of this CCG.
148853 + * @cb_ctx: the corresponding context to be used used if state change
148854 + * notifications are later enabled for this CCG.
148855 + *
148856 + * The congestion group is local to the given class queue channel, so only
148857 + * class queues within the channel can be associated with that congestion group.
148858 + * The association of class queues to congestion groups occurs when the class
148859 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
148860 + * Congestion groups are in a "zero" state when initially claimed, and they are
148861 + * returned to that state when released.
148862 + *
148863 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
148864 + */
148865 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
148866 + struct qm_ceetm_channel *channel,
148867 + unsigned int idx,
148868 + void (*cscn)(struct qm_ceetm_ccg *,
148869 + void *cb_ctx,
148870 + int congested),
148871 + void *cb_ctx);
148872 +
148873 +/**
148874 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
148875 + * @ccg: the given ccg.
148876 + *
148877 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
148878 + * (class queues that are associated with the CCG) have not been released.
148879 + */
148880 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
148881 +
148882 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
148883 + * controls which CCG attributes are to be updated, and the remainder specify
148884 + * the values for those attributes. A CCG counts either frames or the bytes
148885 + * within those frames, but not both ('mode'). A CCG can optionally cause
148886 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
148887 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
148888 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
148889 + * to a "congestion state", but not both ('td_mode'). Congestion state has
148890 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
148891 + * notifications can be sent to software the CCG goes in to and out of this
148892 + * congested state ('cscn_en'). */
148893 +struct qm_ceetm_ccg_params {
148894 + /* Boolean fields together in a single bitfield struct */
148895 + struct {
148896 + /* Whether to count bytes or frames. 1==frames */
148897 + u8 mode:1;
148898 + /* En/disable tail-drop. 1==enable */
148899 + u8 td_en:1;
148900 + /* Tail-drop on congestion-state or threshold. 1=threshold */
148901 + u8 td_mode:1;
148902 + /* Generate congestion state change notifications. 1==enable */
148903 + u8 cscn_en:1;
148904 + /* Enable WRED rejections (per colour). 1==enable */
148905 + u8 wr_en_g:1;
148906 + u8 wr_en_y:1;
148907 + u8 wr_en_r:1;
148908 + } __packed;
148909 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
148910 + struct qm_cgr_cs_thres td_thres;
148911 + /* Congestion state thresholds, for entry and exit. */
148912 + struct qm_cgr_cs_thres cs_thres_in;
148913 + struct qm_cgr_cs_thres cs_thres_out;
148914 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
148915 + signed char oal;
148916 + /* Congestion state change notification for DCP portal, virtual CCGID*/
148917 + /* WRED parameters. */
148918 + struct qm_cgr_wr_parm wr_parm_g;
148919 + struct qm_cgr_wr_parm wr_parm_y;
148920 + struct qm_cgr_wr_parm wr_parm_r;
148921 +};
148922 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
148923 + * the CCGR are to be updated. */
148924 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
148925 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
148926 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
148927 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
148928 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
148929 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
148930 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
148931 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
148932 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
148933 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
148934 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
148935 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
148936 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
148937 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
148938 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
148939 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
148940 +
148941 +/**
148942 + * qman_ceetm_ccg_set
148943 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
148944 + * @ccg: the given CCG object.
148945 + * @we_mask: the write enable mask.
148946 + * @params: the parameters setting for this ccg
148947 + *
148948 + * Return 0 for success, or -EIO if configure ccg command returns error for
148949 + * "set" function, or -EINVAL if query ccg command returns error for "get"
148950 + * function.
148951 + */
148952 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
148953 + u16 we_mask,
148954 + const struct qm_ceetm_ccg_params *params);
148955 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
148956 + struct qm_ceetm_ccg_params *params);
148957 +
148958 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
148959 + * mask.
148960 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
148961 + * in the cscn target mask.
148962 + * @ccg: the give CCG object.
148963 + * @swp_idx: the index of the software portal.
148964 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
148965 + * the target mask.
148966 + * @we_mask: the write enable mask.
148967 + * @params: the parameters setting for this ccg
148968 + *
148969 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148970 + */
148971 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
148972 + u16 swp_idx,
148973 + unsigned int cscn_enabled,
148974 + u16 we_mask,
148975 + const struct qm_ceetm_ccg_params *params);
148976 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
148977 + u16 swp_idx,
148978 + unsigned int *cscn_enabled);
148979 +
148980 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
148981 + * target mask.
148982 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
148983 + * is in the cscn target mask.
148984 + * @ccg: the give CCG object.
148985 + * @dcp_idx: the index of the direct connect portal.
148986 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
148987 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
148988 + * the target mask.
148989 + * @we_mask: the write enable mask.
148990 + * @params: the parameters setting for this ccg
148991 + *
148992 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148993 + */
148994 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
148995 + u16 dcp_idx,
148996 + u8 vcgid,
148997 + unsigned int cscn_enabled,
148998 + u16 we_mask,
148999 + const struct qm_ceetm_ccg_params *params);
149000 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
149001 + u16 dcp_idx,
149002 + u8 *vcgid,
149003 + unsigned int *cscn_enabled);
149004 +
149005 +/**
149006 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
149007 + * CEETM CCG counters.
149008 + * @ccg: the given CCG object.
149009 + * @flags: indicates whether the statistics counter will be cleared after query.
149010 + * @frame_count: The number of the frames that have been counted since the
149011 + * counter was cleared last time.
149012 + * @byte_count: the number of bytes in all frames that have been counted.
149013 + *
149014 + * Return zero for success or -EINVAL if query statistics command returns error.
149015 + *
149016 + */
149017 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
149018 + u64 *frame_count, u64 *byte_count);
149019 +
149020 +/**
149021 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
149022 + * @lfqid: Logical Frame Queue ID
149023 + * @lfqmt_query: Results of the query command
149024 + *
149025 + * Returns zero for success or -EIO if the query command returns error.
149026 + *
149027 + */
149028 +int qman_ceetm_query_lfqmt(int lfqid,
149029 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
149030 +
149031 +/**
149032 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
149033 + * @cid: Target ID (CQID or CCGRID)
149034 + * @dcp_idx: CEETM portal ID
149035 + * @command_type: One of the following:
149036 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
149037 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
149038 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
149039 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
149040 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
149041 + * 5 = Write reject statistics. CID carries the CCGRID to be written
149042 + * @frame_count: Frame count value to be written if this is a write command
149043 + * @byte_count: Bytes count value to be written if this is a write command
149044 + *
149045 + * Returns zero for success or -EIO if the query command returns error.
149046 + */
149047 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
149048 + u16 command_type, u64 frame_count,
149049 + u64 byte_count);
149050 +
149051 +/**
149052 + * qman_set_wpm - Set waterfall power management
149053 + *
149054 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
149055 + *
149056 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
149057 + * accessible.
149058 + */
149059 +int qman_set_wpm(int wpm_enable);
149060 +
149061 +/**
149062 + * qman_get_wpm - Query the waterfall power management setting
149063 + *
149064 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
149065 + *
149066 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
149067 + * accessible.
149068 + */
149069 +int qman_get_wpm(int *wpm_enable);
149070 +
149071 +/* The below qman_p_***() variants might be called in a migration situation
149072 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
149073 + * execution was affine to prior to migration.
149074 + * @qman_portal specifies which portal the APIs will use.
149075 +*/
149076 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
149077 + *p);
149078 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
149079 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
149080 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
149081 +u32 qman_p_poll_slow(struct qman_portal *p);
149082 +void qman_p_poll(struct qman_portal *p);
149083 +void qman_p_stop_dequeues(struct qman_portal *p);
149084 +void qman_p_start_dequeues(struct qman_portal *p);
149085 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
149086 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
149087 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
149088 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
149089 + int park_request);
149090 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
149091 + u32 flags __maybe_unused, u32 vdqcr);
149092 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
149093 + const struct qm_fd *fd, u32 flags);
149094 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
149095 + const struct qm_fd *fd, u32 flags,
149096 + struct qman_fq *orp, u16 orp_seqnum);
149097 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
149098 + const struct qm_fd *fd, u32 flags,
149099 + qman_cb_precommit cb, void *cb_arg);
149100 +#ifdef __cplusplus
149101 +}
149102 +#endif
149103 +
149104 +#endif /* FSL_QMAN_H */
149105 diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h
149106 new file mode 100644
149107 index 00000000..381853de
149108 --- /dev/null
149109 +++ b/include/linux/fsl_usdpaa.h
149110 @@ -0,0 +1,372 @@
149111 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
149112 + *
149113 + * This file is licensed under the terms of the GNU General Public License
149114 + * version 2. This program is licensed "as is" without any warranty of any
149115 + * kind, whether express or implied.
149116 + */
149117 +
149118 +#ifndef FSL_USDPAA_H
149119 +#define FSL_USDPAA_H
149120 +
149121 +#ifdef __cplusplus
149122 +extern "C" {
149123 +#endif
149124 +
149125 +#include <linux/uaccess.h>
149126 +#include <linux/ioctl.h>
149127 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
149128 +#include <linux/compat.h>
149129 +
149130 +#ifdef CONFIG_FSL_USDPAA
149131 +
149132 +/******************************/
149133 +/* Allocation of resource IDs */
149134 +/******************************/
149135 +
149136 +/* This enum is used to distinguish between the type of underlying object being
149137 + * manipulated. */
149138 +enum usdpaa_id_type {
149139 + usdpaa_id_fqid,
149140 + usdpaa_id_bpid,
149141 + usdpaa_id_qpool,
149142 + usdpaa_id_cgrid,
149143 + usdpaa_id_ceetm0_lfqid,
149144 + usdpaa_id_ceetm0_channelid,
149145 + usdpaa_id_ceetm1_lfqid,
149146 + usdpaa_id_ceetm1_channelid,
149147 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
149148 +};
149149 +#define USDPAA_IOCTL_MAGIC 'u'
149150 +struct usdpaa_ioctl_id_alloc {
149151 + uint32_t base; /* Return value, the start of the allocated range */
149152 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
149153 + uint32_t num; /* how many IDs to allocate (and return value) */
149154 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
149155 + int partial; /* whether to allow less than 'num' */
149156 +};
149157 +struct usdpaa_ioctl_id_release {
149158 + /* Input; */
149159 + enum usdpaa_id_type id_type;
149160 + uint32_t base;
149161 + uint32_t num;
149162 +};
149163 +struct usdpaa_ioctl_id_reserve {
149164 + enum usdpaa_id_type id_type;
149165 + uint32_t base;
149166 + uint32_t num;
149167 +};
149168 +
149169 +
149170 +/* ioctl() commands */
149171 +#define USDPAA_IOCTL_ID_ALLOC \
149172 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
149173 +#define USDPAA_IOCTL_ID_RELEASE \
149174 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
149175 +#define USDPAA_IOCTL_ID_RESERVE \
149176 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
149177 +
149178 +/**********************/
149179 +/* Mapping DMA memory */
149180 +/**********************/
149181 +
149182 +/* Maximum length for a map name, including NULL-terminator */
149183 +#define USDPAA_DMA_NAME_MAX 16
149184 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
149185 + * For a sharable and named map, specify _SHARED (whether creating one or
149186 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
149187 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
149188 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
149189 + * specified and the mapping already exists, the mapping will fail unless _LAZY
149190 + * is specified. When mapping to a pre-existing sharable map, the length must be
149191 + * an exact match. Lengths must be a power-of-4 multiple of page size.
149192 + *
149193 + * Note that this does not actually map the memory to user-space, that is done
149194 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
149195 + * ioctl() is what gives the process permission to do this, and a page-offset
149196 + * with which to do so.
149197 + */
149198 +#define USDPAA_DMA_FLAG_SHARE 0x01
149199 +#define USDPAA_DMA_FLAG_CREATE 0x02
149200 +#define USDPAA_DMA_FLAG_LAZY 0x04
149201 +#define USDPAA_DMA_FLAG_RDONLY 0x08
149202 +struct usdpaa_ioctl_dma_map {
149203 + /* Output parameters - virtual and physical addresses */
149204 + void *ptr;
149205 + uint64_t phys_addr;
149206 + /* Input parameter, the length of the region to be created (or if
149207 + * mapping an existing region, this must match it). Must be a power-of-4
149208 + * multiple of page size. */
149209 + uint64_t len;
149210 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
149211 + uint32_t flags;
149212 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
149213 + * of the existing mapping to use). */
149214 + char name[USDPAA_DMA_NAME_MAX];
149215 + /* If this ioctl() creates the mapping, this is an input parameter
149216 + * stating whether the region supports locking. If mapping an existing
149217 + * region, this is a return value indicating the same thing. */
149218 + int has_locking;
149219 + /* In the case of a successful map with _CREATE and _LAZY, this return
149220 + * value indicates whether we created the mapped region or whether it
149221 + * already existed. */
149222 + int did_create;
149223 +};
149224 +
149225 +#ifdef CONFIG_COMPAT
149226 +struct usdpaa_ioctl_dma_map_compat {
149227 + /* Output parameters - virtual and physical addresses */
149228 + compat_uptr_t ptr;
149229 + uint64_t phys_addr;
149230 + /* Input parameter, the length of the region to be created (or if
149231 + * mapping an existing region, this must match it). Must be a power-of-4
149232 + * multiple of page size. */
149233 + uint64_t len;
149234 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
149235 + uint32_t flags;
149236 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
149237 + * of the existing mapping to use). */
149238 + char name[USDPAA_DMA_NAME_MAX];
149239 + /* If this ioctl() creates the mapping, this is an input parameter
149240 + * stating whether the region supports locking. If mapping an existing
149241 + * region, this is a return value indicating the same thing. */
149242 + int has_locking;
149243 + /* In the case of a successful map with _CREATE and _LAZY, this return
149244 + * value indicates whether we created the mapped region or whether it
149245 + * already existed. */
149246 + int did_create;
149247 +};
149248 +
149249 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
149250 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
149251 +#endif
149252 +
149253 +
149254 +#define USDPAA_IOCTL_DMA_MAP \
149255 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
149256 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
149257 + * This ioctl will do both (though you can munmap() before calling the ioctl
149258 + * too). */
149259 +#define USDPAA_IOCTL_DMA_UNMAP \
149260 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
149261 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
149262 + * with a mmap()'d address, and the process will (interruptible) sleep if the
149263 + * lock is already held by another process. Process destruction will
149264 + * automatically clean up any held locks. */
149265 +#define USDPAA_IOCTL_DMA_LOCK \
149266 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
149267 +#define USDPAA_IOCTL_DMA_UNLOCK \
149268 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
149269 +
149270 +/***************************************/
149271 +/* Mapping and using QMan/BMan portals */
149272 +/***************************************/
149273 +enum usdpaa_portal_type {
149274 + usdpaa_portal_qman,
149275 + usdpaa_portal_bman,
149276 +};
149277 +
149278 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
149279 +
149280 +struct usdpaa_ioctl_portal_map {
149281 + /* Input parameter, is a qman or bman portal required. */
149282 +
149283 + enum usdpaa_portal_type type;
149284 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149285 + for don't care. The portal index will be populated by the
149286 + driver when the ioctl() successfully completes */
149287 + uint32_t index;
149288 +
149289 + /* Return value if the map succeeds, this gives the mapped
149290 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149291 + struct usdpaa_portal_map {
149292 + void *cinh;
149293 + void *cena;
149294 + } addr;
149295 + /* Qman-specific return values */
149296 + uint16_t channel;
149297 + uint32_t pools;
149298 +};
149299 +
149300 +#ifdef CONFIG_COMPAT
149301 +struct compat_usdpaa_ioctl_portal_map {
149302 + /* Input parameter, is a qman or bman portal required. */
149303 + enum usdpaa_portal_type type;
149304 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149305 + for don't care. The portal index will be populated by the
149306 + driver when the ioctl() successfully completes */
149307 + uint32_t index;
149308 + /* Return value if the map succeeds, this gives the mapped
149309 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149310 + struct usdpaa_portal_map_compat {
149311 + compat_uptr_t cinh;
149312 + compat_uptr_t cena;
149313 + } addr;
149314 + /* Qman-specific return values */
149315 + uint16_t channel;
149316 + uint32_t pools;
149317 +};
149318 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
149319 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
149320 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
149321 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
149322 +#endif
149323 +
149324 +#define USDPAA_IOCTL_PORTAL_MAP \
149325 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
149326 +#define USDPAA_IOCTL_PORTAL_UNMAP \
149327 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
149328 +
149329 +struct usdpaa_ioctl_irq_map {
149330 + enum usdpaa_portal_type type; /* Type of portal to map */
149331 + int fd; /* File descriptor that contains the portal */
149332 + void *portal_cinh; /* Cache inhibited area to identify the portal */
149333 +};
149334 +
149335 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
149336 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
149337 +
149338 +#ifdef CONFIG_COMPAT
149339 +
149340 +struct compat_ioctl_irq_map {
149341 + enum usdpaa_portal_type type; /* Type of portal to map */
149342 + compat_int_t fd; /* File descriptor that contains the portal */
149343 + compat_uptr_t portal_cinh; /* Used identify the portal */};
149344 +
149345 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
149346 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
149347 +#endif
149348 +
149349 +/* ioctl to query the amount of DMA memory used in the system */
149350 +struct usdpaa_ioctl_dma_used {
149351 + uint64_t free_bytes;
149352 + uint64_t total_bytes;
149353 +};
149354 +#define USDPAA_IOCTL_DMA_USED \
149355 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
149356 +
149357 +/* ioctl to allocate a raw portal */
149358 +struct usdpaa_ioctl_raw_portal {
149359 + /* inputs */
149360 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149361 +
149362 + /* set to non zero to turn on stashing */
149363 + uint8_t enable_stash;
149364 + /* Stashing attributes for the portal */
149365 + uint32_t cpu;
149366 + uint32_t cache;
149367 + uint32_t window;
149368 +
149369 + /* Specifies the stash request queue this portal should use */
149370 + uint8_t sdest;
149371 +
149372 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149373 + * for don't care. The portal index will be populated by the
149374 + * driver when the ioctl() successfully completes */
149375 + uint32_t index;
149376 +
149377 + /* outputs */
149378 + uint64_t cinh;
149379 + uint64_t cena;
149380 +};
149381 +
149382 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
149383 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
149384 +
149385 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
149386 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
149387 +
149388 +#ifdef CONFIG_COMPAT
149389 +
149390 +struct compat_ioctl_raw_portal {
149391 + /* inputs */
149392 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149393 +
149394 + /* set to non zero to turn on stashing */
149395 + uint8_t enable_stash;
149396 + /* Stashing attributes for the portal */
149397 + uint32_t cpu;
149398 + uint32_t cache;
149399 + uint32_t window;
149400 + /* Specifies the stash request queue this portal should use */
149401 + uint8_t sdest;
149402 +
149403 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149404 + * for don't care. The portal index will be populated by the
149405 + * driver when the ioctl() successfully completes */
149406 + uint32_t index;
149407 +
149408 + /* outputs */
149409 + uint64_t cinh;
149410 + uint64_t cena;
149411 +};
149412 +
149413 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
149414 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
149415 +
149416 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
149417 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
149418 +
149419 +#endif
149420 +
149421 +#ifdef __KERNEL__
149422 +
149423 +/* Early-boot hook */
149424 +int __init fsl_usdpaa_init_early(void);
149425 +
149426 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
149427 + * faults within its ranges via this hook. */
149428 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
149429 +
149430 +#endif /* __KERNEL__ */
149431 +
149432 +#endif /* CONFIG_FSL_USDPAA */
149433 +
149434 +#ifdef __KERNEL__
149435 +/* This interface is needed in a few places and though it's not specific to
149436 + * USDPAA as such, creating a new header for it doesn't make any sense. The
149437 + * qbman kernel driver implements this interface and uses it as the backend for
149438 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
149439 + * interface for tracking per-process allocations handed out to user-space. */
149440 +struct dpa_alloc {
149441 + struct list_head free;
149442 + spinlock_t lock;
149443 + struct list_head used;
149444 +};
149445 +#define DECLARE_DPA_ALLOC(name) \
149446 + struct dpa_alloc name = { \
149447 + .free = { \
149448 + .prev = &name.free, \
149449 + .next = &name.free \
149450 + }, \
149451 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
149452 + .used = { \
149453 + .prev = &name.used, \
149454 + .next = &name.used \
149455 + } \
149456 + }
149457 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
149458 +{
149459 + INIT_LIST_HEAD(&alloc->free);
149460 + INIT_LIST_HEAD(&alloc->used);
149461 + spin_lock_init(&alloc->lock);
149462 +}
149463 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
149464 + int partial);
149465 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
149466 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
149467 +
149468 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
149469 + * desired range is not available, or 0 for success. */
149470 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
149471 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
149472 + * 'alloc' is empty. */
149473 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
149474 +/* Returns 1 if the specified id is alloced, 0 otherwise */
149475 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
149476 +#endif /* __KERNEL__ */
149477 +
149478 +#ifdef __cplusplus
149479 +}
149480 +#endif
149481 +
149482 +#endif /* FSL_USDPAA_H */
149483 diff --git a/include/uapi/linux/fmd/Kbuild b/include/uapi/linux/fmd/Kbuild
149484 new file mode 100644
149485 index 00000000..56a20401
149486 --- /dev/null
149487 +++ b/include/uapi/linux/fmd/Kbuild
149488 @@ -0,0 +1,5 @@
149489 +header-y += integrations/
149490 +header-y += Peripherals/
149491 +
149492 +header-y += ioctls.h
149493 +header-y += net_ioctls.h
149494 diff --git a/include/uapi/linux/fmd/Peripherals/Kbuild b/include/uapi/linux/fmd/Peripherals/Kbuild
149495 new file mode 100644
149496 index 00000000..43883efe
149497 --- /dev/null
149498 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
149499 @@ -0,0 +1,4 @@
149500 +header-y += fm_ioctls.h
149501 +header-y += fm_port_ioctls.h
149502 +header-y += fm_pcd_ioctls.h
149503 +header-y += fm_test_ioctls.h
149504 diff --git a/include/uapi/linux/fmd/Peripherals/fm_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149505 new file mode 100644
149506 index 00000000..e0c2dd31
149507 --- /dev/null
149508 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149509 @@ -0,0 +1,628 @@
149510 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149511 + * All rights reserved.
149512 + *
149513 + * Redistribution and use in source and binary forms, with or without
149514 + * modification, are permitted provided that the following conditions are met:
149515 + * * Redistributions of source code must retain the above copyright
149516 + * notice, this list of conditions and the following disclaimer.
149517 + * * Redistributions in binary form must reproduce the above copyright
149518 + * notice, this list of conditions and the following disclaimer in the
149519 + * documentation and/or other materials provided with the distribution.
149520 + * * Neither the name of Freescale Semiconductor nor the
149521 + * names of its contributors may be used to endorse or promote products
149522 + * derived from this software without specific prior written permission.
149523 + *
149524 + *
149525 + * ALTERNATIVELY, this software may be distributed under the terms of the
149526 + * GNU General Public License ("GPL") as published by the Free Software
149527 + * Foundation, either version 2 of that License or (at your option) any
149528 + * later version.
149529 + *
149530 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149531 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149532 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149533 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149534 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149535 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149536 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149537 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149538 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149539 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149540 + */
149541 +
149542 +/**************************************************************************//**
149543 + @File fm_ioctls.h
149544 +
149545 + @Description FM Char device ioctls
149546 +*//***************************************************************************/
149547 +#ifndef __FM_IOCTLS_H
149548 +#define __FM_IOCTLS_H
149549 +
149550 +
149551 +/**************************************************************************//**
149552 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149553 +
149554 + @Description FM Linux ioctls definitions and enums
149555 +
149556 + @{
149557 +*//***************************************************************************/
149558 +
149559 +/**************************************************************************//**
149560 + @Collection FM IOCTL device ('/dev') definitions
149561 +*//***************************************************************************/
149562 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
149563 +
149564 +#define DEV_FM_MINOR_BASE 0
149565 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
149566 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
149567 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
149568 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
149569 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
149570 +
149571 +#define FM_IOC_NUM(n) (n)
149572 +#define FM_PCD_IOC_NUM(n) (n+20)
149573 +#define FM_PORT_IOC_NUM(n) (n+70)
149574 +/* @} */
149575 +
149576 +#define IOC_FM_MAX_NUM_OF_PORTS 64
149577 +
149578 +
149579 +/**************************************************************************//**
149580 + @Description Enum for defining port types
149581 + (must match enum e_FmPortType defined in fm_ext.h)
149582 +*//***************************************************************************/
149583 +typedef enum ioc_fm_port_type {
149584 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
149585 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
149586 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
149587 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
149588 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
149589 + e_IOC_FM_PORT_TYPE_DUMMY
149590 +} ioc_fm_port_type;
149591 +
149592 +
149593 +/**************************************************************************//**
149594 + @Group lnx_ioctl_FM_lib_grp FM library
149595 +
149596 + @Description FM API functions, definitions and enums
149597 + The FM module is the main driver module and is a mandatory module
149598 + for FM driver users. Before any further module initialization,
149599 + this module must be initialized.
149600 + The FM is a "single-tone" module. It is responsible of the common
149601 + HW modules: FPM, DMA, common QMI, common BMI initializations and
149602 + run-time control routines. This module must be initialized always
149603 + when working with any of the FM modules.
149604 + NOTE - We assumes that the FML will be initialize only by core No. 0!
149605 +
149606 + @{
149607 +*//***************************************************************************/
149608 +
149609 +/**************************************************************************//**
149610 + @Description FM Exceptions
149611 +*//***************************************************************************/
149612 +typedef enum ioc_fm_exceptions {
149613 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
149614 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
149615 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
149616 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
149617 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
149618 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
149619 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
149620 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
149621 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
149622 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
149623 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
149624 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
149625 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
149626 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
149627 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
149628 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
149629 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
149630 +} ioc_fm_exceptions;
149631 +
149632 +/**************************************************************************//**
149633 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
149634 +
149635 + @Description FM Runtime control unit API functions, definitions and enums.
149636 + The FM driver provides a set of control routines for each module.
149637 + These routines may only be called after the module was fully
149638 + initialized (both configuration and initialization routines were
149639 + called). They are typically used to get information from hardware
149640 + (status, counters/statistics, revision etc.), to modify a current
149641 + state or to force/enable a required action. Run-time control may
149642 + be called whenever necessary and as many times as needed.
149643 + @{
149644 +*//***************************************************************************/
149645 +
149646 +/**************************************************************************//**
149647 + @Collection General FM defines.
149648 + *//***************************************************************************/
149649 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
149650 + FM_MAX_NUM_OF_1G_RX_PORTS + \
149651 + FM_MAX_NUM_OF_10G_RX_PORTS + \
149652 + FM_MAX_NUM_OF_1G_TX_PORTS + \
149653 + FM_MAX_NUM_OF_10G_TX_PORTS)
149654 +/* @} */
149655 +
149656 +/**************************************************************************//**
149657 + @Description Structure for Port bandwidth requirement. Port is identified
149658 + by type and relative id.
149659 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
149660 +*//***************************************************************************/
149661 +typedef struct ioc_fm_port_bandwidth_t {
149662 + ioc_fm_port_type type; /**< FM port type */
149663 + uint8_t relative_port_id; /**< Type relative port id */
149664 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
149665 +} ioc_fm_port_bandwidth_t;
149666 +
149667 +/**************************************************************************//**
149668 + @Description A Structure containing an array of Port bandwidth requirements.
149669 + The user should state the ports requiring bandwidth in terms of
149670 + percentage - i.e. all port's bandwidths in the array must add
149671 + up to 100.
149672 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
149673 +*//***************************************************************************/
149674 +typedef struct ioc_fm_port_bandwidth_params {
149675 + uint8_t num_of_ports;
149676 + /**< num of ports listed in the array below */
149677 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
149678 + /**< for each port, it's bandwidth (all port's
149679 + bandwidths must add up to 100.*/
149680 +} ioc_fm_port_bandwidth_params;
149681 +
149682 +/**************************************************************************//**
149683 + @Description enum for defining FM counters
149684 +*//***************************************************************************/
149685 +typedef enum ioc_fm_counters {
149686 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
149687 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
149688 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
149689 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
149690 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
149691 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
149692 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
149693 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
149694 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
149695 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
149696 +} ioc_fm_counters;
149697 +
149698 +typedef struct ioc_fm_obj_t {
149699 + void *obj;
149700 +} ioc_fm_obj_t;
149701 +
149702 +/**************************************************************************//**
149703 + @Description A structure for returning revision information
149704 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
149705 +*//***************************************************************************/
149706 +typedef struct ioc_fm_revision_info_t {
149707 + uint8_t major; /**< Major revision */
149708 + uint8_t minor; /**< Minor revision */
149709 +} ioc_fm_revision_info_t;
149710 +
149711 +/**************************************************************************//**
149712 + @Description A structure for FM counters
149713 +*//***************************************************************************/
149714 +typedef struct ioc_fm_counters_params_t {
149715 + ioc_fm_counters cnt; /**< The requested counter */
149716 + uint32_t val; /**< The requested value to get/set from/into the counter */
149717 +} ioc_fm_counters_params_t;
149718 +
149719 +typedef union ioc_fm_api_version_t {
149720 + struct {
149721 + uint8_t major;
149722 + uint8_t minor;
149723 + uint8_t respin;
149724 + uint8_t reserved;
149725 + } version;
149726 + uint32_t ver;
149727 +} ioc_fm_api_version_t;
149728 +
149729 +#if (DPAA_VERSION >= 11)
149730 +/**************************************************************************//**
149731 + @Description A structure of information about each of the external
149732 + buffer pools used by a port or storage-profile.
149733 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
149734 +*//***************************************************************************/
149735 +typedef struct ioc_fm_ext_pool_params {
149736 + uint8_t id; /**< External buffer pool id */
149737 + uint16_t size; /**< External buffer pool buffer size */
149738 +} ioc_fm_ext_pool_params;
149739 +
149740 +/**************************************************************************//**
149741 + @Description A structure for informing the driver about the external
149742 + buffer pools allocated in the BM and used by a port or a
149743 + storage-profile.
149744 + (must be identical to t_FmExtPools defined in fm_ext.h)
149745 +*//***************************************************************************/
149746 +typedef struct ioc_fm_ext_pools {
149747 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
149748 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
149749 + /**< Parameters for each port */
149750 +} ioc_fm_ext_pools;
149751 +
149752 +typedef struct ioc_fm_vsp_params_t {
149753 + void *p_fm; /**< A handle to the FM object this VSP related to */
149754 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149755 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149756 + parameter associated with Rx / OP port */
149757 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149758 + struct {
149759 + ioc_fm_port_type port_type; /**< Port type */
149760 + uint8_t port_id; /**< Port Id - relative to type */
149761 + } port_params;
149762 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149763 + defined in relevant FM object */
149764 + void *id; /**< return value */
149765 +} ioc_fm_vsp_params_t;
149766 +#endif /* (DPAA_VERSION >= 11) */
149767 +
149768 +/**************************************************************************//**
149769 + @Description A structure for defining BM pool depletion criteria
149770 +*//***************************************************************************/
149771 +typedef struct ioc_fm_buf_pool_depletion_t {
149772 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149773 + a number of pools (all together!) are depleted */
149774 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149775 + pause frames transmission. */
149776 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149777 + /**< For each pool, TRUE if it should be considered for
149778 + depletion (Note - this pool must be used by this port!). */
149779 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149780 + a single-pool is depleted; */
149781 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149782 + /**< For each pool, TRUE if it should be considered for
149783 + depletion (Note - this pool must be used by this port!) */
149784 +#if (DPAA_VERSION >= 11)
149785 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149786 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149787 + which is transmitted */
149788 +#endif /* (DPAA_VERSION >= 11) */
149789 +} ioc_fm_buf_pool_depletion_t;
149790 +
149791 +#if (DPAA_VERSION >= 11)
149792 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149793 + void *p_fm_vsp;
149794 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149795 +} ioc_fm_buf_pool_depletion_params_t;
149796 +#endif /* (DPAA_VERSION >= 11) */
149797 +
149798 +typedef struct ioc_fm_buffer_prefix_content_t {
149799 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
149800 + of the external buffer; Note that the private-area will
149801 + start from the base of the buffer address. */
149802 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
149803 + User may use FM_PORT_GetBufferPrsResult() in order to
149804 + get the parser-result from a buffer. */
149805 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
149806 + User may use FM_PORT_GetBufferTimeStamp() in order to
149807 + get the parser-result from a buffer. */
149808 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
149809 + User may use FM_PORT_GetBufferHashResult() in order to
149810 + get the parser-result from a buffer. */
149811 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
149812 + AD, hash-result, key, etc. */
149813 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
149814 + other value for selecting a data alignment (must be a power of 2);
149815 + if write optimization is used, must be >= 16. */
149816 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
149817 + Note that this field impacts the size of the buffer-prefix
149818 + (i.e. it pushes the data offset);
149819 + This field is irrelevant if DPAA_VERSION==10 */
149820 +} ioc_fm_buffer_prefix_content_t;
149821 +
149822 +typedef struct ioc_fm_buffer_prefix_content_params_t {
149823 + void *p_fm_vsp;
149824 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
149825 +} ioc_fm_buffer_prefix_content_params_t;
149826 +
149827 +#if (DPAA_VERSION >= 11)
149828 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
149829 + void *p_fm_vsp;
149830 + bool no_sg;
149831 +} ioc_fm_vsp_config_no_sg_params_t;
149832 +
149833 +typedef struct ioc_fm_vsp_prs_result_params_t {
149834 + void *p_fm_vsp;
149835 + void *p_data;
149836 +} ioc_fm_vsp_prs_result_params_t;
149837 +#endif
149838 +
149839 +typedef struct fm_ctrl_mon_t {
149840 + uint8_t percent_cnt[2];
149841 +} fm_ctrl_mon_t;
149842 +
149843 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
149844 + uint8_t fm_ctrl_index;
149845 + fm_ctrl_mon_t *p_mon;
149846 +} ioc_fm_ctrl_mon_counters_params_t;
149847 +
149848 +/**************************************************************************//**
149849 + @Function FM_IOC_SET_PORTS_BANDWIDTH
149850 +
149851 + @Description Sets relative weights between ports when accessing common resources.
149852 +
149853 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
149854 + their sum must equal 100.
149855 +
149856 + @Return E_OK on success; Error code otherwise.
149857 +
149858 + @Cautions Allowed only following FM_Init().
149859 +*//***************************************************************************/
149860 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
149861 +
149862 +/**************************************************************************//**
149863 + @Function FM_IOC_GET_REVISION
149864 +
149865 + @Description Returns the FM revision
149866 +
149867 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
149868 +
149869 + @Return None.
149870 +
149871 + @Cautions Allowed only following FM_Init().
149872 +*//***************************************************************************/
149873 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
149874 +
149875 +/**************************************************************************//**
149876 + @Function FM_IOC_GET_COUNTER
149877 +
149878 + @Description Reads one of the FM counters.
149879 +
149880 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
149881 +
149882 + @Return Counter's current value.
149883 +
149884 + @Cautions Allowed only following FM_Init().
149885 + Note that it is user's responsibilty to call this routine only
149886 + for enabled counters, and there will be no indication if a
149887 + disabled counter is accessed.
149888 +*//***************************************************************************/
149889 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
149890 +
149891 +/**************************************************************************//**
149892 + @Function FM_IOC_SET_COUNTER
149893 +
149894 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
149895 +
149896 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
149897 +
149898 + @Return E_OK on success; Error code otherwise.
149899 +
149900 + @Cautions Allowed only following FM_Init().
149901 +*//***************************************************************************/
149902 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
149903 +
149904 +/**************************************************************************//**
149905 + @Function FM_IOC_FORCE_INTR
149906 +
149907 + @Description Causes an interrupt event on the requested source.
149908 +
149909 + @Param[in] ioc_fm_exceptions An exception to be forced.
149910 +
149911 + @Return E_OK on success; Error code if the exception is not enabled,
149912 + or is not able to create interrupt.
149913 +
149914 + @Cautions Allowed only following FM_Init().
149915 +*//***************************************************************************/
149916 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
149917 +
149918 +/**************************************************************************//**
149919 + @Function FM_IOC_GET_API_VERSION
149920 +
149921 + @Description Reads the FMD IOCTL API version.
149922 +
149923 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
149924 +
149925 + @Return Version's value.
149926 +*//***************************************************************************/
149927 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
149928 +
149929 +#if (DPAA_VERSION >= 11)
149930 +/**************************************************************************//**
149931 + @Function FM_VSP_Config
149932 +
149933 + @Description Creates descriptor for the FM VSP module.
149934 +
149935 + The routine returns a handle (descriptor) to the FM VSP object.
149936 + This descriptor must be passed as first parameter to all other
149937 + FM VSP function calls.
149938 +
149939 + No actual initialization or configuration of FM hardware is
149940 + done by this routine.
149941 +
149942 +@Param[in] p_FmVspParams Pointer to data structure of parameters
149943 +
149944 + @Retval Handle to FM VSP object, or NULL for Failure.
149945 +*//***************************************************************************/
149946 +#if defined(CONFIG_COMPAT)
149947 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
149948 +#endif
149949 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
149950 +
149951 +/**************************************************************************//**
149952 + @Function FM_VSP_Init
149953 +
149954 + @Description Initializes the FM VSP module
149955 +
149956 + @Param[in] h_FmVsp - FM VSP module descriptor
149957 +
149958 + @Return E_OK on success; Error code otherwise.
149959 +*//***************************************************************************/
149960 +#if defined(CONFIG_COMPAT)
149961 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
149962 +#endif
149963 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
149964 +
149965 +/**************************************************************************//**
149966 + @Function FM_VSP_Free
149967 +
149968 + @Description Frees all resources that were assigned to FM VSP module.
149969 +
149970 + Calling this routine invalidates the descriptor.
149971 +
149972 + @Param[in] h_FmVsp - FM VSP module descriptor
149973 +
149974 + @Return E_OK on success; Error code otherwise.
149975 +*//***************************************************************************/
149976 +#if defined(CONFIG_COMPAT)
149977 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
149978 +#endif
149979 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
149980 +
149981 +/**************************************************************************//**
149982 + @Function FM_VSP_ConfigPoolDepletion
149983 +
149984 + @Description Calling this routine enables pause frame generation depending on the
149985 + depletion status of BM pools. It also defines the conditions to activate
149986 + this functionality. By default, this functionality is disabled.
149987 +
149988 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
149989 +
149990 + @Return E_OK on success; Error code otherwise.
149991 +
149992 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149993 +*//***************************************************************************/
149994 +#if defined(CONFIG_COMPAT)
149995 +#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)
149996 +#endif
149997 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
149998 +
149999 +/**************************************************************************//**
150000 + @Function FM_VSP_ConfigBufferPrefixContent
150001 +
150002 + @Description Defines the structure, size and content of the application buffer.
150003 +
150004 + The prefix will
150005 + In VSPs defined for Tx ports, if 'passPrsResult', the application
150006 + should set a value to their offsets in the prefix of
150007 + the FM will save the first 'privDataSize', than,
150008 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
150009 + and timeStamp, and the packet itself (in this order), to the
150010 + application buffer, and to offset.
150011 +
150012 + Calling this routine changes the buffer margins definitions
150013 + in the internal driver data base from its default
150014 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
150015 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
150016 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
150017 +
150018 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
150019 +
150020 + @Return E_OK on success; Error code otherwise.
150021 +
150022 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
150023 +*//***************************************************************************/
150024 +#if defined(CONFIG_COMPAT)
150025 +#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)
150026 +#endif
150027 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
150028 +
150029 +/**************************************************************************//**
150030 + @Function FM_VSP_ConfigNoScatherGather
150031 +
150032 + @Description Calling this routine changes the possibility to receive S/G frame
150033 + in the internal driver data base
150034 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
150035 +
150036 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
150037 +
150038 + @Return E_OK on success; Error code otherwise.
150039 +
150040 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
150041 +*//***************************************************************************/
150042 +#if defined(CONFIG_COMPAT)
150043 +#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)
150044 +#endif
150045 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
150046 +
150047 +/**************************************************************************//**
150048 + @Function FM_VSP_GetBufferPrsResult
150049 +
150050 + @Description Returns the pointer to the parse result in the data buffer.
150051 + In Rx ports this is relevant after reception, if parse
150052 + result is configured to be part of the data passed to the
150053 + application. For non Rx ports it may be used to get the pointer
150054 + of the area in the buffer where parse result should be
150055 + initialized - if so configured.
150056 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
150057 + configuration.
150058 +
150059 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
150060 +
150061 + @Return Parse result pointer on success, NULL if parse result was not
150062 + configured for this port.
150063 +
150064 + @Cautions Allowed only following FM_VSP_Init().
150065 +*//***************************************************************************/
150066 +#if defined(CONFIG_COMPAT)
150067 +#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)
150068 +#endif
150069 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
150070 +#endif /* (DPAA_VERSION >= 11) */
150071 +
150072 +/**************************************************************************//**
150073 + @Function FM_CtrlMonStart
150074 +
150075 + @Description Start monitoring utilization of all available FM controllers.
150076 +
150077 + In order to obtain FM controllers utilization the following sequence
150078 + should be used:
150079 + -# FM_CtrlMonStart()
150080 + -# FM_CtrlMonStop()
150081 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150082 +
150083 + @Return E_OK on success; Error code otherwise.
150084 +
150085 + @Cautions Allowed only following FM_Init().
150086 +*//***************************************************************************/
150087 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
150088 +
150089 +
150090 +/**************************************************************************//**
150091 + @Function FM_CtrlMonStop
150092 +
150093 + @Description Stop monitoring utilization of all available FM controllers.
150094 +
150095 + In order to obtain FM controllers utilization the following sequence
150096 + should be used:
150097 + -# FM_CtrlMonStart()
150098 + -# FM_CtrlMonStop()
150099 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150100 +
150101 + @Return E_OK on success; Error code otherwise.
150102 +
150103 + @Cautions Allowed only following FM_Init().
150104 +*//***************************************************************************/
150105 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
150106 +
150107 +/**************************************************************************//**
150108 + @Function FM_CtrlMonGetCounters
150109 +
150110 + @Description Obtain FM controller utilization parameters.
150111 +
150112 + In order to obtain FM controllers utilization the following sequence
150113 + should be used:
150114 + -# FM_CtrlMonStart()
150115 + -# FM_CtrlMonStop()
150116 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150117 +
150118 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
150119 +
150120 + @Return E_OK on success; Error code otherwise.
150121 +
150122 + @Cautions Allowed only following FM_Init().
150123 +*//***************************************************************************/
150124 +#if defined(CONFIG_COMPAT)
150125 +#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)
150126 +#endif
150127 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
150128 +
150129 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
150130 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
150131 +/** @} */ /* end of lnx_ioctl_FM_grp */
150132 +
150133 +#define FMD_API_VERSION_MAJOR 21
150134 +#define FMD_API_VERSION_MINOR 1
150135 +#define FMD_API_VERSION_RESPIN 0
150136 +
150137 +#endif /* __FM_IOCTLS_H */
150138 diff --git a/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
150139 new file mode 100644
150140 index 00000000..d13e878d
150141 --- /dev/null
150142 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
150143 @@ -0,0 +1,3084 @@
150144 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
150145 + * All rights reserved.
150146 + *
150147 + * Redistribution and use in source and binary forms, with or without
150148 + * modification, are permitted provided that the following conditions are met:
150149 + * * Redistributions of source code must retain the above copyright
150150 + * notice, this list of conditions and the following disclaimer.
150151 + * * Redistributions in binary form must reproduce the above copyright
150152 + * notice, this list of conditions and the following disclaimer in the
150153 + * documentation and/or other materials provided with the distribution.
150154 + * * Neither the name of Freescale Semiconductor nor the
150155 + * names of its contributors may be used to endorse or promote products
150156 + * derived from this software without specific prior written permission.
150157 + *
150158 + *
150159 + * ALTERNATIVELY, this software may be distributed under the terms of the
150160 + * GNU General Public License ("GPL") as published by the Free Software
150161 + * Foundation, either version 2 of that License or (at your option) any
150162 + * later version.
150163 + *
150164 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
150165 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
150166 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
150167 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
150168 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
150169 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
150170 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
150171 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
150172 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
150173 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
150174 + */
150175 +
150176 +
150177 +/******************************************************************************
150178 + @File fm_pcd_ioctls.h
150179 +
150180 + @Description FM PCD ...
150181 +*//***************************************************************************/
150182 +#ifndef __FM_PCD_IOCTLS_H
150183 +#define __FM_PCD_IOCTLS_H
150184 +
150185 +#include "net_ioctls.h"
150186 +#include "fm_ioctls.h"
150187 +
150188 +
150189 +/**************************************************************************//**
150190 +
150191 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
150192 +
150193 + @Description Frame Manager Linux ioctls definitions and enums
150194 +
150195 + @{
150196 +*//***************************************************************************/
150197 +
150198 +/**************************************************************************//**
150199 + @Group lnx_ioctl_FM_PCD_grp FM PCD
150200 +
150201 + @Description Frame Manager PCD API functions, definitions and enums
150202 +
150203 + The FM PCD module is responsible for the initialization of all
150204 + global classifying FM modules. This includes the parser general and
150205 + common registers, the key generator global and common registers,
150206 + and the policer global and common registers.
150207 + In addition, the FM PCD SW module will initialize all required
150208 + key generator schemes, coarse classification flows, and policer
150209 + profiles. When an FM module is configured to work with one of these
150210 + entities, it will register to it using the FM PORT API. The PCD
150211 + module will manage the PCD resources - i.e. resource management of
150212 + KeyGen schemes, etc.
150213 +
150214 + @{
150215 +*//***************************************************************************/
150216 +
150217 +/**************************************************************************//**
150218 + @Collection General PCD defines
150219 +*//***************************************************************************/
150220 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
150221 +
150222 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
150223 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
150224 + /**< Number of distinction units is limited by
150225 + register size (32 bits) minus reserved bits
150226 + for private headers. */
150227 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
150228 + in a distinction unit */
150229 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
150230 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
150231 + For HW implementation reasons, in most
150232 + cases less than this will be allowed; The
150233 + driver will return an initialization error
150234 + if resource is unavailable. */
150235 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
150236 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
150237 +
150238 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
150239 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
150240 +
150241 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
150242 + insert manipulation */
150243 +
150244 +#if DPAA_VERSION >= 11
150245 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
150246 +#endif /* DPAA_VERSION >= 11 */
150247 +/* @} */
150248 +
150249 +#ifdef FM_CAPWAP_SUPPORT
150250 +#error "FM_CAPWAP_SUPPORT not implemented!"
150251 +#endif
150252 +
150253 +
150254 +/**************************************************************************//**
150255 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
150256 +
150257 + @Description Frame Manager PCD Initialization Unit API
150258 +
150259 + @{
150260 +*//***************************************************************************/
150261 +
150262 +/**************************************************************************//**
150263 + @Description PCD counters
150264 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
150265 +*//***************************************************************************/
150266 +typedef enum ioc_fm_pcd_counters {
150267 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
150268 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
150269 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
150270 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
150271 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
150272 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
150273 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
150274 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
150275 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
150276 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
150277 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
150278 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
150279 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
150280 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
150281 + 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. */
150282 + 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. */
150283 + 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. */
150284 + 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. */
150285 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
150286 + 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. */
150287 + 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). */
150288 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
150289 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
150290 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
150291 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
150292 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
150293 +} ioc_fm_pcd_counters;
150294 +
150295 +/**************************************************************************//**
150296 + @Description PCD interrupts
150297 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
150298 +*//***************************************************************************/
150299 +typedef enum ioc_fm_pcd_exceptions {
150300 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
150301 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
150302 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
150303 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
150304 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
150305 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
150306 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
150307 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
150308 +} ioc_fm_pcd_exceptions;
150309 +
150310 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
150311 +
150312 +
150313 +/**************************************************************************//**
150314 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
150315 +
150316 + @Description Frame Manager PCD Runtime Unit
150317 +
150318 + The runtime control allows creation of PCD infrastructure modules
150319 + such as Network Environment Characteristics, Classification Plan
150320 + Groups and Coarse Classification Trees.
150321 + It also allows on-the-fly initialization, modification and removal
150322 + of PCD modules such as KeyGen schemes, coarse classification nodes
150323 + and Policer profiles.
150324 +
150325 + In order to explain the programming model of the PCD driver interface
150326 + a few terms should be explained, and will be used below.
150327 + - Distinction Header - One of the 16 protocols supported by the FM parser,
150328 + or one of the SHIM headers (1 or 2). May be a header with a special
150329 + option (see below).
150330 + - Interchangeable Headers Group - This is a group of Headers recognized
150331 + by either one of them. For example, if in a specific context the user
150332 + chooses to treat IPv4 and IPV6 in the same way, they may create an
150333 + interchangeable Headers Unit consisting of these 2 headers.
150334 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
150335 + Group.
150336 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
150337 + IPv6, includes multicast, broadcast and other protocol specific options.
150338 + In terms of hardware it relates to the options available in the classification
150339 + plan.
150340 + - Network Environment Characteristics - a set of Distinction Units that define
150341 + the total recognizable header selection for a certain environment. This is
150342 + NOT the list of all headers that will ever appear in a flow, but rather
150343 + everything that needs distinction in a flow, where distinction is made by KeyGen
150344 + schemes and coarse classification action descriptors.
150345 +
150346 + The PCD runtime modules initialization is done in stages. The first stage after
150347 + initializing the PCD module itself is to establish a Network Flows Environment
150348 + Definition. The application may choose to establish one or more such environments.
150349 + Later, when needed, the application will have to state, for some of its modules,
150350 + to which single environment it belongs.
150351 +
150352 + @{
150353 +*//***************************************************************************/
150354 +
150355 +
150356 +/**************************************************************************//**
150357 + @Description structure for FM counters
150358 +*//***************************************************************************/
150359 +typedef struct ioc_fm_pcd_counters_params_t {
150360 + ioc_fm_pcd_counters cnt; /**< The requested counter */
150361 + uint32_t val; /**< The requested value to get/set from/into the counter */
150362 +} ioc_fm_pcd_counters_params_t;
150363 +
150364 +/**************************************************************************//**
150365 + @Description structure for FM exception definitios
150366 +*//***************************************************************************/
150367 +typedef struct ioc_fm_pcd_exception_params_t {
150368 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
150369 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
150370 +} ioc_fm_pcd_exception_params_t;
150371 +
150372 +/**************************************************************************//**
150373 + @Description A structure for SW parser labels
150374 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
150375 + *//***************************************************************************/
150376 +typedef struct ioc_fm_pcd_prs_label_params_t {
150377 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
150378 + resolution), relative to Parser RAM. */
150379 + ioc_net_header_type hdr; /**< The existence of this header will invoke
150380 + the SW parser code. */
150381 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
150382 + attachments for the same header, use this
150383 + index to distinguish between them. */
150384 +} ioc_fm_pcd_prs_label_params_t;
150385 +
150386 +/**************************************************************************//**
150387 + @Description A structure for SW parser
150388 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
150389 + *//***************************************************************************/
150390 +typedef struct ioc_fm_pcd_prs_sw_params_t {
150391 + bool override; /**< FALSE to invoke a check that nothing else
150392 + was loaded to this address, including
150393 + internal patches.
150394 + TRUE to override any existing code.*/
150395 + uint32_t size; /**< SW parser code size */
150396 + uint16_t base; /**< SW parser base (in instruction counts!
150397 + must be larger than 0x20)*/
150398 + uint8_t *p_code; /**< SW parser code */
150399 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
150400 + /**< SW parser data (parameters) */
150401 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
150402 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
150403 + /**< SW parser labels table,
150404 + containing num_of_labels entries */
150405 +} ioc_fm_pcd_prs_sw_params_t;
150406 +
150407 +/**************************************************************************//**
150408 + @Description A structure to set the a KeyGen default value
150409 + *//***************************************************************************/
150410 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
150411 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
150412 + uint32_t value; /**< The requested default value */
150413 +} ioc_fm_pcd_kg_dflt_value_params_t;
150414 +
150415 +
150416 +/**************************************************************************//**
150417 + @Function FM_PCD_Enable
150418 +
150419 + @Description This routine should be called after PCD is initialized for enabling all
150420 + PCD engines according to their existing configuration.
150421 +
150422 + @Return 0 on success; Error code otherwise.
150423 +
150424 + @Cautions Allowed only when PCD is disabled.
150425 +*//***************************************************************************/
150426 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
150427 +
150428 +/**************************************************************************//**
150429 + @Function FM_PCD_Disable
150430 +
150431 + @Description This routine may be called when PCD is enabled in order to
150432 + disable all PCD engines. It may be called
150433 + only when none of the ports in the system are using the PCD.
150434 +
150435 + @Return 0 on success; Error code otherwise.
150436 +
150437 + @Cautions Allowed only when PCD is enabled.
150438 +*//***************************************************************************/
150439 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
150440 +
150441 + /**************************************************************************//**
150442 + @Function FM_PCD_PrsLoadSw
150443 +
150444 + @Description This routine may be called only when all ports in the
150445 + system are actively using the classification plan scheme.
150446 + In such cases it is recommended in order to save resources.
150447 + The driver automatically saves 8 classification plans for
150448 + ports that do NOT use the classification plan mechanism, to
150449 + avoid this (in order to save those entries) this routine may
150450 + be called.
150451 +
150452 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
150453 +
150454 + @Return 0 on success; Error code otherwise.
150455 +
150456 + @Cautions Allowed only when PCD is disabled.
150457 +*//***************************************************************************/
150458 +#if defined(CONFIG_COMPAT)
150459 +#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)
150460 +#endif
150461 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
150462 +
150463 +/**************************************************************************//**
150464 + @Function FM_PCD_KgSetDfltValue
150465 +
150466 + @Description Calling this routine sets a global default value to be used
150467 + by the KeyGen when parser does not recognize a required
150468 + field/header.
150469 + By default default values are 0.
150470 +
150471 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
150472 +
150473 + @Return 0 on success; Error code otherwise.
150474 +
150475 + @Cautions Allowed only when PCD is disabled.
150476 +*//***************************************************************************/
150477 +#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)
150478 +
150479 +/**************************************************************************//**
150480 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
150481 +
150482 + @Description Calling this routine allows the keygen to access data past
150483 + the parser finishing point.
150484 +
150485 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
150486 +
150487 + @Return 0 on success; Error code otherwise.
150488 +
150489 + @Cautions Allowed only when PCD is disabled.
150490 +*//***************************************************************************/
150491 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
150492 +
150493 +/**************************************************************************//**
150494 + @Function FM_PCD_SetException
150495 +
150496 + @Description Calling this routine enables/disables PCD interrupts.
150497 +
150498 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
150499 +
150500 + @Return 0 on success; Error code otherwise.
150501 +*//***************************************************************************/
150502 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
150503 +
150504 +/**************************************************************************//**
150505 + @Function FM_PCD_GetCounter
150506 +
150507 + @Description Reads one of the FM PCD counters.
150508 +
150509 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
150510 +
150511 + @Return 0 on success; Error code otherwise.
150512 +
150513 + @Cautions Note that it is user's responsibilty to call this routine only
150514 + for enabled counters, and there will be no indication if a
150515 + disabled counter is accessed.
150516 +*//***************************************************************************/
150517 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
150518 +
150519 +/**************************************************************************//**
150520 +
150521 + @Function FM_PCD_KgSchemeGetCounter
150522 +
150523 + @Description Reads scheme packet counter.
150524 +
150525 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
150526 +
150527 + @Return Counter's current value.
150528 +
150529 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
150530 +*//***************************************************************************/
150531 +#if defined(CONFIG_COMPAT)
150532 +#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)
150533 +#endif
150534 +#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)
150535 +
150536 +#if 0
150537 +TODO: unused IOCTL
150538 +/**************************************************************************//**
150539 + @Function FM_PCD_ModifyCounter
150540 +
150541 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
150542 +
150543 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
150544 +
150545 + @Return 0 on success; Error code otherwise.
150546 +*//***************************************************************************/
150547 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
150548 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
150549 +#endif
150550 +
150551 +/**************************************************************************//**
150552 + @Function FM_PCD_ForceIntr
150553 +
150554 + @Description Causes an interrupt event on the requested source.
150555 +
150556 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
150557 +
150558 + @Return 0 on success; error code if the exception is not enabled,
150559 + or is not able to create interrupt.
150560 +*//***************************************************************************/
150561 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
150562 +
150563 +/**************************************************************************//**
150564 + @Collection Definitions of coarse classification parameters as required by KeyGen
150565 + (when coarse classification is the next engine after this scheme).
150566 +*//***************************************************************************/
150567 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
150568 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
150569 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
150570 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
150571 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
150572 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
150573 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
150574 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
150575 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
150576 +/* @} */
150577 +
150578 +/**************************************************************************//**
150579 + @Collection A set of definitions to allow protocol
150580 + special option description.
150581 +*//***************************************************************************/
150582 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
150583 +
150584 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
150585 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
150586 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
150587 +
150588 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
150589 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
150590 +
150591 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
150592 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
150593 +
150594 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
150595 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
150596 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
150597 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
150598 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
150599 +
150600 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
150601 + IPV4 Reassembly manipulation requires network
150602 + environment with IPV4 header and IPV4_FRAG_1 option */
150603 +
150604 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
150605 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
150606 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
150607 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
150608 +
150609 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
150610 + IPV6 Reassembly manipulation requires network
150611 + environment with IPV6 header and IPV6_FRAG_1 option */
150612 +#if (DPAA_VERSION >= 11)
150613 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
150614 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
150615 + CAPWAP Reassembly manipulation requires network
150616 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
150617 + in case where fragment found, the fragment-extension offset
150618 + may be found at 'shim2' (in parser-result). */
150619 +#endif /* (DPAA_VERSION >= 11) */
150620 +
150621 +/* @} */
150622 +
150623 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
150624 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
150625 +/**************************************************************************//**
150626 + @Collection A set of definitions to support Header Manipulation selection.
150627 +*//***************************************************************************/
150628 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
150629 +
150630 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
150631 +
150632 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
150633 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150634 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
150635 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150636 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
150637 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
150638 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150639 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
150640 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150641 +
150642 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
150643 +
150644 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
150645 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150646 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
150647 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
150648 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150649 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
150650 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150651 +
150652 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
150653 +
150654 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
150655 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150656 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
150657 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150658 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
150659 +
150660 +/* @} */
150661 +
150662 +/**************************************************************************//**
150663 + @Description A type used for returning the order of the key extraction.
150664 + each value in this array represents the index of the extraction
150665 + command as defined by the user in the initialization extraction array.
150666 + The valid size of this array is the user define number of extractions
150667 + required (also marked by the second '0' in this array).
150668 +*//***************************************************************************/
150669 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150670 +
150671 +/**************************************************************************//**
150672 + @Description All PCD engines
150673 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
150674 +*//***************************************************************************/
150675 +typedef enum ioc_fm_pcd_engine {
150676 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
150677 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
150678 + e_IOC_FM_PCD_KG, /**< KeyGen */
150679 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
150680 + e_IOC_FM_PCD_PLCR, /**< Policer */
150681 + e_IOC_FM_PCD_PRS, /**< Parser */
150682 +#if DPAA_VERSION >= 11
150683 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
150684 +#endif /* DPAA_VERSION >= 11 */
150685 + e_IOC_FM_PCD_HASH /**< Hash Table */
150686 +} ioc_fm_pcd_engine;
150687 +
150688 +/**************************************************************************//**
150689 + @Description An enum for selecting extraction by header types
150690 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
150691 +*//***************************************************************************/
150692 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
150693 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
150694 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
150695 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
150696 +} ioc_fm_pcd_extract_by_hdr_type;
150697 +
150698 +/**************************************************************************//**
150699 + @Description An enum for selecting extraction source (when it is not the header)
150700 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
150701 +*//***************************************************************************/
150702 +typedef enum ioc_fm_pcd_extract_from {
150703 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
150704 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
150705 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
150706 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
150707 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
150708 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
150709 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
150710 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
150711 +} ioc_fm_pcd_extract_from;
150712 +
150713 +/**************************************************************************//**
150714 + @Description An enum for selecting extraction type
150715 +*//***************************************************************************/
150716 +typedef enum ioc_fm_pcd_extract_type {
150717 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
150718 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
150719 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
150720 +} ioc_fm_pcd_extract_type;
150721 +
150722 +/**************************************************************************//**
150723 + @Description An enum for selecting a default
150724 +*//***************************************************************************/
150725 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
150726 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
150727 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
150728 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
150729 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
150730 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
150731 +} ioc_fm_pcd_kg_extract_dflt_select;
150732 +
150733 +/**************************************************************************//**
150734 + @Description Enumeration type defining all default groups - each group shares
150735 + a default value, one of four user-initialized values.
150736 +*//***************************************************************************/
150737 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
150738 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
150739 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
150740 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
150741 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
150742 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
150743 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
150744 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
150745 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
150746 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
150747 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
150748 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
150749 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
150750 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
150751 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
150752 + any data extraction that is not the full
150753 + field described above */
150754 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150755 + any data extraction without validation */
150756 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150757 + extraction from parser result or
150758 + direct use of default value */
150759 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150760 +
150761 +/**************************************************************************//**
150762 + @Description Enumeration type for defining header index for scenarios with
150763 + multiple (tunneled) headers
150764 +*//***************************************************************************/
150765 +typedef enum ioc_fm_pcd_hdr_index {
150766 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150767 + to specify regular IP (not tunneled). */
150768 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150769 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150770 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150771 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150772 +} ioc_fm_pcd_hdr_index;
150773 +
150774 +/**************************************************************************//**
150775 + @Description Enumeration type for selecting the policer profile functional type
150776 +*//***************************************************************************/
150777 +typedef enum ioc_fm_pcd_profile_type_selection {
150778 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150779 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150780 +} ioc_fm_pcd_profile_type_selection;
150781 +
150782 +/**************************************************************************//**
150783 + @Description Enumeration type for selecting the policer profile algorithm
150784 +*//***************************************************************************/
150785 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150786 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150787 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150788 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150789 +} ioc_fm_pcd_plcr_algorithm_selection;
150790 +
150791 +/**************************************************************************//**
150792 + @Description Enumeration type for selecting a policer profile color mode
150793 +*//***************************************************************************/
150794 +typedef enum ioc_fm_pcd_plcr_color_mode {
150795 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150796 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
150797 +} ioc_fm_pcd_plcr_color_mode;
150798 +
150799 +/**************************************************************************//**
150800 + @Description Enumeration type for selecting a policer profile color
150801 +*//***************************************************************************/
150802 +typedef enum ioc_fm_pcd_plcr_color {
150803 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
150804 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
150805 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
150806 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
150807 +} ioc_fm_pcd_plcr_color;
150808 +
150809 +/**************************************************************************//**
150810 + @Description Enumeration type for selecting the policer profile packet frame length selector
150811 +*//***************************************************************************/
150812 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
150813 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
150814 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
150815 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
150816 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
150817 +} ioc_fm_pcd_plcr_frame_length_select;
150818 +
150819 +/**************************************************************************//**
150820 + @Description Enumeration type for selecting roll-back frame
150821 +*//***************************************************************************/
150822 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
150823 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
150824 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
150825 +} ioc_fm_pcd_plcr_roll_back_frame_select;
150826 +
150827 +/**************************************************************************//**
150828 + @Description Enumeration type for selecting the policer profile packet or byte mode
150829 +*//***************************************************************************/
150830 +typedef enum ioc_fm_pcd_plcr_rate_mode {
150831 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
150832 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
150833 +} ioc_fm_pcd_plcr_rate_mode;
150834 +
150835 +/**************************************************************************//**
150836 + @Description Enumeration type for defining action of frame
150837 +*//***************************************************************************/
150838 +typedef enum ioc_fm_pcd_done_action {
150839 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
150840 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
150841 +} ioc_fm_pcd_done_action;
150842 +
150843 +/**************************************************************************//**
150844 + @Description Enumeration type for selecting the policer counter
150845 +*//***************************************************************************/
150846 +typedef enum ioc_fm_pcd_plcr_profile_counters {
150847 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
150848 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
150849 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
150850 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
150851 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
150852 +} ioc_fm_pcd_plcr_profile_counters;
150853 +
150854 +/**************************************************************************//**
150855 + @Description Enumeration type for selecting the PCD action after extraction
150856 +*//***************************************************************************/
150857 +typedef enum ioc_fm_pcd_action {
150858 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
150859 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
150860 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
150861 +} ioc_fm_pcd_action;
150862 +
150863 +/**************************************************************************//**
150864 + @Description Enumeration type for selecting type of insert manipulation
150865 +*//***************************************************************************/
150866 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
150867 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
150868 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
150869 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150870 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
150871 +#endif /* FM_CAPWAP_SUPPORT */
150872 +} ioc_fm_pcd_manip_hdr_insrt_type;
150873 +
150874 +/**************************************************************************//**
150875 + @Description Enumeration type for selecting type of remove manipulation
150876 +*//***************************************************************************/
150877 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
150878 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
150879 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
150880 +} ioc_fm_pcd_manip_hdr_rmv_type;
150881 +
150882 +/**************************************************************************//**
150883 + @Description An enum for selecting specific L2 fields removal
150884 +*//***************************************************************************/
150885 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
150886 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
150887 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
150888 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
150889 + the header which follows the MPLS header */
150890 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
150891 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
150892 +
150893 +/**************************************************************************//**
150894 + @Description Enumeration type for selecting specific fields updates
150895 +*//***************************************************************************/
150896 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
150897 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
150898 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
150899 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
150900 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
150901 +} ioc_fm_pcd_manip_hdr_field_update_type;
150902 +
150903 +/**************************************************************************//**
150904 + @Description Enumeration type for selecting VLAN updates
150905 +*//***************************************************************************/
150906 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
150907 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
150908 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
150909 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
150910 +
150911 +/**************************************************************************//**
150912 + @Description Enumeration type for selecting specific L2 fields removal
150913 +*//***************************************************************************/
150914 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
150915 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
150916 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
150917 +
150918 +#if (DPAA_VERSION >= 11)
150919 +/**************************************************************************//**
150920 + @Description Enumeration type for selecting QoS mapping mode
150921 +
150922 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
150923 + User should instruct the port to read the parser-result
150924 +*//***************************************************************************/
150925 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
150926 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
150927 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
150928 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
150929 +
150930 +/**************************************************************************//**
150931 + @Description Enumeration type for selecting QoS source
150932 +
150933 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
150934 + User should left room for the parser-result on input/output buffer
150935 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
150936 +*//***************************************************************************/
150937 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
150938 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
150939 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
150940 +} ioc_fm_pcd_manip_hdr_qos_src;
150941 +#endif /* (DPAA_VERSION >= 11) */
150942 +
150943 +/**************************************************************************//**
150944 + @Description Enumeration type for selecting type of header insertion
150945 +*//***************************************************************************/
150946 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
150947 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
150948 +#if (DPAA_VERSION >= 11)
150949 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
150950 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
150951 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
150952 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
150953 +#endif /* (DPAA_VERSION >= 11) */
150954 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
150955 +
150956 +/**************************************************************************//**
150957 + @Description Enumeration type for selecting specific custom command
150958 +*//***************************************************************************/
150959 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
150960 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
150961 +} ioc_fm_pcd_manip_hdr_custom_type;
150962 +
150963 +/**************************************************************************//**
150964 + @Description Enumeration type for selecting specific custom command
150965 +*//***************************************************************************/
150966 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
150967 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
150968 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
150969 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
150970 +
150971 +/**************************************************************************//**
150972 + @Description Enumeration type for selecting type of header removal
150973 +*//***************************************************************************/
150974 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
150975 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
150976 +#if (DPAA_VERSION >= 11)
150977 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
150978 +#endif /* (DPAA_VERSION >= 11) */
150979 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
150980 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
150981 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
150982 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
150983 +
150984 +/**************************************************************************//**
150985 + @Description Enumeration type for selecting type of timeout mode
150986 +*//***************************************************************************/
150987 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
150988 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
150989 + from the first fragment to the last */
150990 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
150991 +} ioc_fm_pcd_manip_reassem_time_out_mode;
150992 +
150993 +/**************************************************************************//**
150994 + @Description Enumeration type for selecting type of WaysNumber mode
150995 +*//***************************************************************************/
150996 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
150997 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
150998 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
150999 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
151000 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
151001 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
151002 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
151003 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
151004 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
151005 +} ioc_fm_pcd_manip_reassem_ways_number;
151006 +
151007 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151008 +/**************************************************************************//**
151009 + @Description Enumeration type for selecting type of statistics mode
151010 +*//***************************************************************************/
151011 +typedef enum ioc_fm_pcd_stats {
151012 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
151013 +} ioc_fm_pcd_stats;
151014 +#endif
151015 +
151016 +/**************************************************************************//**
151017 + @Description Enumeration type for selecting manipulation type
151018 +*//***************************************************************************/
151019 +typedef enum ioc_fm_pcd_manip_type {
151020 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
151021 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
151022 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
151023 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
151024 +} ioc_fm_pcd_manip_type;
151025 +
151026 +/**************************************************************************//**
151027 + @Description Enumeration type for selecting type of statistics mode
151028 +*//***************************************************************************/
151029 +typedef enum ioc_fm_pcd_cc_stats_mode {
151030 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
151031 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
151032 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
151033 +#if (DPAA_VERSION >= 11)
151034 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
151035 +#endif /* (DPAA_VERSION >= 11) */
151036 +} ioc_fm_pcd_cc_stats_mode;
151037 +
151038 +/**************************************************************************//**
151039 + @Description Enumeration type for determining the action in case an IP packet
151040 + is larger than MTU but its DF (Don't Fragment) bit is set.
151041 +*//***************************************************************************/
151042 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
151043 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
151044 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
151045 + /**< Obsolete, cannot enqueue to error queue;
151046 + In practice, selects to discard packets;
151047 + Will be removed in the future */
151048 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
151049 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
151050 +} ioc_fm_pcd_manip_dont_frag_action;
151051 +
151052 +/**************************************************************************//**
151053 + @Description Enumeration type for selecting type of special offload manipulation
151054 +*//***************************************************************************/
151055 +typedef enum ioc_fm_pcd_manip_special_offload_type {
151056 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
151057 +#if (DPAA_VERSION >= 11)
151058 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
151059 +#endif /* (DPAA_VERSION >= 11) */
151060 +} ioc_fm_pcd_manip_special_offload_type;
151061 +
151062 +/**************************************************************************//**
151063 + @Description A union of protocol dependent special options
151064 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
151065 +*//***************************************************************************/
151066 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
151067 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
151068 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
151069 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
151070 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
151071 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
151072 +#if (DPAA_VERSION >= 11)
151073 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
151074 +#endif /* (DPAA_VERSION >= 11) */
151075 +} ioc_fm_pcd_hdr_protocol_opt_u;
151076 +
151077 +/**************************************************************************//**
151078 + @Description A union holding all known protocol fields
151079 +*//***************************************************************************/
151080 +typedef union ioc_fm_pcd_fields_u {
151081 + ioc_header_field_eth_t eth; /**< Ethernet */
151082 + ioc_header_field_vlan_t vlan; /**< VLAN */
151083 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
151084 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
151085 + ioc_header_field_mpls_t mpls; /**< MPLS */
151086 + ioc_header_field_ip_t ip; /**< IP */
151087 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
151088 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
151089 + ioc_header_field_udp_t udp; /**< UDP */
151090 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
151091 + ioc_header_field_tcp_t tcp; /**< TCP */
151092 + ioc_header_field_sctp_t sctp; /**< SCTP */
151093 + ioc_header_field_dccp_t dccp; /**< DCCP */
151094 + ioc_header_field_gre_t gre; /**< GRE */
151095 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
151096 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
151097 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
151098 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
151099 +} ioc_fm_pcd_fields_u;
151100 +
151101 +/**************************************************************************//**
151102 + @Description Parameters for defining header extraction for key generation
151103 +*//***************************************************************************/
151104 +typedef struct ioc_fm_pcd_from_hdr_t {
151105 + uint8_t size; /**< Size in byte */
151106 + uint8_t offset; /**< Byte offset */
151107 +} ioc_fm_pcd_from_hdr_t;
151108 +
151109 +/**************************************************************************//**
151110 + @Description Parameters for defining field extraction for key generation
151111 +*//***************************************************************************/
151112 +typedef struct ioc_fm_pcd_from_field_t {
151113 + ioc_fm_pcd_fields_u field; /**< Field selection */
151114 + uint8_t size; /**< Size in byte */
151115 + uint8_t offset; /**< Byte offset */
151116 +} ioc_fm_pcd_from_field_t;
151117 +
151118 +/**************************************************************************//**
151119 + @Description Parameters for defining a single network environment unit
151120 + A distinction unit should be defined if it will later be used
151121 + by one or more PCD engines to distinguish between flows.
151122 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
151123 +*//***************************************************************************/
151124 +typedef struct ioc_fm_pcd_distinction_unit_t {
151125 + struct {
151126 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
151127 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
151128 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
151129 +} ioc_fm_pcd_distinction_unit_t;
151130 +
151131 +/**************************************************************************//**
151132 + @Description Parameters for defining all different distinction units supported
151133 + by a specific PCD Network Environment Characteristics module.
151134 +
151135 + Each unit represent a protocol or a group of protocols that may
151136 + be used later by the different PCD engines to distinguish between flows.
151137 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
151138 +*//***************************************************************************/
151139 +typedef struct ioc_fm_pcd_net_env_params_t {
151140 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
151141 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
151142 + /**< An array of num_of_distinction_units of the
151143 + different units to be identified */
151144 + void *id; /**< Output parameter; Returns the net-env Id to be used */
151145 +} ioc_fm_pcd_net_env_params_t;
151146 +
151147 +/**************************************************************************//**
151148 + @Description Parameters for defining a single extraction action when
151149 + creating a key
151150 +*//***************************************************************************/
151151 +typedef struct ioc_fm_pcd_extract_entry_t {
151152 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
151153 + union {
151154 + struct {
151155 + ioc_net_header_type hdr; /**< Header selection */
151156 + bool ignore_protocol_validation;
151157 + /**< Ignore protocol validation */
151158 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
151159 + IP. Otherwise should be cleared.*/
151160 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
151161 + union {
151162 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
151163 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
151164 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
151165 + } extract_by_hdr_type;
151166 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
151167 + struct {
151168 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
151169 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
151170 + uint16_t ic_indx_mask; /**< Relevant only for CC when
151171 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
151172 + Note that the number of bits that are set within
151173 + this mask must be log2 of the CC-node 'num_of_keys'.
151174 + Note that the mask cannot be set on the lower bits. */
151175 + uint8_t offset; /**< Byte offset */
151176 + uint8_t size; /**< Size in bytes */
151177 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
151178 + } extract_params;
151179 +} ioc_fm_pcd_extract_entry_t;
151180 +
151181 +/**************************************************************************//**
151182 + @Description A structure for defining masks for each extracted
151183 + field in the key.
151184 +*//***************************************************************************/
151185 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
151186 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
151187 + uint8_t offset; /**< Byte offset */
151188 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
151189 +} ioc_fm_pcd_kg_extract_mask_t;
151190 +
151191 +/**************************************************************************//**
151192 + @Description A structure for defining default selection per groups
151193 + of fields
151194 +*//***************************************************************************/
151195 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
151196 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
151197 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
151198 +} ioc_fm_pcd_kg_extract_dflt_t;
151199 +
151200 +
151201 +/**************************************************************************//**
151202 + @Description A structure for defining all parameters needed for
151203 + generation a key and using a hash function
151204 +*//***************************************************************************/
151205 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
151206 + uint32_t private_dflt0; /**< Scheme default register 0 */
151207 + uint32_t private_dflt1; /**< Scheme default register 1 */
151208 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
151209 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
151210 + /**< An array of extraction definitions. */
151211 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
151212 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
151213 + /**< For each extraction used in this scheme, specify the required
151214 + default register to be used when header is not found.
151215 + types not specified in this array will get undefined value. */
151216 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
151217 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
151218 + uint8_t hash_shift; /**< Hash result right shift.
151219 + Selects the 24 bits out of the 64 hash result.
151220 + 0 means using the 24 LSB's, otherwise use the
151221 + 24 LSB's after shifting right.*/
151222 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
151223 + of queues for the key and hash functionality */
151224 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
151225 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
151226 + destination fields on all layers; If TRUE, driver will check that for
151227 + all layers, if SRC extraction is selected, DST extraction must also be
151228 + selected, and vice versa. */
151229 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
151230 +
151231 +/**************************************************************************//**
151232 + @Description A structure of parameters for defining a single
151233 + Qid mask (extracted OR).
151234 +*//***************************************************************************/
151235 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
151236 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
151237 + union {
151238 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
151239 + ioc_net_header_type hdr;
151240 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
151241 + IP. Otherwise should be cleared.*/
151242 + bool ignore_protocol_validation;
151243 +
151244 + } extract_by_hdr;
151245 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
151246 + } extract_params;
151247 + uint8_t extraction_offset; /**< Offset for extraction */
151248 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
151249 + field not found */
151250 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
151251 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
151252 + the extracted byte; Assume byte is placed as the 8 MSB's in
151253 + a 32 bit word where the lower bits
151254 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
151255 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
151256 + extracted byte will effect the 8 LSB's of the FQID,
151257 + if bitOffsetInFqid=31 than the byte's MSB will effect
151258 + the FQID's LSB; 0 means - no effect on FQID;
151259 + Note that one, and only one of
151260 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151261 + extracted byte must effect either FQID or Policer profile).*/
151262 + uint8_t bit_offset_in_plcr_profile;
151263 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
151264 + effect using the extracted byte; Assume byte is placed
151265 + as the 8 MSB's in a 16 bit word where the lower bits
151266 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
151267 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
151268 + than the extracted byte will effect the whole policer profile id,
151269 + if bitOffsetInFqid=15 than the byte's MSB will effect
151270 + the Policer Profile id's LSB;
151271 + 0 means - no effect on policer profile; Note that one, and only one of
151272 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151273 + extracted byte must effect either FQID or Policer profile).*/
151274 +} ioc_fm_pcd_kg_extracted_or_params_t;
151275 +
151276 +/**************************************************************************//**
151277 + @Description A structure for configuring scheme counter
151278 +*//***************************************************************************/
151279 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
151280 + bool update; /**< FALSE to keep the current counter state
151281 + and continue from that point, TRUE to update/reset
151282 + the counter when the scheme is written. */
151283 + uint32_t value; /**< If update=TRUE, this value will be written into the
151284 + counter; clear this field to reset the counter. */
151285 +} ioc_fm_pcd_kg_scheme_counter_t;
151286 +
151287 +
151288 +/**************************************************************************//**
151289 + @Description A structure for retrieving FMKG_SE_SPC
151290 +*//***************************************************************************/
151291 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
151292 + uint32_t val; /**< return value */
151293 + void *id; /**< scheme handle */
151294 +} ioc_fm_pcd_kg_scheme_spc_t;
151295 +
151296 +/**************************************************************************//**
151297 + @Description A structure for defining policer profile parameters as required by keygen
151298 + (when policer is the next engine after this scheme).
151299 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
151300 +*//***************************************************************************/
151301 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
151302 + bool shared_profile; /**< TRUE if this profile is shared between ports
151303 + (i.e. managed by master partition) May not be TRUE
151304 + if profile is after Coarse Classification*/
151305 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
151306 + id, if FALSE fqid_offset_relative_profile_id_base is used
151307 + together with fqid_offset_shift and num_of_profiles
151308 + parameters, to define a range of profiles from
151309 + which the KeyGen result will determine the
151310 + destination policer profile. */
151311 + union {
151312 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
151313 + This parameter should indicate the policer profile offset within the port's
151314 + policer profiles or SHARED window. */
151315 + struct {
151316 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
151317 + uint8_t fqid_offset_relative_profile_id_base;
151318 + /**< OR of KG results without the qid base
151319 + This parameter should indicate the policer profile
151320 + offset within the port's policer profiles window
151321 + or SHARED window depends on shared_profile */
151322 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
151323 + } indirect_profile; /**< Indirect profile parameters */
151324 + } profile_select; /**< Direct/indirect profile selection and parameters */
151325 +} ioc_fm_pcd_kg_plcr_profile_t;
151326 +
151327 +#if DPAA_VERSION >= 11
151328 +/**************************************************************************//**
151329 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
151330 +*//***************************************************************************/
151331 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
151332 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
151333 + profile id;
151334 + If FALSE, fqidOffsetRelativeProfileIdBase is used
151335 + together with fqidOffsetShift and numOfProfiles
151336 + parameters to define a range of profiles from which
151337 + the KeyGen result will determine the destination
151338 + storage profile. */
151339 + union {
151340 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
151341 + should indicate the storage profile offset within the
151342 + port's storage profiles window. */
151343 + struct {
151344 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
151345 + uint8_t fqid_offset_relative_profile_id_base;
151346 + /**< OR of KeyGen results without the FQID base;
151347 + should indicate the policer profile offset within the
151348 + port's storage profiles window. */
151349 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
151350 + } indirect_profile; /**< Indirect profile parameters. */
151351 + } profile_select; /**< Direct/indirect profile selection and parameters. */
151352 +} ioc_fm_pcd_kg_storage_profile_t;
151353 +#endif /* DPAA_VERSION >= 11 */
151354 +
151355 +/**************************************************************************//**
151356 + @Description Parameters for defining CC as the next engine after KeyGen
151357 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
151358 +*//***************************************************************************/
151359 +typedef struct ioc_fm_pcd_kg_cc_t {
151360 + void *tree_id; /**< CC Tree id */
151361 + uint8_t grp_id; /**< CC group id within the CC tree */
151362 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
151363 + policing is required. */
151364 + bool bypass_plcr_profile_generation;
151365 + /**< TRUE to bypass KeyGen policer profile generation;
151366 + selected profile is the one set at port initialization. */
151367 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
151368 + bypass_plcr_profile_generation = FALSE */
151369 +} ioc_fm_pcd_kg_cc_t;
151370 +
151371 +/**************************************************************************//**
151372 + @Description Parameters for defining initializing a KeyGen scheme
151373 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
151374 +*//***************************************************************************/
151375 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
151376 + bool modify; /**< TRUE to change an existing scheme */
151377 + union {
151378 + uint8_t relative_scheme_id;
151379 + /**< if modify=FALSE: partition-relative scheme id */
151380 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
151381 + } scm_id;
151382 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
151383 + for match vector; KeyGen will ignore it when matching */
151384 + struct { /**< HL relevant only if always_direct=FALSE */
151385 + void *net_env_id; /**< The id of the Network Environment as returned
151386 + by FM_PCD_NetEnvCharacteristicsSet() */
151387 + uint8_t num_of_distinction_units;
151388 + /**< Number of NetEnv units listed in unit_ids array */
151389 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
151390 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
151391 + } net_env_params;
151392 + bool use_hash; /**< use the KG Hash functionality */
151393 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
151394 + /**< used only if useHash = TRUE */
151395 + bool bypass_fqid_generation;
151396 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
151397 + In such a case FQID after KG will be the default FQID
151398 + defined for the relevant port, or the FQID defined by CC
151399 + in cases where CC was the previous engine. */
151400 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
151401 + If hash is used and an even distribution is expected
151402 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
151403 + hash_distribution_num_of_fqids. */
151404 + uint8_t num_of_used_extracted_ors;
151405 + /**< Number of FQID masks listed in extracted_ors array*/
151406 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
151407 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
151408 + registers are shared between qid_masks
151409 + functionality and some of the extraction
151410 + actions; Normally only some will be used
151411 + for qid_mask. Driver will return error if
151412 + resource is full at initialization time. */
151413 +#if DPAA_VERSION >= 11
151414 + bool override_storage_profile;
151415 + /**< TRUE if KeyGen override previously decided storage profile */
151416 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
151417 +#endif /* DPAA_VERSION >= 11 */
151418 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
151419 + union { /**< depends on nextEngine */
151420 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
151421 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
151422 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
151423 + } kg_next_engine_params;
151424 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
151425 + the scheme counter */
151426 + void *id; /**< Returns the scheme Id to be used */
151427 +} ioc_fm_pcd_kg_scheme_params_t;
151428 +
151429 +/**************************************************************************//**
151430 + @Collection
151431 +*//***************************************************************************/
151432 +#if DPAA_VERSION >= 11
151433 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
151434 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
151435 +#endif /* DPAA_VERSION >= 11 */
151436 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
151437 +/* @} */
151438 +
151439 +/**************************************************************************//**
151440 + @Description Parameters for defining CC as the next engine after a CC node.
151441 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
151442 +*//***************************************************************************/
151443 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
151444 + void *cc_node_id; /**< Id of the next CC node */
151445 +} ioc_fm_pcd_cc_next_cc_params_t;
151446 +
151447 +#if DPAA_VERSION >= 11
151448 +/**************************************************************************//**
151449 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
151450 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
151451 +*//***************************************************************************/
151452 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
151453 + void* frm_replic_id; /**< The id of the next frame replicator group */
151454 +} ioc_fm_pcd_cc_next_fr_params_t;
151455 +#endif /* DPAA_VERSION >= 11 */
151456 +
151457 +/**************************************************************************//**
151458 + @Description A structure for defining PLCR params when PLCR is the
151459 + next engine after a CC node
151460 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
151461 +*//***************************************************************************/
151462 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
151463 + bool override_params; /**< TRUE if CC override previously decided parameters*/
151464 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
151465 + TRUE if this profile is shared between ports */
151466 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
151467 + (otherwise profile id is taken from keygen);
151468 + This parameter should indicate the policer
151469 + profile offset within the port's
151470 + policer profiles or from SHARED window.*/
151471 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
151472 + FQID for enquing the frame;
151473 + In earlier chips if policer next engine is KEYGEN,
151474 + this parameter can be 0, because the KEYGEN always decides
151475 + the enqueue FQID.*/
151476 +#if DPAA_VERSION >= 11
151477 + uint8_t new_relative_storage_profile_id;
151478 + /**< Indicates the relative storage profile offset within
151479 + the port's storage profiles window;
151480 + Relevant only if the port was configured with VSP. */
151481 +#endif /* DPAA_VERSION >= 11 */
151482 +} ioc_fm_pcd_cc_next_plcr_params_t;
151483 +
151484 +/**************************************************************************//**
151485 + @Description A structure for defining enqueue params when BMI is the
151486 + next engine after a CC node
151487 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
151488 +*//***************************************************************************/
151489 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
151490 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151491 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151492 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
151493 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151494 + (otherwise FQID is taken from KeyGen),
151495 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
151496 +#if DPAA_VERSION >= 11
151497 + uint8_t new_relative_storage_profile_id;
151498 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151499 + storage profile offset within the port's storage profiles
151500 + window; Relevant only if the port was configured with VSP. */
151501 +#endif /* DPAA_VERSION >= 11 */
151502 +
151503 +} ioc_fm_pcd_cc_next_enqueue_params_t;
151504 +
151505 +/**************************************************************************//**
151506 + @Description A structure for defining KG params when KG is the next engine after a CC node
151507 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
151508 +*//***************************************************************************/
151509 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
151510 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151511 + Note - this parameters are irrelevant for earlier chips */
151512 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151513 + (otherwise FQID is taken from KeyGen),
151514 + Note - this parameters are irrelevant for earlier chips */
151515 +#if DPAA_VERSION >= 11
151516 + uint8_t new_relative_storage_profile_id;
151517 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151518 + storage profile offset within the port's storage profiles
151519 + window; Relevant only if the port was configured with VSP. */
151520 +#endif /* DPAA_VERSION >= 11 */
151521 + void *p_direct_scheme; /**< Direct scheme id to go to. */
151522 +} ioc_fm_pcd_cc_next_kg_params_t;
151523 +
151524 +/**************************************************************************//**
151525 + @Description Parameters for defining the next engine after a CC node.
151526 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
151527 +*//***************************************************************************/
151528 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
151529 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
151530 + according to nextEngine definition */
151531 + union {
151532 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
151533 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
151534 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
151535 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
151536 +#if DPAA_VERSION >= 11
151537 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
151538 +#endif /* DPAA_VERSION >= 11 */
151539 + } params; /**< Union used for all the next-engine parameters options */
151540 + void *manip_id; /**< Handle to Manipulation object.
151541 + Relevant if next engine is of type result
151542 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
151543 + bool statistics_en; /**< If TRUE, statistics counters are incremented
151544 + for each frame passing through this
151545 + Coarse Classification entry. */
151546 +} ioc_fm_pcd_cc_next_engine_params_t;
151547 +
151548 +/**************************************************************************//**
151549 + @Description Parameters for defining a single CC key
151550 +*//***************************************************************************/
151551 +typedef struct ioc_fm_pcd_cc_key_params_t {
151552 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
151553 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
151554 + in keySize. p_key and p_mask (if defined) has to be
151555 + of the same size defined in the key_size */
151556 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151557 + /**< parameters for the next for the defined Key in p_key */
151558 +
151559 +} ioc_fm_pcd_cc_key_params_t;
151560 +
151561 +/**************************************************************************//**
151562 + @Description Parameters for defining CC keys parameters
151563 + The driver supports two methods for CC node allocation: dynamic and static.
151564 + Static mode was created in order to prevent runtime alloc/free
151565 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
151566 + the driver automatically allocates the memory according to
151567 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
151568 + size that may be used for this CC-Node taking into consideration
151569 + 'mask_support' and 'statistics_mode' parameters.
151570 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
151571 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
151572 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
151573 + all required structures are allocated according to 'num_of_keys'
151574 + parameter. During runtime modification, these structures are
151575 + re-allocated according to the updated number of keys.
151576 +
151577 + Please note that 'action' and 'ic_indx_mask' mentioned in the
151578 + specific parameter explanations are passed in the extraction
151579 + parameters of the node (fields of extractccparams.extractnonhdr).
151580 +*//***************************************************************************/
151581 +typedef struct ioc_keys_params_t {
151582 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
151583 + A value of zero may be used for dynamic memory allocation. */
151584 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
151585 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
151586 + Should be TRUE to reserve table memory for key masks, even if
151587 + initial keys do not contain masks, or if the node was initialized
151588 + as 'empty' (without keys); this will allow user to add keys with
151589 + masks at runtime. */
151590 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
151591 + To enable statistics gathering, statistics should be enabled per
151592 + every key, using 'statistics_en' in next engine parameters structure
151593 + of that key;
151594 + If 'max_num_of_keys' is set, all required structures will be
151595 + preallocated for all keys. */
151596 +#if (DPAA_VERSION >= 11)
151597 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151598 + /**< Relevant only for 'RMON' statistics mode
151599 + (this feature is supported only on B4860 device);
151600 + Holds a list of programmable thresholds. For each received frame,
151601 + its length in bytes is examined against these range thresholds and
151602 + the appropriate counter is incremented by 1. For example, to belong
151603 + to range i, the following should hold:
151604 + range i-1 threshold < frame length <= range i threshold
151605 + Each range threshold must be larger then its preceding range
151606 + threshold. Last range threshold must be 0xFFFF. */
151607 +#endif /* (DPAA_VERSION >= 11) */
151608 + uint16_t num_of_keys; /**< Number of initial keys;
151609 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
151610 + this field should be power-of-2 of the number of bits that are
151611 + set in 'ic_indx_mask'. */
151612 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
151613 + to be the standard size of the selected key; For other extraction
151614 + types, 'key_size' has to be as size of extraction; When 'action' =
151615 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
151616 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
151617 + /**< An array with 'num_of_keys' entries, each entry specifies the
151618 + corresponding key parameters;
151619 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
151620 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
151621 + for the 'miss' entry. */
151622 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151623 + /**< Parameters for defining the next engine when a key is not matched;
151624 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
151625 +} ioc_keys_params_t;
151626 +
151627 +/**************************************************************************//**
151628 + @Description Parameters for defining a CC node
151629 +*//***************************************************************************/
151630 +typedef struct ioc_fm_pcd_cc_node_params_t {
151631 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
151632 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
151633 + void *id; /**< Output parameter; returns the CC node Id to be used */
151634 +} ioc_fm_pcd_cc_node_params_t;
151635 +
151636 +/**************************************************************************//**
151637 + @Description Parameters for defining a hash table
151638 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
151639 +*//***************************************************************************/
151640 +typedef struct ioc_fm_pcd_hash_table_params_t {
151641 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
151642 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
151643 + requested statistics mode will be allocated according to max_num_of_keys. */
151644 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
151645 + that leads to this hash-table. */
151646 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
151647 + The number-of-sets for this hash will be calculated
151648 + as (2^(number of bits set in 'hash_res_mask'));
151649 + The 4 lower bits must be cleared. */
151650 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
151651 + 2-bytes to be used as hash index. */
151652 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
151653 +
151654 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151655 + /**< Parameters for defining the next engine when a key is not matched */
151656 + void *id;
151657 +} ioc_fm_pcd_hash_table_params_t;
151658 +
151659 +/**************************************************************************//**
151660 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
151661 +*//***************************************************************************/
151662 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
151663 + void *p_hash_tbl;
151664 + uint8_t key_size;
151665 + ioc_fm_pcd_cc_key_params_t key_params;
151666 +} ioc_fm_pcd_hash_table_add_key_params_t;
151667 +
151668 +/**************************************************************************//**
151669 + @Description Parameters for defining a CC tree group.
151670 +
151671 + This structure defines a CC group in terms of NetEnv units
151672 + and the action to be taken in each case. The unit_ids list must
151673 + be given in order from low to high indices.
151674 +
151675 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
151676 + structures where each defines the next action to be taken for
151677 + each units combination. for example:
151678 + num_of_distinction_units = 2
151679 + unit_ids = {1,3}
151680 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151681 + unit 1 - not found; unit 3 - not found;
151682 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151683 + unit 1 - not found; unit 3 - found;
151684 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151685 + unit 1 - found; unit 3 - not found;
151686 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151687 + unit 1 - found; unit 3 - found;
151688 +*//***************************************************************************/
151689 +typedef struct ioc_fm_pcd_cc_grp_params_t {
151690 + uint8_t num_of_distinction_units; /**< Up to 4 */
151691 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
151692 + /**< Indexes of the units as defined in
151693 + FM_PCD_NetEnvCharacteristicsSet() */
151694 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
151695 + /**< Maximum entries per group is 16 */
151696 +} ioc_fm_pcd_cc_grp_params_t;
151697 +
151698 +/**************************************************************************//**
151699 + @Description Parameters for defining the CC tree groups
151700 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
151701 +*//***************************************************************************/
151702 +typedef struct ioc_fm_pcd_cc_tree_params_t {
151703 + void *net_env_id; /**< Id of the Network Environment as returned
151704 + by FM_PCD_NetEnvCharacteristicsSet() */
151705 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
151706 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
151707 + /**< Parameters for each group. */
151708 + void *id; /**< Output parameter; Returns the tree Id to be used */
151709 +} ioc_fm_pcd_cc_tree_params_t;
151710 +
151711 +/**************************************************************************//**
151712 + @Description Parameters for defining policer byte rate
151713 +*//***************************************************************************/
151714 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
151715 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
151716 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
151717 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
151718 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
151719 +
151720 +/**************************************************************************//**
151721 + @Description Parameters for defining the policer profile (based on
151722 + RFC-2698 or RFC-4115 attributes).
151723 +*//***************************************************************************/
151724 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
151725 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
151726 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
151727 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
151728 + uint32_t committed_burst_size; /**< KBits or Packets */
151729 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
151730 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
151731 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
151732 +
151733 +/**************************************************************************//**
151734 + @Description Parameters for defining the next engine after policer
151735 +*//***************************************************************************/
151736 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
151737 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151738 + void *p_profile; /**< Policer profile handle - used when next engine
151739 + is PLCR, must be a SHARED profile */
151740 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
151741 +} ioc_fm_pcd_plcr_next_engine_params_u;
151742 +
151743 +typedef struct ioc_fm_pcd_port_params_t {
151744 + ioc_fm_port_type port_type; /**< Type of port for this profile */
151745 + uint8_t port_id; /**< FM-Port id of port for this profile */
151746 +} ioc_fm_pcd_port_params_t;
151747 +
151748 +/**************************************************************************//**
151749 + @Description Parameters for defining the policer profile entry
151750 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
151751 +*//***************************************************************************/
151752 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151753 + bool modify; /**< TRUE to change an existing profile */
151754 + union {
151755 + struct {
151756 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151757 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151758 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151759 + } new_params; /**< Use it when modify = FALSE */
151760 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151761 + } profile_select;
151762 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151763 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151764 +
151765 + union {
151766 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151767 + any incoming packet with the default value. */
151768 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151769 + pre-color value of 2'b11. */
151770 + } color;
151771 +
151772 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151773 +
151774 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151775 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151776 +
151777 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151778 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151779 +
151780 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151781 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151782 +
151783 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151784 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151785 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151786 +
151787 + void *id; /**< output parameter; Returns the profile Id to be used */
151788 +} ioc_fm_pcd_plcr_profile_params_t;
151789 +
151790 +/**************************************************************************//**
151791 + @Description A structure for modifying CC tree next engine
151792 +*//***************************************************************************/
151793 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151794 + void *id; /**< CC tree Id to be used */
151795 + uint8_t grp_indx; /**< A Group index in the tree */
151796 + uint8_t indx; /**< Entry index in the group defined by grp_index */
151797 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151798 + /**< Parameters for the next for the defined Key in the p_Key */
151799 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
151800 +
151801 +/**************************************************************************//**
151802 + @Description A structure for modifying CC node next engine
151803 +*//***************************************************************************/
151804 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
151805 + void *id; /**< CC node Id to be used */
151806 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151807 + NOTE: This parameter is IGNORED for miss-key! */
151808 + uint8_t key_size; /**< Key size of added key */
151809 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151810 + /**< parameters for the next for the defined Key in the p_Key */
151811 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
151812 +
151813 +/**************************************************************************//**
151814 + @Description A structure for remove CC node key
151815 +*//***************************************************************************/
151816 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
151817 + void *id; /**< CC node Id to be used */
151818 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151819 + NOTE: This parameter is IGNORED for miss-key! */
151820 +} ioc_fm_pcd_cc_node_remove_key_params_t;
151821 +
151822 +/**************************************************************************//**
151823 + @Description A structure for modifying CC node key and next engine
151824 +*//***************************************************************************/
151825 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
151826 + void *id; /**< CC node Id to be used */
151827 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151828 + NOTE: This parameter is IGNORED for miss-key! */
151829 + uint8_t key_size; /**< Key size of added key */
151830 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
151831 + the array of the type ioc_fm_pcd_cc_key_params_t */
151832 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
151833 +
151834 +/**************************************************************************//**
151835 + @Description A structure for modifying CC node key
151836 +*//***************************************************************************/
151837 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
151838 + void *id; /**< CC node Id to be used */
151839 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151840 + NOTE: This parameter is IGNORED for miss-key! */
151841 + uint8_t key_size; /**< Key size of added key */
151842 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
151843 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
151844 + in keySize. p_Key and p_Mask (if defined) have to be
151845 + of the same size as defined in the key_size */
151846 +} ioc_fm_pcd_cc_node_modify_key_params_t;
151847 +
151848 +/**************************************************************************//**
151849 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
151850 +*//***************************************************************************/
151851 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
151852 + void *p_hash_tbl; /**< The id of the hash table */
151853 + uint8_t key_size; /**< The size of the key to remove */
151854 + uint8_t *p_key; /**< Pointer to the key to remove */
151855 +} ioc_fm_pcd_hash_table_remove_key_params_t;
151856 +
151857 +/**************************************************************************//**
151858 + @Description Parameters for selecting a location for requested manipulation
151859 +*//***************************************************************************/
151860 +typedef struct ioc_fm_manip_hdr_info_t {
151861 + ioc_net_header_type hdr; /**< Header selection */
151862 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
151863 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
151864 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
151865 +} ioc_fm_manip_hdr_info_t;
151866 +
151867 +/**************************************************************************//**
151868 + @Description Parameters for defining header removal by header type
151869 +*//***************************************************************************/
151870 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
151871 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
151872 + union {
151873 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151874 + struct {
151875 + bool include;/**< If FALSE, remove until the specified header (not including the header);
151876 + If TRUE, remove also the specified header. */
151877 + ioc_fm_manip_hdr_info_t hdr_info;
151878 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151879 +#endif /* FM_CAPWAP_SUPPORT */
151880 +#if (DPAA_VERSION >= 11)
151881 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151882 +#endif /* (DPAA_VERSION >= 11) */
151883 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
151884 + Defines which L2 headers to remove. */
151885 + } u;
151886 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
151887 +
151888 +/**************************************************************************//**
151889 + @Description Parameters for configuring IP fragmentation manipulation
151890 +*//***************************************************************************/
151891 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
151892 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151893 + IP fragmentation will be executed.*/
151894 +#if DPAA_VERSION == 10
151895 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
151896 +#endif /* DPAA_VERSION == 10 */
151897 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151898 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151899 + received frame's buffer. */
151900 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151901 + This parameter is relevant when 'sg_bpid_en=TRUE';
151902 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151903 + of this pool need to be allocated in the same memory area as the received buffers.
151904 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151905 + mutual to all these sources. */
151906 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
151907 + than MTU and its DF bit is set, then this field will
151908 + determine the action to be taken.*/
151909 +} ioc_fm_pcd_manip_frag_ip_params_t;
151910 +
151911 +/**************************************************************************//**
151912 + @Description Parameters for configuring IP reassembly manipulation.
151913 +
151914 + This is a common structure for both IPv4 and IPv6 reassembly
151915 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
151916 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
151917 +*//***************************************************************************/
151918 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
151919 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
151920 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
151921 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
151922 + NOTE: The following comment is relevant only for FMAN v2 devices:
151923 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
151924 + the user schemes id to ensure that the reassembly's schemes will be first match.
151925 + The remaining schemes, if defined, should have higher relative scheme ID. */
151926 +#if DPAA_VERSION >= 11
151927 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
151928 + profile than the opening fragment (Non-Consistent-SP state)
151929 + then one of two possible scenarios occurs:
151930 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
151931 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
151932 +#else
151933 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
151934 +#endif /* DPAA_VERSION >= 11 */
151935 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151936 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151937 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
151938 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
151939 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
151940 + /**< Number of frames per hash entry needed for reassembly process:
151941 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
151942 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
151943 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
151944 + Must be power of 2;
151945 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
151946 + maxNumFramesInProcess has to be in the range of 4 - 512;
151947 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151948 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151949 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151950 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
151951 + uint32_t timeout_threshold_for_reassm_process;
151952 + /**< Represents the time interval in microseconds which defines
151953 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151954 +} ioc_fm_pcd_manip_reassem_ip_params_t;
151955 +
151956 +/**************************************************************************//**
151957 + @Description Parameters for defining IPSEC manipulation
151958 +*//***************************************************************************/
151959 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
151960 + bool decryption; /**< TRUE if being used in decryption direction;
151961 + FALSE if being used in encryption direction. */
151962 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
151963 + (direction depends on the 'decryption' field). */
151964 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
151965 + (direction depends on the 'decryption' field). */
151966 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
151967 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
151968 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
151969 + It is specifies the length of the outer IP header that was configured in the
151970 + corresponding SA. */
151971 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
151972 + The value must be a multiplication of 16 */
151973 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
151974 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
151975 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
151976 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
151977 +
151978 +#if (DPAA_VERSION >= 11)
151979 +/**************************************************************************//**
151980 + @Description Parameters for configuring CAPWAP fragmentation manipulation
151981 +
151982 + Restrictions:
151983 + - Maximum number of fragments per frame is 16.
151984 + - Transmit confirmation is not supported.
151985 + - Fragmentation nodes must be set as the last PCD action (i.e. the
151986 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
151987 + - Only BMan buffers shall be used for frames to be fragmented.
151988 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
151989 + does not support VSP. Therefore, on the same port where we have IPF we
151990 + cannot support VSP.
151991 +*//***************************************************************************/
151992 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
151993 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151994 + CAPWAP fragmentation will be executed.*/
151995 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151996 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151997 + received frame's buffer. */
151998 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151999 + This parameters is relevant when 'sgBpidEn=TRUE';
152000 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
152001 + of this pool need to be allocated in the same memory area as the received buffers.
152002 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
152003 + mutual to all these sources. */
152004 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
152005 + When this mode is enabled then only the first fragment include the CAPWAP header options
152006 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
152007 + options field (CAPWAP header is updated accordingly).*/
152008 +} ioc_fm_pcd_manip_frag_capwap_params_t;
152009 +
152010 +/**************************************************************************//**
152011 + @Description Parameters for configuring CAPWAP reassembly manipulation.
152012 +
152013 + Restrictions:
152014 + - Application must define one scheme to catch the reassembled frames.
152015 + - Maximum number of fragments per frame is 16.
152016 +
152017 +*//***************************************************************************/
152018 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
152019 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
152020 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
152021 + Rest schemes, if defined, should have higher relative scheme ID. */
152022 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
152023 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
152024 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
152025 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
152026 + considered as a valid length;
152027 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
152028 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
152029 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
152030 + /**< Number of frames per hash entry needed for reassembly process */
152031 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
152032 + Must be power of 2;
152033 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
152034 + maxNumFramesInProcess has to be in the range of 4 - 512;
152035 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
152036 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
152037 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
152038 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
152039 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
152040 + uint32_t timeout_threshold_for_reassm_process;
152041 + /**< Represents the time interval in microseconds which defines
152042 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
152043 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
152044 +
152045 +/**************************************************************************//**
152046 + @Description structure for defining CAPWAP manipulation
152047 +*//***************************************************************************/
152048 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
152049 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
152050 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
152051 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
152052 +
152053 +#endif /* (DPAA_VERSION >= 11) */
152054 +
152055 +/**************************************************************************//**
152056 + @Description Parameters for defining special offload manipulation
152057 +*//***************************************************************************/
152058 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
152059 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
152060 + union
152061 + {
152062 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
152063 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
152064 +
152065 +#if (DPAA_VERSION >= 11)
152066 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
152067 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
152068 +#endif /* (DPAA_VERSION >= 11) */
152069 + } u;
152070 +} ioc_fm_pcd_manip_special_offload_params_t;
152071 +
152072 +/**************************************************************************//**
152073 + @Description Parameters for defining generic removal manipulation
152074 +*//***************************************************************************/
152075 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
152076 + uint8_t offset; /**< Offset from beginning of header to the start
152077 + location of the removal */
152078 + uint8_t size; /**< Size of removed section */
152079 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
152080 +
152081 +/**************************************************************************//**
152082 + @Description Parameters for defining insertion manipulation
152083 +*//***************************************************************************/
152084 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
152085 + uint8_t size; /**< size of inserted section */
152086 + uint8_t *p_data; /**< data to be inserted */
152087 +} ioc_fm_pcd_manip_hdr_insrt_t;
152088 +
152089 +/**************************************************************************//**
152090 + @Description Parameters for defining generic insertion manipulation
152091 +*//***************************************************************************/
152092 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
152093 + uint8_t offset; /**< Offset from beginning of header to the start
152094 + location of the insertion */
152095 + uint8_t size; /**< Size of inserted section */
152096 + bool replace; /**< TRUE to override (replace) existing data at
152097 + 'offset', FALSE to insert */
152098 + uint8_t *p_data; /**< Pointer to data to be inserted */
152099 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
152100 +
152101 +/**************************************************************************//**
152102 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
152103 +*//***************************************************************************/
152104 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
152105 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
152106 + /**< A table of VPri values for each DSCP value;
152107 + The index is the D_SCP value (0-0x3F) and the
152108 + value is the corresponding VPRI (0-15). */
152109 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
152110 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
152111 + this field is the Q Tag default value if the
152112 + IP header is not found. */
152113 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
152114 +
152115 +/**************************************************************************//**
152116 + @Description Parameters for defining header manipulation VLAN fields updates
152117 +*//***************************************************************************/
152118 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
152119 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
152120 + union {
152121 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
152122 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
152123 + is the new VLAN pri. */
152124 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
152125 + /**< Parameters structure, Relevant only if update_type =
152126 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
152127 + } u;
152128 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
152129 +
152130 +/**************************************************************************//**
152131 + @Description Parameters for defining header manipulation IPV4 fields updates
152132 +*//***************************************************************************/
152133 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
152134 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152135 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
152136 + IOC_HDR_MANIP_IPV4_TOS */
152137 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
152138 + contains IOC_HDR_MANIP_IPV4_ID */
152139 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
152140 + contains IOC_HDR_MANIP_IPV4_SRC */
152141 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
152142 + contains IOC_HDR_MANIP_IPV4_DST */
152143 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
152144 +
152145 +/**************************************************************************//**
152146 + @Description Parameters for defining header manipulation IPV6 fields updates
152147 +*//***************************************************************************/
152148 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
152149 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152150 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
152151 + IOC_HDR_MANIP_IPV6_TC */
152152 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
152153 + /**< 16 byte new IP SRC; Relevant only if valid_updates
152154 + contains IOC_HDR_MANIP_IPV6_SRC */
152155 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
152156 + /**< 16 byte new IP DST; Relevant only if valid_updates
152157 + contains IOC_HDR_MANIP_IPV6_DST */
152158 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
152159 +
152160 +/**************************************************************************//**
152161 + @Description Parameters for defining header manipulation TCP/UDP fields updates
152162 +*//***************************************************************************/
152163 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
152164 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152165 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
152166 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
152167 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
152168 + contains IOC_HDR_MANIP_TCP_UDP_DST */
152169 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
152170 +
152171 +/**************************************************************************//**
152172 + @Description Parameters for defining header manipulation fields updates
152173 +*//***************************************************************************/
152174 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
152175 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
152176 + union {
152177 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
152178 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
152179 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
152180 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
152181 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
152182 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
152183 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
152184 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
152185 + } u;
152186 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
152187 +
152188 +/**************************************************************************//**
152189 + @Description Parameters for defining custom header manipulation for IP replacement
152190 +*//***************************************************************************/
152191 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
152192 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
152193 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
152194 + bool update_ipv4_id; /**< Relevant when replace_type =
152195 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
152196 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
152197 + update_ipv4_id = TRUE */
152198 + uint8_t hdr_size; /**< The size of the new IP header */
152199 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
152200 + /**< The new IP header */
152201 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
152202 +
152203 +/**************************************************************************//**
152204 + @Description Parameters for defining custom header manipulation
152205 +*//***************************************************************************/
152206 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
152207 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
152208 + union {
152209 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
152210 + /**< Parameters IP header replacement */
152211 + } u;
152212 +} ioc_fm_pcd_manip_hdr_custom_params_t;
152213 +
152214 +/**************************************************************************//**
152215 + @Description Parameters for defining specific L2 insertion manipulation
152216 +*//***************************************************************************/
152217 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
152218 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
152219 + bool update; /**< TRUE to update MPLS header */
152220 + uint8_t size; /**< size of inserted section */
152221 + uint8_t *p_data; /**< data to be inserted */
152222 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
152223 +
152224 +#if (DPAA_VERSION >= 11)
152225 +/**************************************************************************//**
152226 + @Description Parameters for defining IP insertion manipulation
152227 +*//***************************************************************************/
152228 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
152229 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
152230 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
152231 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
152232 + the inserted header */
152233 + uint16_t id; /**< 16 bit New IP ID */
152234 + bool dont_frag_overwrite;
152235 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
152236 + * This byte is configured to be overwritten when RPD is set. */
152237 + uint8_t last_dst_offset;
152238 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
152239 + * in order to calculate UDP checksum pseudo header;
152240 + * Otherwise set it to '0'. */
152241 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
152242 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
152243 +#endif /* (DPAA_VERSION >= 11) */
152244 +
152245 +/**************************************************************************//**
152246 + @Description Parameters for defining header insertion manipulation by header type
152247 +*//***************************************************************************/
152248 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
152249 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
152250 + union {
152251 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
152252 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
152253 + Selects which L2 headers to remove */
152254 +#if (DPAA_VERSION >= 11)
152255 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
152256 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
152257 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
152258 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
152259 +#endif /* (DPAA_VERSION >= 11) */
152260 + } u;
152261 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
152262 +
152263 +/**************************************************************************//**
152264 + @Description Parameters for defining header insertion manipulation
152265 +*//***************************************************************************/
152266 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
152267 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
152268 + union {
152269 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
152270 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
152271 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
152272 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
152273 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152274 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
152275 + /**< Parameters for defining header insertion manipulation by template,
152276 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
152277 +#endif /* FM_CAPWAP_SUPPORT */
152278 + } u;
152279 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
152280 +
152281 +/**************************************************************************//**
152282 + @Description Parameters for defining header removal manipulation
152283 +*//***************************************************************************/
152284 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
152285 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
152286 + union {
152287 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
152288 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
152289 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
152290 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
152291 + } u;
152292 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
152293 +
152294 +/**************************************************************************//**
152295 + @Description Parameters for defining header manipulation node
152296 +*//***************************************************************************/
152297 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
152298 + bool rmv; /**< TRUE, to define removal manipulation */
152299 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
152300 +
152301 + bool insrt; /**< TRUE, to define insertion manipulation */
152302 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
152303 +
152304 + bool field_update; /**< TRUE, to define field update manipulation */
152305 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
152306 +
152307 + bool custom; /**< TRUE, to define custom manipulation */
152308 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
152309 +
152310 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
152311 + completing the manipulation on the frame */
152312 +} ioc_fm_pcd_manip_hdr_params_t;
152313 +
152314 +
152315 +/**************************************************************************//**
152316 + @Description structure for defining fragmentation manipulation
152317 +*//***************************************************************************/
152318 +typedef struct ioc_fm_pcd_manip_frag_params_t {
152319 + ioc_net_header_type hdr; /**< Header selection */
152320 + union {
152321 +#if (DPAA_VERSION >= 11)
152322 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
152323 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152324 +#endif /* (DPAA_VERSION >= 11) */
152325 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
152326 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152327 + } u;
152328 +} ioc_fm_pcd_manip_frag_params_t;
152329 +
152330 +/**************************************************************************//**
152331 + @Description structure for defining reassemble manipulation
152332 +*//***************************************************************************/
152333 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
152334 + ioc_net_header_type hdr; /**< Header selection */
152335 + union {
152336 +#if (DPAA_VERSION >= 11)
152337 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
152338 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152339 +#endif /* (DPAA_VERSION >= 11) */
152340 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
152341 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152342 + } u;
152343 +} ioc_fm_pcd_manip_reassem_params_t;
152344 +
152345 +/**************************************************************************//**
152346 + @Description Parameters for defining a manipulation node
152347 +*//***************************************************************************/
152348 +typedef struct ioc_fm_pcd_manip_params_t {
152349 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
152350 + union {
152351 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
152352 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
152353 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
152354 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
152355 + } u;
152356 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
152357 + Allows concatenation of manipulation actions
152358 + This parameter is optional and may be NULL. */
152359 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152360 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
152361 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
152362 + relevant if frag_or_reasm = TRUE */
152363 +#endif /* FM_CAPWAP_SUPPORT */
152364 + void *id;
152365 +} ioc_fm_pcd_manip_params_t;
152366 +
152367 +/**************************************************************************//**
152368 + @Description Structure for retrieving IP reassembly statistics
152369 +*//***************************************************************************/
152370 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
152371 + /* common counters for both IPv4 and IPv6 */
152372 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
152373 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152374 + a Reassembly Frame Descriptor */
152375 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152376 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152377 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152378 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152379 +#if (DPAA_VERSION >= 11)
152380 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
152381 + successfully reassembled frames */
152382 +#endif /* (DPAA_VERSION >= 11) */
152383 +struct {
152384 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152385 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152386 + have been processed for all frames */
152387 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152388 + (valid and error fragments) for all frames */
152389 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152390 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152391 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
152392 + to access an IP-Reassembly Automatic Learning Hash set */
152393 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152394 + exceeds 16 */
152395 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
152396 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
152397 +
152398 +/**************************************************************************//**
152399 + @Description Structure for retrieving IP fragmentation statistics
152400 +*//***************************************************************************/
152401 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
152402 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152403 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152404 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152405 +} ioc_fm_pcd_manip_frag_ip_stats_t;
152406 +
152407 +#if (DPAA_VERSION >= 11)
152408 +/**************************************************************************//**
152409 + @Description Structure for retrieving CAPWAP reassembly statistics
152410 +*//***************************************************************************/
152411 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
152412 + uint32_t timeout; /**< Counts the number of timeout occurrences */
152413 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152414 + a Reassembly Frame Descriptor */
152415 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152416 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152417 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152418 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152419 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152420 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152421 + have been processed for all frames */
152422 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152423 + (valid and error fragments) for all frames */
152424 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152425 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
152426 + to access an Reassembly Automatic Learning Hash set */
152427 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152428 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152429 + exceeds 16 */
152430 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
152431 + length exceeds MaxReassembledFrameLength value */
152432 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
152433 +
152434 +/**************************************************************************//**
152435 + @Description Structure for retrieving CAPWAP fragmentation statistics
152436 +*//***************************************************************************/
152437 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
152438 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152439 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152440 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152441 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
152442 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
152443 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
152444 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
152445 +#endif /* (DPAA_VERSION >= 11) */
152446 +
152447 +/**************************************************************************//**
152448 + @Description Structure for retrieving reassembly statistics
152449 +*//***************************************************************************/
152450 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
152451 + union {
152452 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
152453 +#if (DPAA_VERSION >= 11)
152454 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
152455 +#endif /* (DPAA_VERSION >= 11) */
152456 + } u;
152457 +} ioc_fm_pcd_manip_reassem_stats_t;
152458 +
152459 +/**************************************************************************//**
152460 + @Description structure for retrieving fragmentation statistics
152461 +*//***************************************************************************/
152462 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
152463 + union {
152464 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
152465 +#if (DPAA_VERSION >= 11)
152466 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
152467 +#endif /* (DPAA_VERSION >= 11) */
152468 + } u;
152469 +} ioc_fm_pcd_manip_frag_stats_t;
152470 +
152471 +/**************************************************************************//**
152472 + @Description structure for defining manipulation statistics
152473 +*//***************************************************************************/
152474 +typedef struct ioc_fm_pcd_manip_stats_t {
152475 + union {
152476 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
152477 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
152478 + } u;
152479 +} ioc_fm_pcd_manip_stats_t;
152480 +
152481 +/**************************************************************************//**
152482 + @Description Parameters for acquiring manipulation statistics
152483 +*//***************************************************************************/
152484 +typedef struct ioc_fm_pcd_manip_get_stats_t {
152485 + void *id;
152486 + ioc_fm_pcd_manip_stats_t stats;
152487 +} ioc_fm_pcd_manip_get_stats_t;
152488 +
152489 +#if DPAA_VERSION >= 11
152490 +/**************************************************************************//**
152491 + @Description Parameters for defining frame replicator group and its members
152492 +*//***************************************************************************/
152493 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
152494 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
152495 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
152496 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
152497 + /**< Array of members' parameters */
152498 + void *id;
152499 +} ioc_fm_pcd_frm_replic_group_params_t;
152500 +
152501 +typedef struct ioc_fm_pcd_frm_replic_member_t {
152502 + void *h_replic_group;
152503 + uint16_t member_index;
152504 +} ioc_fm_pcd_frm_replic_member_t;
152505 +
152506 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
152507 + ioc_fm_pcd_frm_replic_member_t member;
152508 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
152509 +} ioc_fm_pcd_frm_replic_member_params_t;
152510 +#endif /* DPAA_VERSION >= 11 */
152511 +
152512 +
152513 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
152514 + uint32_t byte_count; /**< This counter reflects byte count of frames that
152515 + were matched by this key. */
152516 + uint32_t frame_count; /**< This counter reflects count of frames that
152517 + were matched by this key. */
152518 +#if (DPAA_VERSION >= 11)
152519 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
152520 + /**< These counters reflect how many frames matched
152521 + this key in 'RMON' statistics mode:
152522 + Each counter holds the number of frames of a
152523 + specific frames length range, according to the
152524 + ranges provided at initialization. */
152525 +#endif /* (DPAA_VERSION >= 11) */
152526 +} ioc_fm_pcd_cc_key_statistics_t;
152527 +
152528 +
152529 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
152530 + void *id;
152531 + uint16_t key_index;
152532 + ioc_fm_pcd_cc_key_statistics_t statistics;
152533 +} ioc_fm_pcd_cc_tbl_get_stats_t;
152534 +
152535 +/**************************************************************************//**
152536 + @Function FM_PCD_MatchTableGetKeyStatistics
152537 +
152538 + @Description This routine may be used to get statistics counters of specific key
152539 + in a CC Node.
152540 +
152541 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152542 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152543 + these counters reflect how many frames passed that were matched
152544 + this key; The total frames count will be returned in the counter
152545 + of the first range (as only one frame length range was defined).
152546 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
152547 + frame count will be separated to frame length counters, based on
152548 + provided frame length ranges.
152549 +
152550 + @Param[in] h_CcNode A handle to the node
152551 + @Param[in] keyIndex Key index for adding
152552 + @Param[out] p_KeyStatistics Key statistics counters
152553 +
152554 + @Return The specific key statistics.
152555 +
152556 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152557 +*//***************************************************************************/
152558 +
152559 +#if defined(CONFIG_COMPAT)
152560 +#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)
152561 +#endif
152562 +#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)
152563 +
152564 +/**************************************************************************//**
152565 + @Function FM_PCD_MatchTableGetMissStatistics
152566 +
152567 + @Description This routine may be used to get statistics counters of miss entry
152568 + in a CC Node.
152569 +
152570 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152571 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152572 + these counters reflect how many frames were not matched to any
152573 + existing key and therefore passed through the miss entry; The
152574 + total frames count will be returned in the counter of the
152575 + first range (as only one frame length range was defined).
152576 +
152577 + @Param[in] h_CcNode A handle to the node
152578 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152579 +
152580 + @Return E_OK on success; Error code otherwise.
152581 +
152582 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152583 +*//***************************************************************************/
152584 +
152585 +#if defined(CONFIG_COMPAT)
152586 +#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)
152587 +#endif
152588 +#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)
152589 +
152590 +/**************************************************************************//**
152591 + @Function FM_PCD_HashTableGetMissStatistics
152592 +
152593 + @Description This routine may be used to get statistics counters of 'miss'
152594 + entry of the a hash table.
152595 +
152596 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152597 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152598 + these counters reflect how many frames were not matched to any
152599 + existing key and therefore passed through the miss entry;
152600 +
152601 + @Param[in] h_HashTbl A handle to a hash table
152602 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152603 +
152604 + @Return E_OK on success; Error code otherwise.
152605 +
152606 + @Cautions Allowed only following FM_PCD_HashTableSet().
152607 +*//***************************************************************************/
152608 +
152609 +#if defined(CONFIG_COMPAT)
152610 +#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)
152611 +#endif
152612 +#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)
152613 +
152614 +
152615 +/**************************************************************************//**
152616 + @Function FM_PCD_NetEnvCharacteristicsSet
152617 +
152618 + @Description Define a set of Network Environment Characteristics.
152619 +
152620 + When setting an environment it is important to understand its
152621 + application. It is not meant to describe the flows that will run
152622 + on the ports using this environment, but what the user means TO DO
152623 + with the PCD mechanisms in order to parse-classify-distribute those
152624 + frames.
152625 + By specifying a distinction unit, the user means it would use that option
152626 + for distinction between frames at either a KeyGen scheme or a coarse
152627 + classification action descriptor. Using interchangeable headers to define a
152628 + unit means that the user is indifferent to which of the interchangeable
152629 + headers is present in the frame, and wants the distinction to be based
152630 + on the presence of either one of them.
152631 +
152632 + Depending on context, there are limitations to the use of environments. A
152633 + port using the PCD functionality is bound to an environment. Some or even
152634 + all ports may share an environment but also an environment per port is
152635 + possible. When initializing a scheme, a classification plan group (see below),
152636 + or a coarse classification tree, one of the initialized environments must be
152637 + stated and related to. When a port is bound to a scheme, a classification
152638 + plan group, or a coarse classification tree, it MUST be bound to the same
152639 + environment.
152640 +
152641 + The different PCD modules, may relate (for flows definition) ONLY on
152642 + distinction units as defined by their environment. When initializing a
152643 + scheme for example, it may not choose to select IPV4 as a match for
152644 + recognizing flows unless it was defined in the relating environment. In
152645 + fact, to guide the user through the configuration of the PCD, each module's
152646 + characterization in terms of flows is not done using protocol names, but using
152647 + environment indexes.
152648 +
152649 + In terms of HW implementation, the list of distinction units sets the LCV vectors
152650 + and later used for match vector, classification plan vectors and coarse classification
152651 + indexing.
152652 +
152653 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
152654 +
152655 + @Return 0 on success; Error code otherwise.
152656 +*//***************************************************************************/
152657 +#if defined(CONFIG_COMPAT)
152658 +#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)
152659 +#endif
152660 +#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)
152661 +
152662 +/**************************************************************************//**
152663 + @Function FM_PCD_NetEnvCharacteristicsDelete
152664 +
152665 + @Description Deletes a set of Network Environment Charecteristics.
152666 +
152667 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
152668 +
152669 + @Return 0 on success; Error code otherwise.
152670 +*//***************************************************************************/
152671 +#if defined(CONFIG_COMPAT)
152672 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
152673 +#endif
152674 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
152675 +
152676 +/**************************************************************************//**
152677 + @Function FM_PCD_KgSchemeSet
152678 +
152679 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
152680 + This routine should be called for adding or modifying a scheme.
152681 + When a scheme needs modifying, the API requires that it will be
152682 + rewritten. In such a case 'modify' should be TRUE. If the
152683 + routine is called for a valid scheme and 'modify' is FALSE,
152684 + it will return error.
152685 +
152686 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
152687 +
152688 + @Return 0 on success; Error code otherwise.
152689 +*//***************************************************************************/
152690 +#if defined(CONFIG_COMPAT)
152691 +#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)
152692 +#endif
152693 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
152694 +
152695 +/**************************************************************************//**
152696 + @Function FM_PCD_KgSchemeDelete
152697 +
152698 + @Description Deleting an initialized scheme.
152699 +
152700 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
152701 +
152702 + @Return 0 on success; Error code otherwise.
152703 +*//***************************************************************************/
152704 +#if defined(CONFIG_COMPAT)
152705 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
152706 +#endif
152707 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
152708 +
152709 +/**************************************************************************//**
152710 + @Function FM_PCD_CcRootBuild
152711 +
152712 + @Description This routine must be called to define a complete coarse
152713 + classification tree. This is the way to define coarse
152714 + classification to a certain flow - the KeyGen schemes
152715 + may point only to trees defined in this way.
152716 +
152717 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
152718 +
152719 + @Return 0 on success; Error code otherwise.
152720 +*//***************************************************************************/
152721 +#if defined(CONFIG_COMPAT)
152722 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
152723 +#endif
152724 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
152725 +
152726 +/**************************************************************************//**
152727 + @Function FM_PCD_CcRootDelete
152728 +
152729 + @Description Deleting a built tree.
152730 +
152731 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
152732 +*//***************************************************************************/
152733 +#if defined(CONFIG_COMPAT)
152734 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
152735 +#endif
152736 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
152737 +
152738 +/**************************************************************************//**
152739 + @Function FM_PCD_MatchTableSet
152740 +
152741 + @Description This routine should be called for each CC (coarse classification)
152742 + node. The whole CC tree should be built bottom up so that each
152743 + node points to already defined nodes. p_NodeId returns the node
152744 + Id to be used by other nodes.
152745 +
152746 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
152747 +
152748 + @Return 0 on success; Error code otherwise.
152749 +*//***************************************************************************/
152750 +#if defined(CONFIG_COMPAT)
152751 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
152752 +#endif
152753 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152754 +
152755 +/**************************************************************************//**
152756 + @Function FM_PCD_MatchTableDelete
152757 +
152758 + @Description Deleting a built node.
152759 +
152760 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152761 +
152762 + @Return 0 on success; Error code otherwise.
152763 +*//***************************************************************************/
152764 +#if defined(CONFIG_COMPAT)
152765 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152766 +#endif
152767 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152768 +
152769 +/**************************************************************************//**
152770 + @Function FM_PCD_CcRootModifyNextEngine
152771 +
152772 + @Description Modify the Next Engine Parameters in the entry of the tree.
152773 +
152774 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152775 +
152776 + @Return 0 on success; Error code otherwise.
152777 +
152778 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152779 +*//***************************************************************************/
152780 +#if defined(CONFIG_COMPAT)
152781 +#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)
152782 +#endif
152783 +#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)
152784 +
152785 +/**************************************************************************//**
152786 + @Function FM_PCD_MatchTableModifyNextEngine
152787 +
152788 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152789 +
152790 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152791 +
152792 + @Return 0 on success; Error code otherwise.
152793 +
152794 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152795 +*//***************************************************************************/
152796 +#if defined(CONFIG_COMPAT)
152797 +#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)
152798 +#endif
152799 +#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)
152800 +
152801 +/**************************************************************************//**
152802 + @Function FM_PCD_MatchTableModifyMissNextEngine
152803 +
152804 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
152805 +
152806 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152807 +
152808 + @Return 0 on success; Error code otherwise.
152809 +
152810 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152811 +*//***************************************************************************/
152812 +#if defined(CONFIG_COMPAT)
152813 +#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)
152814 +#endif
152815 +#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)
152816 +
152817 +/**************************************************************************//**
152818 + @Function FM_PCD_MatchTableRemoveKey
152819 +
152820 + @Description Remove the key (including next engine parameters of this key)
152821 + defined by the index of the relevant node.
152822 +
152823 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
152824 +
152825 + @Return 0 on success; Error code otherwise.
152826 +
152827 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152828 + node and for all of the nodes that lead to it.
152829 +*//***************************************************************************/
152830 +#if defined(CONFIG_COMPAT)
152831 +#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)
152832 +#endif
152833 +#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)
152834 +
152835 +/**************************************************************************//**
152836 + @Function FM_PCD_MatchTableAddKey
152837 +
152838 + @Description Add the key (including next engine parameters of this key in the
152839 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
152840 + may be used when the user doesn't care about the position of the
152841 + key in the table - in that case, the key will be automatically
152842 + added by the driver in the last available entry.
152843 +
152844 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152845 +
152846 + @Return 0 on success; Error code otherwise.
152847 +
152848 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152849 + node and for all of the nodes that lead to it.
152850 +*//***************************************************************************/
152851 +#if defined(CONFIG_COMPAT)
152852 +#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)
152853 +#endif
152854 +#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)
152855 +
152856 +/**************************************************************************//**
152857 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
152858 +
152859 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
152860 +
152861 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152862 +
152863 + @Return 0 on success; Error code otherwise.
152864 +
152865 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
152866 + the node that points to this node
152867 +*//***************************************************************************/
152868 +#if defined(CONFIG_COMPAT)
152869 +#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)
152870 +#endif
152871 +#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)
152872 +
152873 +/**************************************************************************//**
152874 + @Function FM_PCD_MatchTableModifyKey
152875 +
152876 + @Description Modify the key at the index defined by key_index.
152877 +
152878 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
152879 +
152880 + @Return 0 on success; Error code otherwise.
152881 +
152882 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152883 + node and for all of the nodes that lead to it.
152884 +*//***************************************************************************/
152885 +#if defined(CONFIG_COMPAT)
152886 +#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)
152887 +#endif
152888 +#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)
152889 +
152890 +/**************************************************************************//**
152891 + @Function FM_PCD_HashTableSet
152892 +
152893 + @Description This routine initializes a hash table structure.
152894 + KeyGen hash result determines the hash bucket.
152895 + Next, KeyGen key is compared against all keys of this
152896 + bucket (exact match).
152897 + Number of sets (number of buckets) of the hash equals to the
152898 + number of 1-s in 'hash_res_mask' in the provided parameters.
152899 + Number of hash table ways is then calculated by dividing
152900 + 'max_num_of_keys' equally between the hash sets. This is the maximal
152901 + number of keys that a hash bucket may hold.
152902 + The hash table is initialized empty and keys may be
152903 + added to it following the initialization. Keys masks are not
152904 + supported in current hash table implementation.
152905 + The initialized hash table can be integrated as a node in a
152906 + CC tree.
152907 +
152908 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
152909 +
152910 + @Return 0 on success; Error code otherwise.
152911 +*//***************************************************************************/
152912 +#if defined(CONFIG_COMPAT)
152913 +#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)
152914 +#endif
152915 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
152916 +
152917 +
152918 +/**************************************************************************//**
152919 + @Function FM_PCD_HashTableDelete
152920 +
152921 + @Description This routine deletes the provided hash table and released all
152922 + its allocated resources.
152923 +
152924 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
152925 +
152926 + @Return 0 on success; Error code otherwise.
152927 +
152928 + @Cautions Allowed only following FM_PCD_HashTableSet().
152929 +*//***************************************************************************/
152930 +#if defined(CONFIG_COMPAT)
152931 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
152932 +#endif
152933 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
152934 +
152935 +/**************************************************************************//**
152936 + @Function FM_PCD_HashTableAddKey
152937 +
152938 + @Description This routine adds the provided key (including next engine
152939 + parameters of this key) to the hash table.
152940 + The key is added as the last key of the bucket that it is
152941 + mapped to.
152942 +
152943 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
152944 +
152945 + @Return 0 on success; error code otherwise.
152946 +
152947 + @Cautions Allowed only following FM_PCD_HashTableSet().
152948 +*//***************************************************************************/
152949 +#if defined(CONFIG_COMPAT)
152950 +#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)
152951 +#endif
152952 +#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)
152953 +
152954 +/**************************************************************************//**
152955 + @Function FM_PCD_HashTableRemoveKey
152956 +
152957 + @Description This routine removes the requested key (including next engine
152958 + parameters of this key) from the hash table.
152959 +
152960 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
152961 +
152962 + @Return 0 on success; Error code otherwise.
152963 +
152964 + @Cautions Allowed only following FM_PCD_HashTableSet().
152965 +*//***************************************************************************/
152966 +#if defined(CONFIG_COMPAT)
152967 +#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)
152968 +#endif
152969 +#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)
152970 +
152971 +/**************************************************************************//**
152972 + @Function FM_PCD_PlcrProfileSet
152973 +
152974 + @Description Sets a profile entry in the policer profile table.
152975 + The routine overrides any existing value.
152976 +
152977 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
152978 + policer profile entry.
152979 +
152980 + @Return 0 on success; Error code otherwise.
152981 +*//***************************************************************************/
152982 +#if defined(CONFIG_COMPAT)
152983 +#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)
152984 +#endif
152985 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
152986 +
152987 +/**************************************************************************//**
152988 + @Function FM_PCD_PlcrProfileDelete
152989 +
152990 + @Description Delete a profile entry in the policer profile table.
152991 + The routine set entry to invalid.
152992 +
152993 + @Param[in] ioc_fm_obj_t The id of a policer profile.
152994 +
152995 + @Return 0 on success; Error code otherwise.
152996 +*//***************************************************************************/
152997 +#if defined(CONFIG_COMPAT)
152998 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
152999 +#endif
153000 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
153001 +
153002 +/**************************************************************************//**
153003 + @Function FM_PCD_ManipNodeSet
153004 +
153005 + @Description This routine should be called for defining a manipulation
153006 + node. A manipulation node must be defined before the CC node
153007 + that precedes it.
153008 +
153009 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
153010 +
153011 + @Return A handle to the initialized object on success; NULL code otherwise.
153012 +*//***************************************************************************/
153013 +#if defined(CONFIG_COMPAT)
153014 +#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)
153015 +#endif
153016 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
153017 +
153018 +/**************************************************************************//**
153019 + @Function FM_PCD_ManipNodeReplace
153020 +
153021 + @Description Change existing manipulation node to be according to new requirement.
153022 + (Here, it's implemented as a variant of the same IOCTL as for
153023 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
153024 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
153025 + the manip node's handle)
153026 +
153027 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
153028 +
153029 + @Return 0 on success; error code otherwise.
153030 +
153031 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153032 +*//***************************************************************************/
153033 +#if defined(CONFIG_COMPAT)
153034 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
153035 +#endif
153036 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
153037 +
153038 +/**************************************************************************//**
153039 + @Function FM_PCD_ManipNodeDelete
153040 +
153041 + @Description Delete an existing manipulation node.
153042 +
153043 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
153044 +
153045 + @Return 0 on success; error code otherwise.
153046 +
153047 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153048 +*//***************************************************************************/
153049 +#if defined(CONFIG_COMPAT)
153050 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
153051 +#endif
153052 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
153053 +
153054 +/**************************************************************************//**
153055 + @Function FM_PCD_ManipGetStatistics
153056 +
153057 + @Description Retrieve the manipulation statistics.
153058 +
153059 + @Param[in] h_ManipNode A handle to a manipulation node.
153060 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
153061 +
153062 + @Return E_OK on success; Error code otherwise.
153063 +
153064 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153065 +*//***************************************************************************/
153066 +#if defined(CONFIG_COMPAT)
153067 +#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)
153068 +#endif
153069 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
153070 +
153071 +/**************************************************************************//**
153072 +@Function FM_PCD_SetAdvancedOffloadSupport
153073 +
153074 +@Description This routine must be called in order to support the following features:
153075 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
153076 +
153077 +@Param[in] h_FmPcd FM PCD module descriptor.
153078 +
153079 +@Return 0 on success; error code otherwise.
153080 +
153081 +@Cautions Allowed only when PCD is disabled.
153082 +*//***************************************************************************/
153083 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
153084 +
153085 +#if (DPAA_VERSION >= 11)
153086 +/**************************************************************************//**
153087 + @Function FM_PCD_FrmReplicSetGroup
153088 +
153089 + @Description Initialize a Frame Replicator group.
153090 +
153091 + @Param[in] h_FmPcd FM PCD module descriptor.
153092 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
153093 + the frame replicator group.
153094 +
153095 + @Return A handle to the initialized object on success; NULL code otherwise.
153096 +
153097 + @Cautions Allowed only following FM_PCD_Init().
153098 +*//***************************************************************************/
153099 +#if defined(CONFIG_COMPAT)
153100 +#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)
153101 +#endif
153102 +#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)
153103 +
153104 +/**************************************************************************//**
153105 + @Function FM_PCD_FrmReplicDeleteGroup
153106 +
153107 + @Description Delete a Frame Replicator group.
153108 +
153109 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153110 +
153111 + @Return E_OK on success; Error code otherwise.
153112 +
153113 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
153114 +*//***************************************************************************/
153115 +#if defined(CONFIG_COMPAT)
153116 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
153117 +#endif
153118 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
153119 +
153120 +/**************************************************************************//**
153121 + @Function FM_PCD_FrmReplicAddMember
153122 +
153123 + @Description Add the member in the index defined by the memberIndex.
153124 +
153125 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153126 + @Param[in] memberIndex member index for adding.
153127 + @Param[in] p_MemberParams A pointer to the new member parameters.
153128 +
153129 + @Return E_OK on success; Error code otherwise.
153130 +
153131 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
153132 +*//***************************************************************************/
153133 +#if defined(CONFIG_COMPAT)
153134 +#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)
153135 +#endif
153136 +#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)
153137 +
153138 +/**************************************************************************//**
153139 + @Function FM_PCD_FrmReplicRemoveMember
153140 +
153141 + @Description Remove the member defined by the index from the relevant group.
153142 +
153143 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153144 + @Param[in] memberIndex member index for removing.
153145 +
153146 + @Return E_OK on success; Error code otherwise.
153147 +
153148 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
153149 +*//***************************************************************************/
153150 +#if defined(CONFIG_COMPAT)
153151 +#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)
153152 +#endif
153153 +#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)
153154 +
153155 +#endif
153156 +
153157 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153158 +/**************************************************************************//**
153159 + @Function FM_PCD_StatisticsSetNode
153160 +
153161 + @Description This routine should be called for defining a statistics node.
153162 +
153163 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
153164 +
153165 + @Return 0 on success; Error code otherwise.
153166 +*//***************************************************************************/
153167 +#if defined(CONFIG_COMPAT)
153168 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
153169 +#endif
153170 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
153171 +
153172 +#endif /* FM_CAPWAP_SUPPORT */
153173 +
153174 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
153175 +#if defined(CONFIG_COMPAT)
153176 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
153177 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
153178 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
153179 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
153180 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
153181 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
153182 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
153183 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
153184 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
153185 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
153186 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
153187 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
153188 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
153189 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
153190 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
153191 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
153192 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
153193 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
153194 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
153195 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
153196 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
153197 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
153198 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
153199 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
153200 +#endif
153201 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
153202 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
153203 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
153204 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
153205 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
153206 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
153207 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
153208 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
153209 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
153210 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
153211 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
153212 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
153213 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
153214 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
153215 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
153216 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
153217 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
153218 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
153219 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
153220 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
153221 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
153222 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
153223 +
153224 +#endif /* __FM_PCD_IOCTLS_H */
153225 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
153226 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
153227 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153228 diff --git a/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
153229 new file mode 100644
153230 index 00000000..a2f61107
153231 --- /dev/null
153232 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
153233 @@ -0,0 +1,948 @@
153234 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153235 + * All rights reserved.
153236 + *
153237 + * Redistribution and use in source and binary forms, with or without
153238 + * modification, are permitted provided that the following conditions are met:
153239 + * * Redistributions of source code must retain the above copyright
153240 + * notice, this list of conditions and the following disclaimer.
153241 + * * Redistributions in binary form must reproduce the above copyright
153242 + * notice, this list of conditions and the following disclaimer in the
153243 + * documentation and/or other materials provided with the distribution.
153244 + * * Neither the name of Freescale Semiconductor nor the
153245 + * names of its contributors may be used to endorse or promote products
153246 + * derived from this software without specific prior written permission.
153247 + *
153248 + *
153249 + * ALTERNATIVELY, this software may be distributed under the terms of the
153250 + * GNU General Public License ("GPL") as published by the Free Software
153251 + * Foundation, either version 2 of that License or (at your option) any
153252 + * later version.
153253 + *
153254 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153255 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153256 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153257 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153258 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153259 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153260 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153261 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153262 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153263 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153264 + */
153265 +
153266 +/******************************************************************************
153267 + @File fm_port_ioctls.h
153268 +
153269 + @Description FM Port routines
153270 +*//***************************************************************************/
153271 +#ifndef __FM_PORT_IOCTLS_H
153272 +#define __FM_PORT_IOCTLS_H
153273 +
153274 +#include "enet_ext.h"
153275 +#include "net_ioctls.h"
153276 +#include "fm_ioctls.h"
153277 +#include "fm_pcd_ioctls.h"
153278 +
153279 +
153280 +/**************************************************************************//**
153281 +
153282 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
153283 +
153284 + @Description FM Linux ioctls definitions and enums
153285 +
153286 + @{
153287 +*//***************************************************************************/
153288 +
153289 +/**************************************************************************//**
153290 + @Group lnx_ioctl_FM_PORT_grp FM Port
153291 +
153292 + @Description FM Port API
153293 +
153294 + The FM uses a general module called "port" to represent a Tx port
153295 + (MAC), an Rx port (MAC), offline parsing flow or host command
153296 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
153297 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
153298 + Host command/Offline parsing ports. The SW driver manages these
153299 + ports as sub-modules of the FM, i.e. after an FM is initialized,
153300 + its ports may be initialized and operated upon.
153301 +
153302 + The port is initialized aware of its type, but other functions on
153303 + a port may be indifferent to its type. When necessary, the driver
153304 + verifies coherency and returns error if applicable.
153305 +
153306 + On initialization, user specifies the port type and it's index
153307 + (relative to the port's type). Host command and Offline parsing
153308 + ports share the same id range, I.e user may not initialized host
153309 + command port 0 and offline parsing port 0.
153310 +
153311 + @{
153312 +*//***************************************************************************/
153313 +
153314 +/**************************************************************************//**
153315 + @Description An enum for defining port PCD modes.
153316 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
153317 +
153318 + This enum defines the superset of PCD engines support - i.e. not
153319 + all engines have to be used, but all have to be enabled. The real
153320 + flow of a specific frame depends on the PCD configuration and the
153321 + frame headers and payload.
153322 + Note: the first engine and the first engine after the parser (if
153323 + exists) should be in order, the order is important as it will
153324 + define the flow of the port. However, as for the rest engines
153325 + (the ones that follows), the order is not important anymore as
153326 + it is defined by the PCD graph itself.
153327 +*//***************************************************************************/
153328 +typedef enum ioc_fm_port_pcd_support {
153329 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
153330 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
153331 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
153332 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
153333 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
153334 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
153335 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
153336 + /**< Use all PCD engines */
153337 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
153338 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
153339 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
153340 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
153341 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153342 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
153343 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
153344 +#endif /* FM_CAPWAP_SUPPORT */
153345 +} ioc_fm_port_pcd_support;
153346 +
153347 +
153348 +/**************************************************************************//**
153349 + @Collection FM Frame error
153350 +*//***************************************************************************/
153351 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
153352 +
153353 +/* @} */
153354 +
153355 +
153356 +/**************************************************************************//**
153357 + @Description An enum for defining Dual Tx rate limiting scale.
153358 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
153359 +*//***************************************************************************/
153360 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
153361 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
153362 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
153363 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
153364 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
153365 +} ioc_fm_port_dual_rate_limiter_scale_down;
153366 +
153367 +/**************************************************************************//**
153368 + @Description A structure for defining Tx rate limiting
153369 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
153370 +*//***************************************************************************/
153371 +typedef struct ioc_fm_port_rate_limit_t {
153372 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
153373 + for offline parsing ports. (note that
153374 + for early chips burst size is
153375 + rounded up to a multiply of 1000 frames).*/
153376 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
153377 + offline parsing ports. Rate limit refers to
153378 + data rate (rather than line rate). */
153379 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
153380 + for some earlier chip revisions */
153381 +} ioc_fm_port_rate_limit_t;
153382 +
153383 +
153384 +
153385 +/**************************************************************************//**
153386 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
153387 +
153388 + @Description FM Port Runtime control unit API functions, definitions and enums.
153389 +
153390 + @{
153391 +*//***************************************************************************/
153392 +
153393 +/**************************************************************************//**
153394 + @Description An enum for defining FM Port counters.
153395 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
153396 +*//***************************************************************************/
153397 +typedef enum ioc_fm_port_counters {
153398 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
153399 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
153400 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
153401 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
153402 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
153403 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
153404 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
153405 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
153406 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
153407 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
153408 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
153409 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
153410 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
153411 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
153412 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
153413 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
153414 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
153415 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
153416 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
153417 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
153418 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
153419 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
153420 +} ioc_fm_port_counters;
153421 +
153422 +typedef struct ioc_fm_port_bmi_stats_t {
153423 + uint32_t cnt_cycle;
153424 + uint32_t cnt_task_util;
153425 + uint32_t cnt_queue_util;
153426 + uint32_t cnt_dma_util;
153427 + uint32_t cnt_fifo_util;
153428 + uint32_t cnt_rx_pause_activation;
153429 + uint32_t cnt_frame;
153430 + uint32_t cnt_discard_frame;
153431 + uint32_t cnt_dealloc_buf;
153432 + uint32_t cnt_rx_bad_frame;
153433 + uint32_t cnt_rx_large_frame;
153434 + uint32_t cnt_rx_filter_frame;
153435 + uint32_t cnt_rx_list_dma_err;
153436 + uint32_t cnt_rx_out_of_buffers_discard;
153437 + uint32_t cnt_wred_discard;
153438 + uint32_t cnt_length_err;
153439 + uint32_t cnt_unsupported_format;
153440 +} ioc_fm_port_bmi_stats_t;
153441 +
153442 +/**************************************************************************//**
153443 + @Description Structure for Port id parameters.
153444 + (Description may be inaccurate;
153445 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
153446 +
153447 + Fields commented 'IN' are passed by the port module to be used
153448 + by the FM module.
153449 + Fields commented 'OUT' will be filled by FM before returning to port.
153450 +*//***************************************************************************/
153451 +typedef struct ioc_fm_port_congestion_groups_t {
153452 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
153453 + to define the size of the following array */
153454 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
153455 + /**< An array of CG indexes;
153456 + Note that the size of the array should be
153457 + 'num_of_congestion_grps_to_consider'. */
153458 +#if DPAA_VERSION >= 11
153459 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
153460 + /**< A matrix that represents the map between the CG ids
153461 + defined in 'congestion_grps_to_consider' to the priorities
153462 + mapping array. */
153463 +#endif /* DPAA_VERSION >= 11 */
153464 +} ioc_fm_port_congestion_groups_t;
153465 +
153466 +
153467 +
153468 +/**************************************************************************//**
153469 + @Function FM_PORT_Disable
153470 +
153471 + @Description Gracefully disable an FM port. The port will not start new tasks after all
153472 + tasks associated with the port are terminated.
153473 +
153474 + @Return 0 on success; error code otherwise.
153475 +
153476 + @Cautions This is a blocking routine, it returns after port is
153477 + gracefully stopped, i.e. the port will not except new frames,
153478 + but it will finish all frames or tasks which were already began
153479 +*//***************************************************************************/
153480 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
153481 +
153482 +/**************************************************************************//**
153483 + @Function FM_PORT_Enable
153484 +
153485 + @Description A runtime routine provided to allow disable/enable of port.
153486 +
153487 + @Return 0 on success; error code otherwise.
153488 +*//***************************************************************************/
153489 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
153490 +
153491 +/**************************************************************************//**
153492 + @Function FM_PORT_SetRateLimit
153493 +
153494 + @Description Calling this routine enables rate limit algorithm.
153495 + By default, this functionality is disabled.
153496 + Note that rate-limit mechanism uses the FM time stamp.
153497 + The selected rate limit specified here would be
153498 + rounded DOWN to the nearest 16M.
153499 +
153500 + May be used for Tx and offline parsing ports only
153501 +
153502 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
153503 +
153504 + @Return 0 on success; error code otherwise.
153505 +*//***************************************************************************/
153506 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
153507 +
153508 +/**************************************************************************//**
153509 + @Function FM_PORT_DeleteRateLimit
153510 +
153511 + @Description Calling this routine disables the previously enabled rate limit.
153512 +
153513 + May be used for Tx and offline parsing ports only
153514 +
153515 + @Return 0 on success; error code otherwise.
153516 +*//***************************************************************************/
153517 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
153518 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
153519 +
153520 +
153521 +/**************************************************************************//**
153522 + @Function FM_PORT_AddCongestionGrps
153523 +
153524 + @Description This routine effects the corresponding Tx port.
153525 + It should be called in order to enable pause
153526 + frame transmission in case of congestion in one or more
153527 + of the congestion groups relevant to this port.
153528 + Each call to this routine may add one or more congestion
153529 + groups to be considered relevant to this port.
153530 +
153531 + May be used for Rx, or RX+OP ports only (depending on chip)
153532 +
153533 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153534 + congestion group ids to consider.
153535 +
153536 + @Return 0 on success; error code otherwise.
153537 +*//***************************************************************************/
153538 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
153539 +
153540 +/**************************************************************************//**
153541 + @Function FM_PORT_RemoveCongestionGrps
153542 +
153543 + @Description This routine effects the corresponding Tx port. It should be
153544 + called when congestion groups were
153545 + defined for this port and are no longer relevant, or pause
153546 + frames transmitting is not required on their behalf.
153547 + Each call to this routine may remove one or more congestion
153548 + groups to be considered relevant to this port.
153549 +
153550 + May be used for Rx, or RX+OP ports only (depending on chip)
153551 +
153552 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153553 + congestion group ids to consider.
153554 +
153555 + @Return 0 on success; error code otherwise.
153556 +*//***************************************************************************/
153557 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
153558 +
153559 +/**************************************************************************//**
153560 + @Function FM_PORT_SetErrorsRoute
153561 +
153562 + @Description Errors selected for this routine will cause a frame with that error
153563 + to be enqueued to error queue.
153564 + Errors not selected for this routine will cause a frame with that error
153565 + to be enqueued to the one of the other port queues.
153566 + By default all errors are defined to be enqueued to error queue.
153567 + Errors that were configured to be discarded (at initialization)
153568 + may not be selected here.
153569 +
153570 + May be used for Rx and offline parsing ports only
153571 +
153572 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
153573 +
153574 + @Return 0 on success; error code otherwise.
153575 +
153576 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153577 + (szbs001: How is it possible to have one function that needs to be
153578 + called BEFORE FM_PORT_Init() implemented as an ioctl,
153579 + which will ALWAYS be called AFTER the FM_PORT_Init()
153580 + for that port!?!?!?!???!?!??!?!?)
153581 +*//***************************************************************************/
153582 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
153583 +
153584 +
153585 +/**************************************************************************//**
153586 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
153587 +
153588 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
153589 +
153590 + @{
153591 +*//***************************************************************************/
153592 +
153593 +/**************************************************************************//**
153594 + @Description A structure defining the KG scheme after the parser.
153595 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
153596 +
153597 + This is relevant only to change scheme selection mode - from
153598 + direct to indirect and vice versa, or when the scheme is selected directly,
153599 + to select the scheme id.
153600 +
153601 +*//***************************************************************************/
153602 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
153603 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
153604 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
153605 + 'scheme_id' selects the scheme after parser. */
153606 +} ioc_fm_pcd_kg_scheme_select_t;
153607 +
153608 +/**************************************************************************//**
153609 + @Description Scheme IDs structure
153610 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
153611 +*//***************************************************************************/
153612 +typedef struct ioc_fm_pcd_port_schemes_params_t {
153613 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153614 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
153615 + port to be bound to */
153616 +} ioc_fm_pcd_port_schemes_params_t;
153617 +
153618 +/**************************************************************************//**
153619 + @Description A union for defining port protocol parameters for parser
153620 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
153621 +*//***************************************************************************/
153622 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
153623 + /* MPLS */
153624 + struct {
153625 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
153626 + interpreted as described in HW spec table. When the bit
153627 + is cleared, the parser will advance to MPLS next parse */
153628 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
153629 + } mpls_prs_options;
153630 +
153631 + /* VLAN */
153632 + struct {
153633 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
153634 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153635 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
153636 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153637 + } vlan_prs_options;
153638 +
153639 + /* PPP */
153640 + struct{
153641 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
153642 + } pppoe_prs_options;
153643 +
153644 + /* IPV6 */
153645 + struct {
153646 + bool routing_hdr_disable; /**< Disable routing header */
153647 + } ipv6_prs_options;
153648 +
153649 + /* UDP */
153650 + struct {
153651 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153652 + } udp_prs_options;
153653 +
153654 + /* TCP */
153655 + struct {
153656 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153657 + } tcp_prs_options;
153658 +} ioc_fm_pcd_hdr_prs_opts_u;
153659 +
153660 +/**************************************************************************//**
153661 + @Description A structure for defining each header for the parser
153662 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
153663 +*//***************************************************************************/
153664 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
153665 + ioc_net_header_type hdr; /**< Selected header */
153666 + bool err_disable; /**< TRUE to disable error indication */
153667 + bool soft_prs_enable; /**< Enable jump to SW parser when this
153668 + header is recognized by the HW parser. */
153669 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
153670 + attachments exists for the same header,
153671 + (in the main sw parser code) use this
153672 + index to distinguish between them. */
153673 + bool use_prs_opts; /**< TRUE to use parser options. */
153674 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
153675 + defining the parser options selected.*/
153676 +} ioc_fm_pcd_prs_additional_hdr_params_t;
153677 +
153678 +/**************************************************************************//**
153679 + @Description A structure for defining port PCD parameters
153680 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
153681 +*//***************************************************************************/
153682 +typedef struct ioc_fm_port_pcd_prs_params_t {
153683 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
153684 + port information into the parser result. This information
153685 + may be extracted by KeyGen and be used for frames
153686 + distribution when a per-port distinction is required,
153687 + it may also be used as a port logical id for analyzing
153688 + incoming frames. */
153689 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
153690 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
153691 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
153692 + uint8_t num_of_hdrs_with_additional_params;
153693 + /**< Normally 0, some headers may get special parameters */
153694 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
153695 + /**< 'num_of_hdrs_with_additional_params' structures
153696 + additional parameters for each header that requires them */
153697 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
153698 + indicate a VLAN tag (in addition to the TPID values
153699 + 0x8100 and 0x88A8). */
153700 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153701 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
153702 + indicate a VLAN tag (in addition to the TPID values
153703 + 0x8100 and 0x88A8). */
153704 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153705 +} ioc_fm_port_pcd_prs_params_t;
153706 +
153707 +/**************************************************************************//**
153708 + @Description A structure for defining coarse alassification parameters
153709 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
153710 +*//***************************************************************************/
153711 +typedef struct ioc_fm_port_pcd_cc_params_t {
153712 + void *cc_tree_id; /**< CC tree id */
153713 +} ioc_fm_port_pcd_cc_params_t;
153714 +
153715 +/**************************************************************************//**
153716 + @Description A structure for defining keygen parameters
153717 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
153718 +*//***************************************************************************/
153719 +typedef struct ioc_fm_port_pcd_kg_params_t {
153720 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153721 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
153722 + /**< Array of 'num_of_schemes' schemes for the
153723 + port to be bound to */
153724 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
153725 + regardless of parser result */
153726 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
153727 + relevant only if direct=TRUE. */
153728 +} ioc_fm_port_pcd_kg_params_t;
153729 +
153730 +/**************************************************************************//**
153731 + @Description A structure for defining policer parameters
153732 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
153733 +*//***************************************************************************/
153734 +typedef struct ioc_fm_port_pcd_plcr_params_t {
153735 + void *plcr_profile_id; /**< Selected profile handle;
153736 + relevant in one of the following cases:
153737 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
153738 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
153739 + or if any flow uses a KG scheme where policer
153740 + profile is not generated (bypass_plcr_profile_generation selected) */
153741 +} ioc_fm_port_pcd_plcr_params_t;
153742 +
153743 +/**************************************************************************//**
153744 + @Description A structure for defining port PCD parameters
153745 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
153746 +*//***************************************************************************/
153747 +typedef struct ioc_fm_port_pcd_params_t {
153748 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
153749 + Describes the active PCD engines for this port. */
153750 + void *net_env_id; /**< HL Unused in PLCR only mode */
153751 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
153752 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
153753 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
153754 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
153755 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153756 +#if (DPAA_VERSION >= 11)
153757 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153758 +#endif /* (DPAA_VERSION >= 11) */
153759 +} ioc_fm_port_pcd_params_t;
153760 +
153761 +/**************************************************************************//**
153762 + @Description A structure for defining the Parser starting point
153763 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153764 +*//***************************************************************************/
153765 +typedef struct ioc_fm_pcd_prs_start_t {
153766 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153767 + start parsing */
153768 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153769 + 'parsing_offset' */
153770 +} ioc_fm_pcd_prs_start_t;
153771 +
153772 +
153773 +/**************************************************************************//**
153774 + @Description FQID parameters structure
153775 +*//***************************************************************************/
153776 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153777 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153778 + uint8_t alignment; /**< Alignment required for this port */
153779 + uint32_t base_fqid; /**< output parameter - the base fqid */
153780 +} ioc_fm_port_pcd_fqids_params_t;
153781 +
153782 +
153783 +/**************************************************************************//**
153784 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153785 +
153786 + @Description Allocates FQID's
153787 +
153788 + May be used for Rx and offline parsing ports only
153789 +
153790 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153791 +
153792 + @Return 0 on success; error code otherwise.
153793 +*//***************************************************************************/
153794 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153795 +
153796 +/**************************************************************************//**
153797 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
153798 +
153799 + @Description Frees previously-allocated FQIDs
153800 +
153801 + May be used for Rx and offline parsing ports only
153802 +
153803 + @Param[in] uint32_t Base FQID of previously allocated range.
153804 +
153805 + @Return 0 on success; error code otherwise.
153806 +*//***************************************************************************/
153807 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
153808 +
153809 +
153810 +/**************************************************************************//**
153811 + @Function FM_PORT_SetPCD
153812 +
153813 + @Description Calling this routine defines the port's PCD configuration.
153814 + It changes it from its default configuration which is PCD
153815 + disabled (BMI to BMI) and configures it according to the passed
153816 + parameters.
153817 +
153818 + May be used for Rx and offline parsing ports only
153819 +
153820 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
153821 + configuration.
153822 +
153823 + @Return 0 on success; error code otherwise.
153824 +*//***************************************************************************/
153825 +#if defined(CONFIG_COMPAT)
153826 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
153827 +#endif
153828 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
153829 +
153830 +/**************************************************************************//**
153831 + @Function FM_PORT_DeletePCD
153832 +
153833 + @Description Calling this routine releases the port's PCD configuration.
153834 + The port returns to its default configuration which is PCD
153835 + disabled (BMI to BMI) and all PCD configuration is removed.
153836 +
153837 + May be used for Rx and offline parsing ports which are
153838 + in PCD mode only
153839 +
153840 + @Return 0 on success; error code otherwise.
153841 +*//***************************************************************************/
153842 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
153843 +
153844 +/**************************************************************************//**
153845 + @Function FM_PORT_AttachPCD
153846 +
153847 + @Description This routine may be called after FM_PORT_DetachPCD was called,
153848 + to return to the originally configured PCD support flow.
153849 + The couple of routines are used to allow PCD configuration changes
153850 + that demand that PCD will not be used while changes take place.
153851 +
153852 + May be used for Rx and offline parsing ports which are
153853 + in PCD mode only
153854 +
153855 + @Return 0 on success; error code otherwise.
153856 +*//***************************************************************************/
153857 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
153858 +
153859 +/**************************************************************************//**
153860 + @Function FM_PORT_DetachPCD
153861 +
153862 + @Description Calling this routine detaches the port from its PCD functionality.
153863 + The port returns to its default flow which is BMI to BMI.
153864 +
153865 + May be used for Rx and offline parsing ports which are
153866 + in PCD mode only
153867 +
153868 + @Return 0 on success; error code otherwise.
153869 +*//***************************************************************************/
153870 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
153871 +
153872 +/**************************************************************************//**
153873 + @Function FM_PORT_PcdPlcrAllocProfiles
153874 +
153875 + @Description This routine may be called only for ports that use the Policer in
153876 + order to allocate private policer profiles.
153877 +
153878 + @Param[in] uint16_t The number of required policer profiles
153879 +
153880 + @Return 0 on success; error code otherwise.
153881 +
153882 + @Cautions Allowed before FM_PORT_SetPCD() only.
153883 +*//***************************************************************************/
153884 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
153885 +
153886 +/**************************************************************************//**
153887 + @Function FM_PORT_PcdPlcrFreeProfiles
153888 +
153889 + @Description This routine should be called for freeing private policer profiles.
153890 +
153891 + @Return 0 on success; error code otherwise.
153892 +
153893 + @Cautions Allowed before FM_PORT_SetPCD() only.
153894 +*//***************************************************************************/
153895 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
153896 +
153897 +/**************************************************************************//**
153898 + @Function FM_PORT_PcdKgModifyInitialScheme
153899 +
153900 + @Description This routine may be called only for ports that use the keygen in
153901 + order to change the initial scheme frame should be routed to.
153902 + The change may be of a scheme id (in case of direct mode),
153903 + from direct to indirect, or from indirect to direct - specifying the scheme id.
153904 +
153905 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
153906 + a scheme is direct/indirect, and if direct - scheme id.
153907 +
153908 + @Return 0 on success; error code otherwise.
153909 +*//***************************************************************************/
153910 +#if defined(CONFIG_COMPAT)
153911 +#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)
153912 +#endif
153913 +#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)
153914 +
153915 +/**************************************************************************//**
153916 + @Function FM_PORT_PcdPlcrModifyInitialProfile
153917 +
153918 + @Description This routine may be called for ports with flows
153919 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
153920 + to change the initial Policer profile frame should be routed to.
153921 + The change may be of a profile and/or absolute/direct mode selection.
153922 +
153923 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
153924 +
153925 + @Return 0 on success; error code otherwise.
153926 +*//***************************************************************************/
153927 +#if defined(CONFIG_COMPAT)
153928 +#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)
153929 +#endif
153930 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
153931 +
153932 +/**************************************************************************//**
153933 + @Function FM_PORT_PcdCcModifyTree
153934 +
153935 + @Description This routine may be called to change this port connection to
153936 + a pre-initializes coarse classification Tree.
153937 +
153938 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
153939 +
153940 + @Return 0 on success; error code otherwise.
153941 +
153942 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
153943 +*//***************************************************************************/
153944 +#if defined(CONFIG_COMPAT)
153945 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
153946 +#endif
153947 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
153948 +
153949 +/**************************************************************************//**
153950 + @Function FM_PORT_PcdKgBindSchemes
153951 +
153952 + @Description These routines may be called for modifying the binding of ports
153953 + to schemes. The scheme itself is not added,
153954 + just this specific port starts using it.
153955 +
153956 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153957 +
153958 + @Return 0 on success; error code otherwise.
153959 +
153960 + @Cautions Allowed only following FM_PORT_SetPCD().
153961 +*//***************************************************************************/
153962 +#if defined(CONFIG_COMPAT)
153963 +#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)
153964 +#endif
153965 +#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)
153966 +
153967 +/**************************************************************************//**
153968 + @Function FM_PORT_PcdKgUnbindSchemes
153969 +
153970 + @Description These routines may be called for modifying the binding of ports
153971 + to schemes. The scheme itself is not removed or invalidated,
153972 + just this specific port stops using it.
153973 +
153974 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153975 +
153976 + @Return 0 on success; error code otherwise.
153977 +
153978 + @Cautions Allowed only following FM_PORT_SetPCD().
153979 +*//***************************************************************************/
153980 +#if defined(CONFIG_COMPAT)
153981 +#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)
153982 +#endif
153983 +#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)
153984 +
153985 +typedef struct ioc_fm_port_mac_addr_params_t {
153986 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
153987 +} ioc_fm_port_mac_addr_params_t;
153988 +
153989 +/**************************************************************************//**
153990 + @Function FM_MAC_AddHashMacAddr
153991 +
153992 + @Description Add an Address to the hash table. This is for filter purpose only.
153993 +
153994 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153995 +
153996 + @Return E_OK on success; Error code otherwise.
153997 +
153998 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
153999 + @Cautions Some address need to be filtered out in upper FM blocks.
154000 +*//***************************************************************************/
154001 +#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)
154002 +
154003 +/**************************************************************************//**
154004 + @Function FM_MAC_RemoveHashMacAddr
154005 +
154006 + @Description Delete an Address to the hash table. This is for filter purpose only.
154007 +
154008 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
154009 +
154010 + @Return E_OK on success; Error code otherwise.
154011 +
154012 + @Cautions Allowed only following FM_MAC_Init().
154013 +*//***************************************************************************/
154014 +#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)
154015 +
154016 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
154017 + uint8_t priority;
154018 + uint16_t pause_time;
154019 + uint16_t thresh_time;
154020 +} ioc_fm_port_tx_pause_frames_params_t;
154021 +
154022 +/**************************************************************************//**
154023 + @Function FM_MAC_SetTxPauseFrames
154024 +
154025 + @Description Enable/Disable transmission of Pause-Frames.
154026 + The routine changes the default configuration:
154027 + pause-time - [0xf000]
154028 + threshold-time - [0]
154029 +
154030 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
154031 +
154032 + @Return E_OK on success; Error code otherwise.
154033 +
154034 + @Cautions Allowed only following FM_MAC_Init().
154035 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
154036 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
154037 + in the 'priority' field.
154038 +*//***************************************************************************/
154039 +#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)
154040 +
154041 +typedef struct ioc_fm_port_mac_statistics_t {
154042 + /* RMON */
154043 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
154044 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
154045 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
154046 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
154047 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
154048 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
154049 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
154050 + /* */
154051 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
154052 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
154053 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
154054 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
154055 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
154056 + This count does not include range length errors */
154057 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
154058 + a valid FCS and otherwise well formed */
154059 + /* Pause */
154060 + uint64_t te_stat_pause; /**< Pause MAC Control received */
154061 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
154062 + /* MIB II */
154063 + uint64_t if_in_octets; /**< Total number of byte received. */
154064 + uint64_t if_in_pkts; /**< Total number of packets received.*/
154065 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
154066 + NOTE: this counter is not supported on dTSEC MAC */
154067 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
154068 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
154069 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
154070 + uint64_t if_in_errors; /**< Number of frames received with error:
154071 + - FIFO Overflow Error
154072 + - CRC Error
154073 + - Frame Too Long Error
154074 + - Alignment Error
154075 + - The dedicated Error Code (0xfe, not a code error) was received */
154076 + uint64_t if_out_octets; /**< Total number of byte sent. */
154077 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
154078 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
154079 + NOTE: this counter is not supported on dTSEC MAC */
154080 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
154081 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
154082 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
154083 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
154084 + - FIFO Overflow Error
154085 + - FIFO Underflow Error
154086 + - Other */
154087 +} ioc_fm_port_mac_statistics_t;
154088 +
154089 +/**************************************************************************//**
154090 + @Function FM_MAC_GetStatistics
154091 +
154092 + @Description get all MAC statistics counters
154093 +
154094 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
154095 +
154096 + @Return E_OK on success; Error code otherwise.
154097 +
154098 + @Cautions Allowed only following FM_Init().
154099 +*//***************************************************************************/
154100 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
154101 +
154102 +/**************************************************************************//**
154103 + @Function FM_PORT_ConfigBufferPrefixContent
154104 +
154105 + @Description Defines the structure, size and content of the application buffer.
154106 + The prefix will
154107 + In Tx ports, if 'passPrsResult', the application
154108 + should set a value to their offsets in the prefix of
154109 + the FM will save the first 'privDataSize', than,
154110 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
154111 + and timeStamp, and the packet itself (in this order), to the
154112 + application buffer, and to offset.
154113 + Calling this routine changes the buffer margins definitions
154114 + in the internal driver data base from its default
154115 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
154116 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
154117 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
154118 +
154119 + May be used for all ports
154120 +
154121 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
154122 +
154123 + @Return E_OK on success; Error code otherwise.
154124 +
154125 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
154126 +*//***************************************************************************/
154127 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
154128 +
154129 +#if (DPAA_VERSION >= 11)
154130 +typedef struct ioc_fm_port_vsp_alloc_params_t {
154131 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
154132 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
154133 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
154134 + if relevant function called for Rx port */
154135 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
154136 +}ioc_fm_port_vsp_alloc_params_t;
154137 +
154138 +/**************************************************************************//**
154139 + @Function FM_PORT_VSPAlloc
154140 +
154141 + @Description This routine allocated VSPs per port and forces the port to work
154142 + in VSP mode. Note that the port is initialized by default with the
154143 + physical-storage-profile only.
154144 +
154145 + @Param[in] h_FmPort A handle to a FM Port module.
154146 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
154147 +
154148 + @Return E_OK on success; Error code otherwise.
154149 +
154150 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
154151 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
154152 +*//***************************************************************************/
154153 +#if defined(CONFIG_COMPAT)
154154 +#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)
154155 +#endif
154156 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
154157 +#endif /* (DPAA_VERSION >= 11) */
154158 +
154159 +/**************************************************************************//**
154160 + @Function FM_PORT_GetBmiCounters
154161 +
154162 + @Description Read port's BMI stat counters and place them into
154163 + a designated structure of counters.
154164 +
154165 + @Param[in] h_FmPort A handle to a FM Port module.
154166 + @Param[out] p_BmiStats counters structure
154167 +
154168 + @Return E_OK on success; Error code otherwise.
154169 +
154170 + @Cautions Allowed only following FM_PORT_Init().
154171 +*//***************************************************************************/
154172 +
154173 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
154174 +
154175 +
154176 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
154177 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
154178 +
154179 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
154180 +/** @} */ /* end of lnx_ioctl_FM_grp group */
154181 +#endif /* __FM_PORT_IOCTLS_H */
154182 diff --git a/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
154183 new file mode 100644
154184 index 00000000..207ed1eb
154185 --- /dev/null
154186 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
154187 @@ -0,0 +1,208 @@
154188 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154189 + * All rights reserved.
154190 + *
154191 + * Redistribution and use in source and binary forms, with or without
154192 + * modification, are permitted provided that the following conditions are met:
154193 + * * Redistributions of source code must retain the above copyright
154194 + * notice, this list of conditions and the following disclaimer.
154195 + * * Redistributions in binary form must reproduce the above copyright
154196 + * notice, this list of conditions and the following disclaimer in the
154197 + * documentation and/or other materials provided with the distribution.
154198 + * * Neither the name of Freescale Semiconductor nor the
154199 + * names of its contributors may be used to endorse or promote products
154200 + * derived from this software without specific prior written permission.
154201 + *
154202 + *
154203 + * ALTERNATIVELY, this software may be distributed under the terms of the
154204 + * GNU General Public License ("GPL") as published by the Free Software
154205 + * Foundation, either version 2 of that License or (at your option) any
154206 + * later version.
154207 + *
154208 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154209 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154210 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154211 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154212 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154213 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154214 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154215 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154216 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154217 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154218 + */
154219 +
154220 +/**************************************************************************//**
154221 + @File fm_test_ioctls.h
154222 +
154223 + @Description FM Char device ioctls
154224 +*//***************************************************************************/
154225 +#ifndef __FM_TEST_IOCTLS_H
154226 +#define __FM_TEST_IOCTLS_H
154227 +
154228 +#include "ioctls.h"
154229 +
154230 +
154231 +/**************************************************************************//**
154232 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
154233 +
154234 + @Description FM-Test Linux ioctls definitions and enums
154235 +
154236 + @{
154237 +*//***************************************************************************/
154238 +
154239 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
154240 +
154241 +/**************************************************************************//**
154242 + @Collection TEST Parameters
154243 +*//***************************************************************************/
154244 +/**************************************************************************//**
154245 + @Description: Name of the FM-Test chardev
154246 +*//***************************************************************************/
154247 +#define DEV_FM_TEST_NAME "fm-test-port"
154248 +
154249 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
154250 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
154251 +
154252 +#define FMT_PORT_IOC_NUM(n) n
154253 +/* @} */
154254 +
154255 +/**************************************************************************//**
154256 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
154257 +
154258 + @Description TODO
154259 +
154260 + @{
154261 +*//***************************************************************************/
154262 +
154263 +/**************************************************************************//**
154264 + @Description TODO
154265 +*//***************************************************************************/
154266 +typedef uint8_t ioc_fmt_xxx_t;
154267 +
154268 +#define FM_PRS_MAX 32
154269 +#define FM_TIME_STAMP_MAX 8
154270 +
154271 +/**************************************************************************//**
154272 + @Description FM Port buffer content description
154273 +*//***************************************************************************/
154274 +typedef struct ioc_fmt_buff_context_t {
154275 + void *p_user_priv;
154276 + uint8_t fm_prs_res[FM_PRS_MAX];
154277 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154278 +} ioc_fmt_buff_context_t;
154279 +
154280 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154281 +typedef struct ioc_fmt_compat_buff_context_t {
154282 + compat_uptr_t p_user_priv;
154283 + uint8_t fm_prs_res[FM_PRS_MAX];
154284 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154285 +} ioc_fmt_compat_buff_context_t;
154286 +#endif
154287 +
154288 +/**************************************************************************//**
154289 + @Description Buffer descriptor
154290 +*//***************************************************************************/
154291 +typedef struct ioc_fmt_buff_desc_t {
154292 + uint32_t qid;
154293 + void *p_data;
154294 + uint32_t size;
154295 + uint32_t status;
154296 + ioc_fmt_buff_context_t buff_context;
154297 +} ioc_fmt_buff_desc_t;
154298 +
154299 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154300 +typedef struct ioc_fmt_compat_buff_desc_t {
154301 + uint32_t qid;
154302 + compat_uptr_t p_data;
154303 + uint32_t size;
154304 + uint32_t status;
154305 + ioc_fmt_compat_buff_context_t buff_context;
154306 +} ioc_fmt_compat_buff_desc_t;
154307 +#endif
154308 +
154309 +/**************************************************************************//**
154310 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
154311 +
154312 + @Description TODO
154313 + @{
154314 +*//***************************************************************************/
154315 +
154316 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
154317 +
154318 +
154319 +/**************************************************************************//**
154320 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
154321 +
154322 + @Description TODO
154323 +
154324 + @{
154325 +*//***************************************************************************/
154326 +
154327 +/**************************************************************************//**
154328 + @Description FM-Test FM port type
154329 +*//***************************************************************************/
154330 +typedef enum ioc_fmt_port_type {
154331 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
154332 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
154333 +} ioc_fmt_port_type;
154334 +
154335 +/**************************************************************************//**
154336 + @Description TODO
154337 +*//***************************************************************************/
154338 +typedef struct ioc_fmt_port_param_t {
154339 + uint8_t fm_id;
154340 + ioc_fmt_port_type fm_port_type;
154341 + uint8_t fm_port_id;
154342 + uint32_t num_tx_queues;
154343 +} ioc_fmt_port_param_t;
154344 +
154345 +
154346 +/**************************************************************************//**
154347 + @Function FMT_PORT_IOC_INIT
154348 +
154349 + @Description TODO
154350 +
154351 + @Param[in] ioc_fmt_port_param_t TODO
154352 +
154353 + @Cautions Allowed only after the FM equivalent port is already initialized.
154354 +*//***************************************************************************/
154355 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
154356 +
154357 +/**************************************************************************//**
154358 + @Function FMT_PORT_IOC_SET_DIAG_MODE
154359 +
154360 + @Description TODO
154361 +
154362 + @Param[in] ioc_diag_mode TODO
154363 +
154364 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154365 +*//***************************************************************************/
154366 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
154367 +
154368 +/**************************************************************************//**
154369 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
154370 +
154371 + @Description Set IP header manipulations for this port.
154372 +
154373 + @Param[in] int 1 to enable; 0 to disable
154374 +
154375 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154376 +*//***************************************************************************/
154377 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
154378 +
154379 +/**************************************************************************//**
154380 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
154381 +
154382 + @Description Set DPA in echo mode - all frame are sent back.
154383 +
154384 + @Param[in] int 1 to enable; 0 to disable
154385 +
154386 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154387 +*//***************************************************************************/
154388 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
154389 +
154390 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
154391 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
154392 +/** @} */ /* end of lnx_ioctl_FMT_grp */
154393 +
154394 +
154395 +#endif /* __FM_TEST_IOCTLS_H */
154396 diff --git a/include/uapi/linux/fmd/integrations/Kbuild b/include/uapi/linux/fmd/integrations/Kbuild
154397 new file mode 100644
154398 index 00000000..e548d676
154399 --- /dev/null
154400 +++ b/include/uapi/linux/fmd/integrations/Kbuild
154401 @@ -0,0 +1 @@
154402 +header-y += integration_ioctls.h
154403 diff --git a/include/uapi/linux/fmd/integrations/integration_ioctls.h b/include/uapi/linux/fmd/integrations/integration_ioctls.h
154404 new file mode 100644
154405 index 00000000..61d696e2
154406 --- /dev/null
154407 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
154408 @@ -0,0 +1,56 @@
154409 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154410 + * All rights reserved.
154411 + *
154412 + * Redistribution and use in source and binary forms, with or without
154413 + * modification, are permitted provided that the following conditions are met:
154414 + * * Redistributions of source code must retain the above copyright
154415 + * notice, this list of conditions and the following disclaimer.
154416 + * * Redistributions in binary form must reproduce the above copyright
154417 + * notice, this list of conditions and the following disclaimer in the
154418 + * documentation and/or other materials provided with the distribution.
154419 + * * Neither the name of Freescale Semiconductor nor the
154420 + * names of its contributors may be used to endorse or promote products
154421 + * derived from this software without specific prior written permission.
154422 + *
154423 + *
154424 + * ALTERNATIVELY, this software may be distributed under the terms of the
154425 + * GNU General Public License ("GPL") as published by the Free Software
154426 + * Foundation, either version 2 of that License or (at your option) any
154427 + * later version.
154428 + *
154429 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154430 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154431 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154432 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154433 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154434 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154435 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154436 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154437 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154438 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154439 + */
154440 +
154441 +/**************************************************************************//**
154442 + @File integration_ioctls.h
154443 +
154444 + @Description External header file for Integration unit routines.
154445 +*//***************************************************************************/
154446 +
154447 +#ifndef __INTG_IOCTLS_H
154448 +#define __INTG_IOCTLS_H
154449 +
154450 +
154451 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
154452 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
154453 +
154454 +/*#define FM_IOCTL_DBG*/
154455 +
154456 +#if defined(FM_IOCTL_DBG)
154457 + #define _fm_ioctl_dbg(format, arg...) \
154458 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
154459 + __func__, __LINE__, smp_processor_id(), ##arg)
154460 +#else
154461 +# define _fm_ioctl_dbg(arg...)
154462 +#endif
154463 +
154464 +#endif /* __INTG_IOCTLS_H */
154465 diff --git a/include/uapi/linux/fmd/ioctls.h b/include/uapi/linux/fmd/ioctls.h
154466 new file mode 100644
154467 index 00000000..4f36cb05
154468 --- /dev/null
154469 +++ b/include/uapi/linux/fmd/ioctls.h
154470 @@ -0,0 +1,96 @@
154471 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154472 + * All rights reserved.
154473 + *
154474 + * Redistribution and use in source and binary forms, with or without
154475 + * modification, are permitted provided that the following conditions are met:
154476 + * * Redistributions of source code must retain the above copyright
154477 + * notice, this list of conditions and the following disclaimer.
154478 + * * Redistributions in binary form must reproduce the above copyright
154479 + * notice, this list of conditions and the following disclaimer in the
154480 + * documentation and/or other materials provided with the distribution.
154481 + * * Neither the name of Freescale Semiconductor nor the
154482 + * names of its contributors may be used to endorse or promote products
154483 + * derived from this software without specific prior written permission.
154484 + *
154485 + *
154486 + * ALTERNATIVELY, this software may be distributed under the terms of the
154487 + * GNU General Public License ("GPL") as published by the Free Software
154488 + * Foundation, either version 2 of that License or (at your option) any
154489 + * later version.
154490 + *
154491 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154492 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154493 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154494 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154495 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154496 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154497 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154498 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154499 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154500 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154501 + */
154502 +
154503 +/**************************************************************************//**
154504 + @File ioctls.h
154505 +
154506 + @Description Structures and definitions for Command Relay Ioctls
154507 +*//***************************************************************************/
154508 +
154509 +#ifndef __IOCTLS_H__
154510 +#define __IOCTLS_H__
154511 +
154512 +#include <asm/ioctl.h>
154513 +
154514 +#include "integration_ioctls.h"
154515 +
154516 +
154517 +/**************************************************************************//**
154518 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
154519 + @{
154520 +*//***************************************************************************/
154521 +
154522 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
154523 + the NCSW Linux module commands */
154524 +
154525 +
154526 +/**************************************************************************//**
154527 + @Description IOCTL Memory allocation types.
154528 +*//***************************************************************************/
154529 +typedef enum ioc_mem_type {
154530 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
154531 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
154532 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
154533 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
154534 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
154535 +} ioc_mem_type;
154536 +
154537 +/**************************************************************************//**
154538 + @Description Enumeration (bit flags) of communication modes (Transmit,
154539 + receive or both).
154540 +*//***************************************************************************/
154541 +typedef enum ioc_comm_mode {
154542 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
154543 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
154544 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
154545 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
154546 +} ioc_comm_mode;
154547 +
154548 +/**************************************************************************//**
154549 + @Description General Diagnostic Mode
154550 +*//***************************************************************************/
154551 +typedef enum ioc_diag_mode
154552 +{
154553 + e_IOC_DIAG_MODE_NONE = 0,
154554 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
154555 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
154556 + E.g. IO-pins, SerDes, etc. */
154557 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
154558 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
154559 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
154560 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
154561 +} ioc_diag_mode;
154562 +
154563 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
154564 +
154565 +
154566 +#endif /* __IOCTLS_H__ */
154567 diff --git a/include/uapi/linux/fmd/net_ioctls.h b/include/uapi/linux/fmd/net_ioctls.h
154568 new file mode 100644
154569 index 00000000..c99d64cf
154570 --- /dev/null
154571 +++ b/include/uapi/linux/fmd/net_ioctls.h
154572 @@ -0,0 +1,430 @@
154573 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154574 + * All rights reserved.
154575 + *
154576 + * Redistribution and use in source and binary forms, with or without
154577 + * modification, are permitted provided that the following conditions are met:
154578 + * * Redistributions of source code must retain the above copyright
154579 + * notice, this list of conditions and the following disclaimer.
154580 + * * Redistributions in binary form must reproduce the above copyright
154581 + * notice, this list of conditions and the following disclaimer in the
154582 + * documentation and/or other materials provided with the distribution.
154583 + * * Neither the name of Freescale Semiconductor nor the
154584 + * names of its contributors may be used to endorse or promote products
154585 + * derived from this software without specific prior written permission.
154586 + *
154587 + *
154588 + * ALTERNATIVELY, this software may be distributed under the terms of the
154589 + * GNU General Public License ("GPL") as published by the Free Software
154590 + * Foundation, either version 2 of that License or (at your option) any
154591 + * later version.
154592 + *
154593 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154594 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154595 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154596 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154597 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154598 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154599 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154600 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154601 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154602 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154603 + */
154604 +
154605 +
154606 +/**************************************************************************//**
154607 + @File net_ioctls.h
154608 +
154609 + @Description This file contains common and general netcomm headers definitions.
154610 +*//***************************************************************************/
154611 +#ifndef __NET_IOCTLS_H
154612 +#define __NET_IOCTLS_H
154613 +
154614 +#include "ioctls.h"
154615 +
154616 +
154617 +typedef uint8_t ioc_header_field_ppp_t;
154618 +
154619 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
154620 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
154621 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
154622 +
154623 +
154624 +typedef uint8_t ioc_header_field_pppoe_t;
154625 +
154626 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
154627 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
154628 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
154629 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
154630 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
154631 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
154632 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
154633 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
154634 +
154635 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
154636 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
154637 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
154638 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
154639 +
154640 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
154641 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
154642 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
154643 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
154644 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
154645 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
154646 +
154647 +
154648 +typedef uint8_t ioc_header_field_eth_t;
154649 +
154650 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
154651 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
154652 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
154653 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
154654 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
154655 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
154656 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
154657 +
154658 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
154659 +
154660 +typedef uint16_t ioc_header_field_ip_t;
154661 +
154662 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
154663 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
154664 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
154665 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
154666 +
154667 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
154668 +
154669 +typedef uint16_t ioc_header_field_ipv4_t;
154670 +
154671 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
154672 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
154673 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
154674 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
154675 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
154676 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
154677 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
154678 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
154679 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
154680 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
154681 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
154682 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
154683 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
154684 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
154685 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
154686 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
154687 +
154688 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
154689 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
154690 +
154691 +
154692 +typedef uint8_t ioc_header_field_ipv6_t;
154693 +
154694 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
154695 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
154696 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
154697 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
154698 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
154699 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
154700 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
154701 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
154702 +
154703 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
154704 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
154705 +
154706 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
154707 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
154708 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
154709 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
154710 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
154711 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
154712 +
154713 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
154714 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
154715 +
154716 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
154717 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
154718 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
154719 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
154720 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
154721 +
154722 +
154723 +typedef uint16_t ioc_header_field_tcp_t;
154724 +
154725 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
154726 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
154727 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
154728 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
154729 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
154730 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
154731 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
154732 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
154733 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
154734 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
154735 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
154736 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
154737 +
154738 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
154739 +
154740 +
154741 +typedef uint8_t ioc_header_field_sctp_t;
154742 +
154743 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
154744 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
154745 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
154746 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
154747 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
154748 +
154749 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
154750 +
154751 +typedef uint8_t ioc_header_field_dccp_t;
154752 +
154753 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
154754 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
154755 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
154756 +
154757 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
154758 +
154759 +
154760 +typedef uint8_t ioc_header_field_udp_t;
154761 +
154762 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
154763 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
154764 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
154765 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
154766 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
154767 +
154768 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
154769 +
154770 +typedef uint8_t ioc_header_field_udp_lite_t;
154771 +
154772 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
154773 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
154774 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
154775 +
154776 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
154777 +
154778 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
154779 +
154780 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
154781 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
154782 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
154783 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
154784 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
154785 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
154786 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
154787 +
154788 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
154789 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
154790 +
154791 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
154792 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
154793 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
154794 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
154795 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
154796 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
154797 +
154798 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
154799 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
154800 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
154801 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
154802 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
154803 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
154804 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
154805 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
154806 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
154807 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
154808 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
154809 +
154810 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
154811 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
154812 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
154813 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
154814 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
154815 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
154816 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
154817 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
154818 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
154819 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
154820 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
154821 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
154822 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
154823 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
154824 +
154825 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
154826 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
154827 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
154828 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
154829 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
154830 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
154831 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
154832 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
154833 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
154834 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
154835 +
154836 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
154837 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
154838 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
154839 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
154840 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
154841 +
154842 +
154843 +typedef uint8_t ioc_header_field_vlan_t;
154844 +
154845 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
154846 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
154847 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
154848 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
154849 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
154850 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
154851 +
154852 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
154853 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
154854 + IOC_NET_HEADER_FIELD_VLAN_VID)
154855 +
154856 +
154857 +typedef uint8_t ioc_header_field_llc_t;
154858 +
154859 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
154860 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
154861 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
154862 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
154863 +
154864 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
154865 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
154866 +
154867 +
154868 +typedef uint8_t ioc_header_field_snap_t;
154869 +
154870 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
154871 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
154872 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
154873 +
154874 +
154875 +typedef uint8_t ioc_header_field_llc_snap_t;
154876 +
154877 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
154878 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
154879 +
154880 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
154881 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
154882 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
154883 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
154884 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
154885 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
154886 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
154887 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
154888 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
154889 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
154890 +
154891 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
154892 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
154893 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
154894 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
154895 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
154896 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
154897 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
154898 +
154899 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
154900 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
154901 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
154902 +
154903 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
154904 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
154905 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
154906 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
154907 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
154908 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
154909 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
154910 +
154911 +
154912 +typedef uint8_t ioc_header_field_gre_t;
154913 +
154914 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
154915 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
154916 +
154917 +
154918 +typedef uint8_t ioc_header_field_minencap_t;
154919 +
154920 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
154921 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
154922 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
154923 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
154924 +
154925 +
154926 +typedef uint8_t ioc_header_field_ipsec_ah_t;
154927 +
154928 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
154929 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
154930 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
154931 +
154932 +
154933 +typedef uint8_t ioc_header_field_ipsec_esp_t;
154934 +
154935 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
154936 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
154937 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
154938 +
154939 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
154940 +
154941 +
154942 +typedef uint8_t ioc_header_field_mpls_t;
154943 +
154944 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
154945 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
154946 +
154947 +
154948 +typedef uint8_t ioc_header_field_macsec_t;
154949 +
154950 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
154951 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
154952 +
154953 +
154954 +typedef enum {
154955 + e_IOC_NET_HEADER_TYPE_NONE = 0,
154956 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
154957 + e_IOC_NET_HEADER_TYPE_ETH,
154958 + e_IOC_NET_HEADER_TYPE_VLAN,
154959 + e_IOC_NET_HEADER_TYPE_IPv4,
154960 + e_IOC_NET_HEADER_TYPE_IPv6,
154961 + e_IOC_NET_HEADER_TYPE_IP,
154962 + e_IOC_NET_HEADER_TYPE_TCP,
154963 + e_IOC_NET_HEADER_TYPE_UDP,
154964 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
154965 + e_IOC_NET_HEADER_TYPE_IPHC,
154966 + e_IOC_NET_HEADER_TYPE_SCTP,
154967 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
154968 + e_IOC_NET_HEADER_TYPE_PPPoE,
154969 + e_IOC_NET_HEADER_TYPE_PPP,
154970 + e_IOC_NET_HEADER_TYPE_PPPMUX,
154971 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
154972 + e_IOC_NET_HEADER_TYPE_L2TPv2,
154973 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
154974 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
154975 + e_IOC_NET_HEADER_TYPE_LLC,
154976 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
154977 + e_IOC_NET_HEADER_TYPE_NLPID,
154978 + e_IOC_NET_HEADER_TYPE_SNAP,
154979 + e_IOC_NET_HEADER_TYPE_MPLS,
154980 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
154981 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
154982 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
154983 + e_IOC_NET_HEADER_TYPE_MACSEC,
154984 + e_IOC_NET_HEADER_TYPE_GRE,
154985 + e_IOC_NET_HEADER_TYPE_MINENCAP,
154986 + e_IOC_NET_HEADER_TYPE_DCCP,
154987 + e_IOC_NET_HEADER_TYPE_ICMP,
154988 + e_IOC_NET_HEADER_TYPE_IGMP,
154989 + e_IOC_NET_HEADER_TYPE_ARP,
154990 + e_IOC_NET_HEADER_TYPE_CAPWAP,
154991 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
154992 + e_IOC_NET_HEADER_TYPE_RFC2684,
154993 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
154994 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
154995 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
154996 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
154997 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
154998 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
154999 +} ioc_net_header_type;
155000 +
155001 +
155002 +#endif /* __NET_IOCTLS_H */
155003 --
155004 2.14.1
155005